4#include <unordered_map>
7#include <initializer_list>
19 template<
class T1,
class T2 >
20 std::size_t
operator()(
const std::pair< T1, T2 >& p)
const noexcept;
34template<
typename T,
typename row_index_type = std::
size_t,
typename col_index_type = row_index_type,
typename hasher = pair_hash >
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;
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;
59 T&
at(row_index_type r, col_index_type c);
60 const T&
at(row_index_type r, col_index_type c)
const;
62 const T&
at(key_type k)
const;
64 const T
operator()(row_index_type r, col_index_type c)
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);
72 size_type
size() const noexcept;
77 std::pair< iterator,
bool >
insert(const value_type& value);
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);
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;
98 const_iterator
begin() const noexcept;
99 const_iterator
cbegin() const noexcept;
101 const_iterator
end() const noexcept;
102 const_iterator
cend() const noexcept;
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;
126 std::unordered_map< key_type, T, hasher > data_;
141template< class T1, class T2 >
142std::
size_t pair_hash::operator()(const std::pair< T1, T2 >& p) const noexcept
145 auto h1 = std::hash< T1 > {}(p.first);
146 auto h2 = std::hash< T2 > {}(p.second);
150 return h1 ^ (h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2));
169template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
197template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
200 return data_.at({ r, c });
203template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
230template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
233 return data_.at({ r, c });
236template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
259template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
262 return data_[ { r, c } ];
264template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
285template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
288 auto it = data_.find({ r, c });
289 return it != data_.end() ? it->second : T();
291template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
294 auto it = data_.find(k);
295 return it != data_.end() ? it->second : T();
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)
321template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
324 auto it = data_.find({ r, c });
325 return it != data_.end() ? it->second : T();
345template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
348 auto it = data_.find({ r, c });
349 return it != data_.end() ? it->second : defaultValue;
367template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
370 return data_.empty();
387template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
407template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
411 return data_.max_size();
427template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
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<
455 hasher >::insert(
const value_type& value)
457 return data_.
insert(value);
478template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
480std::pair< typename da_hash_table< T, row_index_type, col_index_type, hasher >::iterator,
bool >
da_hash_table<
484 hasher >::insert(P&& value)
486 return data_.
insert(std::forward< P >(value));
508template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
509template<
class InputIt >
512 data_.insert(first, last);
531template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
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<
561 hasher >::emplace(Args&&... args)
563 return data_.emplace(std::forward< Args >(args)...);
583template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
587 return data_.erase(pos);
613template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
615 const_iterator first,
618 return data_.erase(first, last);
637template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
642 return data_.erase({ r, c });
650template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
654 return data_.find(k);
662template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
666 return data_.find(k);
687template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
692 return data_.find({ r, c });
713template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
716 col_index_type c)
const
718 return data_.find({ r, c });
737template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
740 col_index_type c)
const
742 return data_.count({ r, c });
761template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
764 return data_.begin();
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,
787 hasher >::begin() const noexcept
789 return data_.
begin();
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,
812 hasher >::cbegin() const noexcept
832template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
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,
857 hasher >::end() const noexcept
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,
881 hasher >::cend() const noexcept
900template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
903 return data_.load_factor();
920template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
923 return data_.max_load_factor();
939template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
942 data_.max_load_factor(ml);
958template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
977template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
980 data_.reserve(count);
997template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
1001 return data_.bucket_count();
1018template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
1022 return data_.max_bucket_count();
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,
1048 hasher >::shape()
const
1050 if (data_.empty()) {
1051 return { row_index_type(), col_index_type() };
1054 auto it = data_.
cbegin();
1055 row_index_type max_row = it->first.first;
1056 col_index_type max_col = it->first.second;
1059 for (; it != data_.cend(); ++it) {
1060 if (it->first.first > max_row) {
1061 max_row = it->first.first;
1063 if (it->first.second > max_col) {
1064 max_col = it->first.second;
1069 return { max_row + 1, max_col + 1 };
1089template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
1092 std::vector< row_index_type > rows;
1093 for (
const auto& item : data_) {
1094 rows.push_back(item.first.first);
1098 std::sort(rows.begin(), rows.end());
1099 rows.erase(std::unique(rows.begin(), rows.end()), rows.end());
1121template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
1124 std::vector< col_index_type > cols;
1125 for (
const auto& item : data_) {
1126 cols.push_back(item.first.second);
1130 std::sort(cols.begin(), cols.end());
1131 cols.erase(std::unique(cols.begin(), cols.end()), cols.end());
1154template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
1157 std::vector< std::pair< col_index_type, T > > result;
1159 for (
const auto& item : data_) {
1160 if (item.first.first == r) {
1161 result.emplace_back(item.first.second, item.second);
1166 std::sort(result.begin(), result.end(), [](
const auto& a,
const auto& b) { return a.first < b.first; });
1189template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
1191 col_index_type c)
const
1193 std::vector< std::pair< row_index_type, T > > result;
1195 for (
const auto& item : data_) {
1196 if (item.first.second == c) {
1197 result.emplace_back(item.first.first, item.second);
1202 std::sort(result.begin(), result.end(), [](
const auto& a,
const auto& b) { return a.first < b.first; });
1222template<
typename T,
typename row_index_type,
typename col_index_type,
typename hasher >
1225 data_.swap(other.data_);
基于 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