DAWorkbench 0.0.1
DAWorkbench API
载入中...
搜索中...
未找到
da_hash_table.hpp
1#ifndef DA_HASH_TABLE_H
2#define DA_HASH_TABLE_H
3
4#include <unordered_map>
5#include <utility>
6#include <functional>
7#include <initializer_list>
8#include <vector>
9#include <algorithm>
10
11namespace DA
12{
13
18{
19 template< class T1, class T2 >
20 std::size_t operator()(const std::pair< T1, T2 >& p) const noexcept;
21};
22
34template< typename T, typename row_index_type = std::size_t, typename col_index_type = row_index_type, typename hasher = pair_hash >
36{
37public:
38 using key_type = std::pair< row_index_type, col_index_type >;
39 using value_type = std::pair< const key_type, T >;
40 using table_index_type = key_type;
41
42 // 迭代器类型定义
43 using iterator = typename std::unordered_map< key_type, T, hasher >::iterator;
44 using const_iterator = typename std::unordered_map< key_type, T, hasher >::const_iterator;
45 using size_type = typename std::unordered_map< key_type, T, hasher >::size_type;
46
47public:
48 // 构造函数
49 da_hash_table() = default; // 默认构造函数
50 da_hash_table(const da_hash_table& other) = default; // 拷贝构造函数
51 da_hash_table(da_hash_table&& other) noexcept = default; // 移动构造函数
52 da_hash_table(std::initializer_list< value_type > init); // 初始化列表构造函数
53
54 // 赋值运算符
55 da_hash_table& operator=(const da_hash_table& other) = default; // 拷贝赋值运算符
56 da_hash_table& operator=(da_hash_table&& other) noexcept = default; // 移动赋值运算符
57
58 // 元素访问
59 T& at(row_index_type r, col_index_type c); // 带边界检查的元素访问
60 const T& at(row_index_type r, col_index_type c) const; // 带边界检查的常量元素访问
61 T& at(key_type k); // 带边界检查的元素访问
62 const T& at(key_type k) const; // 带边界检查的常量元素访问
63 T& operator()(row_index_type r, col_index_type c); // 函数调用运算符访问元素
64 const T operator()(row_index_type r, col_index_type c) const; // 函数调用运算符访问元素(常量版本)
65 T& operator()(key_type k); // 函数调用运算符访问元素
66 const T operator()(key_type k) const; // 函数调用运算符访问元素(常量版本)
67 T value(row_index_type r, col_index_type c) const; // 安全的元素访问,返回默认值如果不存在
68 T value(row_index_type r, col_index_type c, const T& defaultValue) const; // 安全的元素访问,返回指定默认值如果不存在
69 T& operator[](key_type k); // 函数调用运算符访问元素
70 // 容量操作
71 bool empty() const noexcept; // 检查表格是否为空
72 size_type size() const noexcept; // 返回元素数量
73 size_type max_size() const noexcept; // 返回最大可能元素数量
74
75 // 修改器
76 void clear() noexcept; // 清空表格
77 std::pair< iterator, bool > insert(const value_type& value); // 插入元素
78 template< class P >
79 std::pair< iterator, bool > insert(P&& value); // 插入元素(通用引用)
80 template< class InputIt >
81 void insert(InputIt first, InputIt last); // 插入元素范围
82 void insert(std::initializer_list< value_type > ilist); // 插入初始化列表
83 template< class... Args >
84 std::pair< iterator, bool > emplace(Args&&... args); // 原位构造元素
85 iterator erase(const_iterator pos); // 删除指定位置元素
86 iterator erase(const_iterator first, const_iterator last); // 删除元素范围
87 size_type erase(row_index_type r, col_index_type c); // 删除指定行列元素
88
89 // 查找操作
90 iterator find(key_type k); // 查找元素
91 const_iterator find(key_type k) const; // 查找元素(常量版本)
92 iterator find(row_index_type r, col_index_type c); // 查找元素
93 const_iterator find(row_index_type r, col_index_type c) const; // 查找元素(常量版本)
94 size_type count(row_index_type r, col_index_type c) const; // 统计元素出现次数
95
96 // 迭代器访问
97 iterator begin() noexcept; // 返回指向起始的迭代器
98 const_iterator begin() const noexcept; // 返回指向起始的常量迭代器
99 const_iterator cbegin() const noexcept; // 返回指向起始的常量迭代器
100 iterator end() noexcept; // 返回指向末尾的迭代器
101 const_iterator end() const noexcept; // 返回指向末尾的常量迭代器
102 const_iterator cend() const noexcept; // 返回指向末尾的常量迭代器
103
104 // 哈希策略
105 float load_factor() const noexcept; // 返回当前负载因子
106 float max_load_factor() const noexcept; // 返回最大负载因子
107 void max_load_factor(float ml); // 设置最大负载因子
108 void rehash(size_type count); // 设置桶数并重新哈希
109 void reserve(size_type count); // 预留空间
110
111 // 桶接口
112 size_type bucket_count() const noexcept; // 返回桶数
113 size_type max_bucket_count() const noexcept; // 返回最大桶数
114
115 // 形状和结构操作
116 table_index_type shape() const; // 计算表格形状
117 std::vector< row_index_type > row_indices() const; // 获取实际使用的行索引列表
118 std::vector< col_index_type > column_indices() const; // 获取实际使用的列索引列表
119 std::vector< std::pair< col_index_type, T > > row(row_index_type r) const; // 获取指定行的所有元素
120 std::vector< std::pair< row_index_type, T > > column(col_index_type c) const; // 获取指定列的所有元素
121
122 // 其他操作
123 void swap(da_hash_table& other) noexcept; // 交换两个表格的内容
124
125private:
126 std::unordered_map< key_type, T, hasher > data_;
127};
128
141template< class T1, class T2 >
142std::size_t pair_hash::operator()(const std::pair< T1, T2 >& p) const noexcept
143{
144 // 更好的哈希组合方式,减少冲突
145 auto h1 = std::hash< T1 > {}(p.first);
146 auto h2 = std::hash< T2 > {}(p.second);
147
148 // 使用更安全的哈希组合方法
149 // 参考 Boost 的 hash_combine 方法
150 return h1 ^ (h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2));
151}
152
169template< typename T, typename row_index_type, typename col_index_type, typename hasher >
171 : data_(init)
172{
173}
174
197template< typename T, typename row_index_type, typename col_index_type, typename hasher >
199{
200 return data_.at({ r, c });
201}
202
203template< typename T, typename row_index_type, typename col_index_type, typename hasher >
205{
206 return data_.at(k);
207}
208
230template< typename T, typename row_index_type, typename col_index_type, typename hasher >
231const T& da_hash_table< T, row_index_type, col_index_type, hasher >::at(row_index_type r, col_index_type c) const
232{
233 return data_.at({ r, c });
234}
235
236template< typename T, typename row_index_type, typename col_index_type, typename hasher >
238{
239 return data_.at(k);
240}
241
259template< typename T, typename row_index_type, typename col_index_type, typename hasher >
261{
262 return data_[ { r, c } ];
263}
264template< typename T, typename row_index_type, typename col_index_type, typename hasher >
266{
267 return data_[ k ];
268}
285template< typename T, typename row_index_type, typename col_index_type, typename hasher >
286const T da_hash_table< T, row_index_type, col_index_type, hasher >::operator()(row_index_type r, col_index_type c) const
287{
288 auto it = data_.find({ r, c });
289 return it != data_.end() ? it->second : T();
290}
291template< typename T, typename row_index_type, typename col_index_type, typename hasher >
293{
294 auto it = data_.find(k);
295 return it != data_.end() ? it->second : T();
296}
297
298template< typename T, typename row_index_type, typename col_index_type, typename hasher >
299T& da_hash_table< T, row_index_type, col_index_type, hasher >::operator[](
300 da_hash_table< T, row_index_type, col_index_type, hasher >::key_type k)
301{
302 return data_[ k ];
303}
304
321template< typename T, typename row_index_type, typename col_index_type, typename hasher >
323{
324 auto it = data_.find({ r, c });
325 return it != data_.end() ? it->second : T();
326}
327
345template< typename T, typename row_index_type, typename col_index_type, typename hasher >
346T da_hash_table< T, row_index_type, col_index_type, hasher >::value(row_index_type r, col_index_type c, const T& defaultValue) const
347{
348 auto it = data_.find({ r, c });
349 return it != data_.end() ? it->second : defaultValue;
350}
351
367template< typename T, typename row_index_type, typename col_index_type, typename hasher >
369{
370 return data_.empty();
371}
372
387template< typename T, typename row_index_type, typename col_index_type, typename hasher >
388typename da_hash_table< T, row_index_type, col_index_type, hasher >::size_type da_hash_table< T, row_index_type, col_index_type, hasher >::size()
389 const noexcept
390{
391 return data_.size();
392}
393
407template< typename T, typename row_index_type, typename col_index_type, typename hasher >
408typename da_hash_table< T, row_index_type, col_index_type, hasher >::size_type da_hash_table< T, row_index_type, col_index_type, hasher >::max_size()
409 const noexcept
410{
411 return data_.max_size();
412}
413
427template< typename T, typename row_index_type, typename col_index_type, typename hasher >
429{
430 data_.clear();
431}
432
450template< typename T, typename row_index_type, typename col_index_type, typename hasher >
451std::pair< typename da_hash_table< T, row_index_type, col_index_type, hasher >::iterator, bool > da_hash_table<
452 T,
453 row_index_type,
454 col_index_type,
455 hasher >::insert(const value_type& value)
456{
457 return data_.insert(value);
458}
459
478template< typename T, typename row_index_type, typename col_index_type, typename hasher >
479template< class P >
480std::pair< typename da_hash_table< T, row_index_type, col_index_type, hasher >::iterator, bool > da_hash_table<
481 T,
482 row_index_type,
483 col_index_type,
484 hasher >::insert(P&& value)
485{
486 return data_.insert(std::forward< P >(value));
487}
488
508template< typename T, typename row_index_type, typename col_index_type, typename hasher >
509template< class InputIt >
511{
512 data_.insert(first, last);
513}
514
531template< typename T, typename row_index_type, typename col_index_type, typename hasher >
532void da_hash_table< T, row_index_type, col_index_type, hasher >::insert(std::initializer_list< value_type > ilist)
533{
534 data_.insert(ilist);
535}
536
555template< typename T, typename row_index_type, typename col_index_type, typename hasher >
556template< class... Args >
557std::pair< typename da_hash_table< T, row_index_type, col_index_type, hasher >::iterator, bool > da_hash_table<
558 T,
559 row_index_type,
560 col_index_type,
561 hasher >::emplace(Args&&... args)
562{
563 return data_.emplace(std::forward< Args >(args)...);
564}
565
583template< typename T, typename row_index_type, typename col_index_type, typename hasher >
584typename da_hash_table< T, row_index_type, col_index_type, hasher >::iterator da_hash_table< T, row_index_type, col_index_type, hasher >::erase(
585 const_iterator pos)
586{
587 return data_.erase(pos);
588}
589
613template< typename T, typename row_index_type, typename col_index_type, typename hasher >
614typename da_hash_table< T, row_index_type, col_index_type, hasher >::iterator da_hash_table< T, row_index_type, col_index_type, hasher >::erase(
615 const_iterator first,
616 const_iterator last)
617{
618 return data_.erase(first, last);
619}
620
637template< typename T, typename row_index_type, typename col_index_type, typename hasher >
638typename da_hash_table< T, row_index_type, col_index_type, hasher >::size_type da_hash_table< T, row_index_type, col_index_type, hasher >::erase(
639 row_index_type r,
640 col_index_type c)
641{
642 return data_.erase({ r, c });
643}
644
650template< typename T, typename row_index_type, typename col_index_type, typename hasher >
651typename da_hash_table< T, row_index_type, col_index_type, hasher >::iterator da_hash_table< T, row_index_type, col_index_type, hasher >::find(
652 key_type k)
653{
654 return data_.find(k);
655}
656
662template< typename T, typename row_index_type, typename col_index_type, typename hasher >
663typename da_hash_table< T, row_index_type, col_index_type, hasher >::const_iterator da_hash_table< T, row_index_type, col_index_type, hasher >::find(
664 key_type k) const
665{
666 return data_.find(k);
667}
668
687template< typename T, typename row_index_type, typename col_index_type, typename hasher >
688typename da_hash_table< T, row_index_type, col_index_type, hasher >::iterator da_hash_table< T, row_index_type, col_index_type, hasher >::find(
689 row_index_type r,
690 col_index_type c)
691{
692 return data_.find({ r, c });
693}
694
713template< typename T, typename row_index_type, typename col_index_type, typename hasher >
714typename da_hash_table< T, row_index_type, col_index_type, hasher >::const_iterator da_hash_table< T, row_index_type, col_index_type, hasher >::find(
715 row_index_type r,
716 col_index_type c) const
717{
718 return data_.find({ r, c });
719}
720
737template< typename T, typename row_index_type, typename col_index_type, typename hasher >
738typename da_hash_table< T, row_index_type, col_index_type, hasher >::size_type da_hash_table< T, row_index_type, col_index_type, hasher >::count(
739 row_index_type r,
740 col_index_type c) const
741{
742 return data_.count({ r, c });
743}
744
761template< typename T, typename row_index_type, typename col_index_type, typename hasher >
762typename da_hash_table< T, row_index_type, col_index_type, hasher >::iterator da_hash_table< T, row_index_type, col_index_type, hasher >::begin() noexcept
763{
764 return data_.begin();
765}
766
783template< typename T, typename row_index_type, typename col_index_type, typename hasher >
784typename da_hash_table< T, row_index_type, col_index_type, hasher >::const_iterator da_hash_table< T,
785 row_index_type,
786 col_index_type,
787 hasher >::begin() const noexcept
788{
789 return data_.begin();
790}
791
808template< typename T, typename row_index_type, typename col_index_type, typename hasher >
809typename da_hash_table< T, row_index_type, col_index_type, hasher >::const_iterator da_hash_table< T,
810 row_index_type,
811 col_index_type,
812 hasher >::cbegin() const noexcept
813{
814 return data_.cbegin();
815}
816
832template< typename T, typename row_index_type, typename col_index_type, typename hasher >
833typename da_hash_table< T, row_index_type, col_index_type, hasher >::iterator da_hash_table< T, row_index_type, col_index_type, hasher >::end() noexcept
834{
835 return data_.end();
836}
837
853template< typename T, typename row_index_type, typename col_index_type, typename hasher >
854typename da_hash_table< T, row_index_type, col_index_type, hasher >::const_iterator da_hash_table< T,
855 row_index_type,
856 col_index_type,
857 hasher >::end() const noexcept
858{
859 return data_.end();
860}
861
877template< typename T, typename row_index_type, typename col_index_type, typename hasher >
878typename da_hash_table< T, row_index_type, col_index_type, hasher >::const_iterator da_hash_table< T,
879 row_index_type,
880 col_index_type,
881 hasher >::cend() const noexcept
882{
883 return data_.cend();
884}
885
900template< typename T, typename row_index_type, typename col_index_type, typename hasher >
902{
903 return data_.load_factor();
904}
905
920template< typename T, typename row_index_type, typename col_index_type, typename hasher >
922{
923 return data_.max_load_factor();
924}
925
939template< typename T, typename row_index_type, typename col_index_type, typename hasher >
941{
942 data_.max_load_factor(ml);
943}
944
958template< typename T, typename row_index_type, typename col_index_type, typename hasher >
960{
961 data_.rehash(count);
962}
963
977template< typename T, typename row_index_type, typename col_index_type, typename hasher >
979{
980 data_.reserve(count);
981}
982
997template< typename T, typename row_index_type, typename col_index_type, typename hasher >
998typename da_hash_table< T, row_index_type, col_index_type, hasher >::size_type da_hash_table< T, row_index_type, col_index_type, hasher >::
999 bucket_count() const noexcept
1000{
1001 return data_.bucket_count();
1002}
1003
1018template< typename T, typename row_index_type, typename col_index_type, typename hasher >
1019typename da_hash_table< T, row_index_type, col_index_type, hasher >::size_type da_hash_table< T, row_index_type, col_index_type, hasher >::
1020 max_bucket_count() const noexcept
1021{
1022 return data_.max_bucket_count();
1023}
1024
1044template< typename T, typename row_index_type, typename col_index_type, typename hasher >
1045typename da_hash_table< T, row_index_type, col_index_type, hasher >::table_index_type da_hash_table< T,
1046 row_index_type,
1047 col_index_type,
1048 hasher >::shape() const
1049{
1050 if (data_.empty()) {
1051 return { row_index_type(), col_index_type() };
1052 }
1053
1054 auto it = data_.cbegin();
1055 row_index_type max_row = it->first.first;
1056 col_index_type max_col = it->first.second;
1057
1058 ++it;
1059 for (; it != data_.cend(); ++it) {
1060 if (it->first.first > max_row) {
1061 max_row = it->first.first;
1062 }
1063 if (it->first.second > max_col) {
1064 max_col = it->first.second;
1065 }
1066 }
1067
1068 // 返回最大索引+1,表示形状
1069 return { max_row + 1, max_col + 1 };
1070}
1071
1089template< typename T, typename row_index_type, typename col_index_type, typename hasher >
1091{
1092 std::vector< row_index_type > rows;
1093 for (const auto& item : data_) {
1094 rows.push_back(item.first.first);
1095 }
1096
1097 // 去重并排序
1098 std::sort(rows.begin(), rows.end());
1099 rows.erase(std::unique(rows.begin(), rows.end()), rows.end());
1100
1101 return rows;
1102}
1103
1121template< typename T, typename row_index_type, typename col_index_type, typename hasher >
1123{
1124 std::vector< col_index_type > cols;
1125 for (const auto& item : data_) {
1126 cols.push_back(item.first.second);
1127 }
1128
1129 // 去重并排序
1130 std::sort(cols.begin(), cols.end());
1131 cols.erase(std::unique(cols.begin(), cols.end()), cols.end());
1132
1133 return cols;
1134}
1135
1154template< typename T, typename row_index_type, typename col_index_type, typename hasher >
1155std::vector< std::pair< col_index_type, T > > da_hash_table< T, row_index_type, col_index_type, hasher >::row(row_index_type r) const
1156{
1157 std::vector< std::pair< col_index_type, T > > result;
1158
1159 for (const auto& item : data_) {
1160 if (item.first.first == r) {
1161 result.emplace_back(item.first.second, item.second);
1162 }
1163 }
1164
1165 // 按列索引排序
1166 std::sort(result.begin(), result.end(), [](const auto& a, const auto& b) { return a.first < b.first; });
1167
1168 return result;
1169}
1170
1189template< typename T, typename row_index_type, typename col_index_type, typename hasher >
1191 col_index_type c) const
1192{
1193 std::vector< std::pair< row_index_type, T > > result;
1194
1195 for (const auto& item : data_) {
1196 if (item.first.second == c) {
1197 result.emplace_back(item.first.first, item.second);
1198 }
1199 }
1200
1201 // 按行索引排序
1202 std::sort(result.begin(), result.end(), [](const auto& a, const auto& b) { return a.first < b.first; });
1203
1204 return result;
1205}
1206
1222template< typename T, typename row_index_type, typename col_index_type, typename hasher >
1224{
1225 data_.swap(other.data_);
1226}
1227
1228} // namespace DA
1229
1230#endif // DA_HASH_TABLE_H
基于 std::unordered_map 的稀疏表格数据结构
Definition da_hash_table.hpp:36
iterator erase(const_iterator pos)
删除指定位置元素
Definition da_hash_table.hpp:584
std::vector< col_index_type > column_indices() const
获取实际使用的列索引列表
Definition da_hash_table.hpp:1122
iterator find(key_type k)
查找元素
Definition da_hash_table.hpp:651
void reserve(size_type count)
预留空间
Definition da_hash_table.hpp:978
da_hash_table(std::initializer_list< value_type > init)
初始化列表构造函数
Definition da_hash_table.hpp:170
std::vector< std::pair< row_index_type, T > > column(col_index_type c) const
获取指定列的所有元素
Definition da_hash_table.hpp:1190
size_type max_size() const noexcept
返回最大可能元素数量
Definition da_hash_table.hpp:408
iterator begin() noexcept
返回指向起始的迭代器
Definition da_hash_table.hpp:762
void clear() noexcept
清空表格
Definition da_hash_table.hpp:428
const T operator()(row_index_type r, col_index_type c) const
函数调用运算符访问元素(常量版本)
Definition da_hash_table.hpp:286
const_iterator cend() const noexcept
返回指向末尾的常量迭代器
Definition da_hash_table.hpp:881
std::pair< iterator, bool > insert(const value_type &value)
插入元素
Definition da_hash_table.hpp:455
const_iterator cbegin() const noexcept
返回指向起始的常量迭代器
Definition da_hash_table.hpp:812
size_type size() const noexcept
返回元素数量
Definition da_hash_table.hpp:388
T value(row_index_type r, col_index_type c, const T &defaultValue) const
安全的元素访问,返回指定默认值如果不存在
Definition da_hash_table.hpp:346
void rehash(size_type count)
设置桶数并重新哈希
Definition da_hash_table.hpp:959
std::vector< std::pair< col_index_type, T > > row(row_index_type r) const
获取指定行的所有元素
Definition da_hash_table.hpp:1155
float max_load_factor() const noexcept
返回最大负载因子
Definition da_hash_table.hpp:921
std::vector< row_index_type > row_indices() const
获取实际使用的行索引列表
Definition da_hash_table.hpp:1090
size_type bucket_count() const noexcept
返回桶数
Definition da_hash_table.hpp:999
size_type max_bucket_count() const noexcept
返回最大桶数
Definition da_hash_table.hpp:1020
bool empty() const noexcept
检查表格是否为空
Definition da_hash_table.hpp:368
T & operator()(row_index_type r, col_index_type c)
函数调用运算符访问元素
Definition da_hash_table.hpp:260
void swap(da_hash_table &other) noexcept
交换两个表格的内容
Definition da_hash_table.hpp:1223
iterator end() noexcept
返回指向末尾的迭代器
Definition da_hash_table.hpp:833
T value(row_index_type r, col_index_type c) const
安全的元素访问,返回默认值如果不存在
Definition da_hash_table.hpp:322
size_type count(row_index_type r, col_index_type c) const
统计元素出现次数
Definition da_hash_table.hpp:738
const T & at(row_index_type r, col_index_type c) const
带边界检查的常量元素访问
Definition da_hash_table.hpp:231
T & at(row_index_type r, col_index_type c)
带边界检查的元素访问
Definition da_hash_table.hpp:198
float load_factor() const noexcept
返回当前负载因子
Definition da_hash_table.hpp:901
table_index_type shape() const
计算表格的形状(最大行索引和最大列索引加1)
Definition da_hash_table.hpp:1048
序列化类都是带异常的,使用中需要处理异常
Definition AppMainWindow.cpp:44
Hash function for std::pair to be used in unordered containers
Definition da_hash_table.hpp:18
std::size_t operator()(const std::pair< T1, T2 > &p) const noexcept
Hash function for std::pair to be used in unordered containers
Definition da_hash_table.hpp:142