DAWorkbench 0.0.1
DAWorkbench API
载入中...
搜索中...
未找到
DATable.hpp
1#ifndef DATABLE_H
2#define DATABLE_H
3
4#include <memory>
5#include <functional>
6#include <vector>
7#include <algorithm>
8#include <utility>
9#include <iterator>
10#include "da_hash_table.hpp"
11#include "da_vector_table.hpp"
12
13namespace DA
14{
15
24template< typename T >
26{
27public:
28 using Type = T;
29 using IndexType = int;
30 using IndexPair = std::pair< IndexType, IndexType >;
32 using TableIterator = typename TableType::iterator;
33 using TableConstIterator = typename TableType::const_iterator;
34 using value_type = typename TableType::value_type;
35 using PredFun = std::function< bool(const value_type&) >;
36
37public:
38 // 构造函数和赋值运算符
39 DATable(); // 默认构造函数
40 DATable(const DATable& other); // 拷贝构造函数
41 DATable(DATable&& other) noexcept; // 移动构造函数
42 DATable< T >& operator=(const DATable& other); // 拷贝赋值运算符
43 DATable< T >& operator=(DATable&& other) noexcept; // 移动赋值运算符
44
45 // 元素访问
46 bool contain(int r, int c) const; // 检查单元格是否有内容
47 bool contain(IndexPair i) const; // 检查单元格是否有内容(使用索引对)
48 const T& at(int r, int c) const; // 带边界检查的元素访问
49 T& at(int r, int c); // 带边界检查的元素访问
50 const T& at(const IndexPair& i) const; // 带边界检查的元素访问(使用索引对)
51 T& at(const IndexPair& i); // 带边界检查的元素访问(使用索引对)
52 T cell(int r, int c) const; // 安全的元素访问,返回默认值如果不存在
53 T cell(const IndexPair& i) const; // 安全的元素访问,返回默认值如果不存在(使用索引对)
54 T& operator[](const IndexPair& i); // 下标运算符访问元素
55 T& operator()(IndexType r, IndexType c); // 函数调用运算符访问元素
56 const T operator()(IndexType r, IndexType c) const; // 函数调用运算符访问元素(常量版本)
57 // 修改器
58 void set(const IndexPair& k, const T& v); // 设置单元格值
59 void set(IndexType row, IndexType col, const T& v); // 设置单元格值
60
61 // 容量操作
62 int rowCount() const; // 获取表格行数
63 int columnCount() const; // 获取表格列数
64 IndexPair shape() const; // 获取表格形状
65 std::size_t size() const; // 获取表格元素数量
66 bool empty() const; // 检查表格是否为空
67
68 // 表格操作
69 void recalcShape(); // 重新计算表格形状
70 bool removeCell(int r, int c); // 移除指定单元格
71 bool removeCell(const IndexPair& i); // 移除指定单元格(使用索引对)
72 void clear(); // 清空表格
73 std::size_t erase_if(PredFun pred); // 按条件删除元素
74 void dropColumn(IndexType col); // 移除指定列
75
76 // 迭代器访问
77 TableConstIterator find(const IndexPair& i) const; // 查找元素
78 TableConstIterator find(int r, int c) const; // 查找元素
79 TableIterator find(const IndexPair& i); // 查找元素
80 TableIterator find(int r, int c); // 查找元素
81 TableConstIterator end() const; // 返回末尾迭代器
82 TableIterator end(); // 返回末尾迭代器
83 TableConstIterator begin() const; // 返回起始迭代器
84 TableIterator begin(); // 返回起始迭代器
85
86 // 转换操作
87 template< typename OtherType >
88 DATable< OtherType > transfered(std::function< OtherType(const T& v) > trFun) const; // 转换表格数据类型
89
90 void transferColumn(IndexType col, std::function< bool(const T& v) > trFun) const; // 遍历指定列
91
92 // 赋值操作
93 template< typename OtherType >
94 DATable< T >& operator=(const da_vector_table< OtherType >& other); // 从 da_vector_table 赋值
95
96 // 内部数据访问
97 TableType& rawData(); // 获取内部表格数据(不安全)
98 const TableType& rawData() const; // 获取内部表格数据(常量版本,不安全)
99
100 IndexPair getShape() const;
101
102private:
103 void reflashShape(const IndexPair& k); // 刷新形状信息
104 std::size_t erase_if__(PredFun pred); // 内部条件删除实现
105
106private:
107 TableType mData; // 内部表格数据
108 IndexPair mShape; // 表格形状信息
109};
110
111// ============================================================================
112// 实现部分
113// ============================================================================
114
123template< typename T >
124DATable< T >::DATable() : mShape(0, 0)
125{
126}
127
139template< typename T >
141{
142 mData = other.mData;
143 mShape = other.mShape;
144}
145
161template< typename T >
163{
164 mData = std::move(other.mData);
165 mShape = std::move(other.mShape);
166}
167
181template< typename T >
183{
184 mData = other.mData;
185 mShape = other.mShape;
186 return *this;
187}
188
202template< typename T >
204{
205 mData = std::move(other.mData);
206 mShape = std::move(other.mShape);
207 return *this;
208}
209
224template< typename T >
225bool DATable< T >::contain(int r, int c) const
226{
227 return (mData.cend() != mData.find(r, c));
228}
229
243template< typename T >
245{
246 return (mData.cend() != mData.find(i));
247}
248
262template< typename T >
264{
265 return mShape;
266}
267
287template< typename T >
288const T& DATable< T >::at(int r, int c) const
289{
290 return mData.at(r, c);
291}
292
313template< typename T >
314T& DATable< T >::at(int r, int c)
315{
316 return mData.at(r, c);
317}
318
337template< typename T >
338const T& DATable< T >::at(const IndexPair& i) const
339{
340 return mData.at(i);
341}
342
362template< typename T >
364{
365 return mData.at(i);
366}
367
382template< typename T >
383T DATable< T >::cell(int r, int c) const
384{
385 return mData.value(r, c);
386}
387
401template< typename T >
403{
404 return mData.value(i);
405}
406
419template< typename T >
421{
422 reflashShape(i);
423 return mData[ i ];
424}
425
440template< typename T >
442{
443 reflashShape(std::make_pair(r, c));
444 return mData(r, c);
445}
446
454template< typename T >
456{
457 return mData(r, c);
458}
459
471template< typename T >
472void DATable< T >::set(const IndexPair& k, const T& v)
473{
474 mData[ k ] = v;
475 reflashShape(k);
476}
477
490template< typename T >
491void DATable< T >::set(IndexType row, IndexType col, const T& v)
492{
493 set(IndexPair(row, col), v);
494}
495
507template< typename T >
509{
510 return mShape.first;
511}
512
524template< typename T >
526{
527 return mShape.second;
528}
529
541template< typename T >
543{
544 return mShape;
545}
546
557template< typename T >
559{
560 mShape = mData.shape();
561}
562
575template< typename T >
576std::size_t DATable< T >::size() const
577{
578 return mData.size();
579}
580
595template< typename T >
596bool DATable< T >::removeCell(int r, int c)
597{
598 auto i = mData.find(r, c);
599 if (i != mData.end()) {
600 mData.erase(i);
601 // 判断是否触发reshape
602 if (r == (mShape.first - 1) || c == (mShape.second - 1)) {
603 // 但凡有一边接触到边界,在删除后都有重新计算边界
604 recalcShape();
605 }
606 return true;
607 }
608 return false;
609}
610
624template< typename T >
626{
627 return removeCell(i.first, i.second);
628}
629
641template< typename T >
643{
644 mData.clear();
645 mShape = IndexPair(0, 0);
646}
647
663template< typename T >
665{
666 return mData;
667}
668
680template< typename T >
682{
683 return mData;
684}
685
701template< typename T >
703{
704 return mData.find(i);
705}
706
723template< typename T >
725{
726 return find(IndexPair(r, c));
727}
728
744template< typename T >
746{
747 return mData.find(i.first, i.second);
748}
749
766template< typename T >
768{
769 return find(IndexPair(r, c));
770}
771
784template< typename T >
786{
787 return mData.end();
788}
789
802template< typename T >
804{
805 return mData.end();
806}
807
820template< typename T >
822{
823 return mData.begin();
824}
825
838template< typename T >
840{
841 return mData.begin();
842}
843
856template< typename T >
858{
859 return mData.empty();
860}
861
877template< typename T >
879{
880 std::size_t r = erase_if__(pred);
881 recalcShape();
882 return r;
883}
884
899template< typename T >
901{
902 // 分两步,第一步删除,第二部移动
903 // 先把列号等于col的移除
904 std::vector< value_type > temp;
905 std::ignore = erase_if__([ col, &temp ](const value_type& v) -> bool {
906 if (v.first.second == col) {
907 return true;
908 } else if (v.first.second > col) {
909 // 大于这个列的也要删除,但要把值缓存起来,并进行左移动
910 temp.emplace_back(v);
911 return true;
912 }
913 return false;
914 });
915 // 再把列号大于col的全部减去1
916 std::for_each(temp.begin(), temp.end(), [ this ](value_type& v) {
917 IndexPair k = v.first;
918 --k.second;
919 mData[ k ] = v.second;
920 });
921 recalcShape();
922}
923
939template< typename T >
940template< typename OtherType >
941DATable< OtherType > DATable< T >::transfered(std::function< OtherType(const T& v) > trFun) const
942{
944 for (auto i = mData.cbegin(), last = mData.cend(); i != last; ++i) {
945 other[ i->first ] = trFun(i->second);
946 }
947 return other;
948}
949
969template< typename T >
970void DATable< T >::transferColumn(IndexType col, std::function< bool(const T& v) > trFun) const
971{
972 auto rowCnt = rowCount();
973 for (auto r = 0; r < rowCnt; ++r) {
974 auto ite = mData.find(IndexPair(r, col));
975 if (ite != mData.end()) {
976 if (!trFun(ite->second)) {
977 return;
978 }
979 }
980 }
981}
982
996template< typename T >
997template< typename OtherType >
999{
1000 clear();
1001 auto rc = other.row_count();
1002 auto cc = other.column_count();
1003 for (auto r = 0; r < rc; ++r) {
1004 for (auto c = 0; c < cc; ++c) {
1005 set(r, c, other(r, c));
1006 }
1007 }
1008 return *this;
1009}
1010
1020template< typename T >
1021void DATable< T >::reflashShape(const IndexPair& k)
1022{
1023 if (k.first >= mShape.first) {
1024 mShape.first = k.first + 1;
1025 }
1026 if (k.second >= mShape.second) {
1027 mShape.second = k.second + 1;
1028 }
1029}
1030
1041template< typename T >
1042std::size_t DATable< T >::erase_if__(PredFun pred)
1043{
1044 auto old_size = size();
1045 for (auto i = mData.begin(), last = mData.end(); i != last;) {
1046 if (pred(*i)) {
1047 i = mData.erase(i);
1048 } else {
1049 ++i;
1050 }
1051 }
1052 return old_size - size();
1053}
1054
1056//
1058
1072template< typename T1, typename T2 >
1073da_vector_table< T1 > table_transfered(const DATable< T2 >& table, std::function< T1(const T2&) > tr_fun)
1074{
1075 da_vector_table< T1 > res;
1076 const typename DATable< T2 >::IndexPair sh = table.shape();
1077 res.resize(sh.first, sh.second);
1078 for (auto c = table.begin(); c != table.end(); ++c) {
1079 res(c->first.first, c->first.second) = tr_fun(c->second);
1080 }
1081 return res;
1082}
1083template< typename T1, typename T2 >
1084da_vector_table< T1 > table_transfered(const DATable< T2 >& table)
1085{
1086 da_vector_table< T1 > res;
1087 const typename DATable< T2 >::IndexPair sh = table.shape();
1088 res.resize(sh.first, sh.second);
1089 for (auto c = table.begin(); c != table.end(); ++c) {
1090 res(c->first.first, c->first.second) = c->second;
1091 }
1092 return res;
1093}
1094
1108template< typename T1, typename T2 >
1109DATable< T1 > table_transfered(const da_vector_table< T2 >& table, std::function< T1(const T2&) > tr_fun)
1110{
1111 DATable< T1 > res;
1112 auto rc = table.row_count();
1113 auto cc = table.column_count();
1114 for (std::size_t r = 0; r < rc; ++r) {
1115 for (std::size_t c = 0; c < cc; ++c) {
1116 res.set(r, c, tr_fun(table(r, c)));
1117 }
1118 }
1119 return res;
1120}
1121
1122} // end DA
1123
1124#endif // DATABLE_H
支持稀疏存储和各种算法的表格类
Definition DATable.hpp:26
std::pair< IndexType, IndexType > IndexPair
索引对类型
Definition DATable.hpp:30
DATable< OtherType > transfered(std::function< OtherType(const T &v) > trFun) const
转换表格数据类型
Definition DATable.hpp:941
void clear()
清空表格
Definition DATable.hpp:642
int columnCount() const
获取表格列数
Definition DATable.hpp:525
int rowCount() const
获取表格行数
Definition DATable.hpp:508
bool empty() const
检查表格是否为空
Definition DATable.hpp:857
std::size_t size() const
获取表格元素数量
Definition DATable.hpp:576
typename TableType::iterator TableIterator
表格迭代器
Definition DATable.hpp:32
T & operator()(IndexType r, IndexType c)
函数调用运算符访问元素
Definition DATable.hpp:441
bool contain(int r, int c) const
检查单元格是否有内容
Definition DATable.hpp:225
void recalcShape()
重新计算表格形状
Definition DATable.hpp:558
T Type
值类型
Definition DATable.hpp:28
std::function< bool(const value_type &) > PredFun
谓词函数类型
Definition DATable.hpp:35
int IndexType
索引类型
Definition DATable.hpp:29
void dropColumn(IndexType col)
移除指定列
Definition DATable.hpp:900
const T & at(int r, int c) const
带边界检查的元素访问
Definition DATable.hpp:288
TableConstIterator end() const
返回末尾迭代器
Definition DATable.hpp:785
void set(const IndexPair &k, const T &v)
设置单元格值
Definition DATable.hpp:472
TableConstIterator begin() const
返回起始迭代器
Definition DATable.hpp:821
TableConstIterator find(const IndexPair &i) const
查找元素
Definition DATable.hpp:702
typename TableType::value_type value_type
兼容std的值类型
Definition DATable.hpp:34
IndexPair shape() const
获取表格形状
Definition DATable.hpp:542
DATable< T > & operator=(const DATable &other)
拷贝赋值运算符
Definition DATable.hpp:182
TableType & rawData()
获取内部表格数据
Definition DATable.hpp:664
T cell(int r, int c) const
安全的元素访问,返回默认值如果不存在
Definition DATable.hpp:383
DATable()
默认构造函数
Definition DATable.hpp:124
IndexPair getShape() const
获取表格形状
Definition DATable.hpp:263
void transferColumn(IndexType col, std::function< bool(const T &v) > trFun) const
遍历指定列
Definition DATable.hpp:970
T & operator[](const IndexPair &i)
下标运算符访问元素
Definition DATable.hpp:420
std::size_t erase_if(PredFun pred)
按条件删除元素
Definition DATable.hpp:878
bool removeCell(int r, int c)
移除指定单元格
Definition DATable.hpp:596
typename TableType::const_iterator TableConstIterator
表格常量迭代器
Definition DATable.hpp:33
iterator find(key_type k)
查找元素
Definition da_hash_table.hpp:651
二维表格数据结构,使用一维数组存储以提高缓存友好性
Definition da_vector_table.hpp:22
std::size_t column_count() const noexcept
获取表格的列数
Definition da_vector_table.hpp:1512
std::size_t row_count() const noexcept
获取表格的行数
Definition da_vector_table.hpp:1495
序列化类都是带异常的,使用中需要处理异常
Definition AppMainWindow.cpp:44
DATable< T1 > table_transfered(const da_vector_table< T2 > &table, std::function< T1(const T2 &) > tr_fun)
实现DATable向da_vector_table的转换
Definition DATable.hpp:1109