为boost::dynamic_bitset生成哈希,并将哈希转换回boost::dynamic_bitset
Generate hash for boost::dynamic_bitset and convert hash back to boost::dynamic_bitset
我希望生成一个boost::dynamic_bitset
哈希,以便将值存储在boost::bimaps
中。我尝试了以下代码,在这里测试代码。
#include <iostream>
#include <boost/dynamic_bitset.hpp>
#include <unordered_map>
#include <boost/bimap.hpp>
#include <boost/bimap/unordered_set_of.hpp>
#include <boost/bimap/unordered_multiset_of.hpp>
#include <boost/bimap/set_of.hpp>
#include <boost/bimap/multiset_of.hpp>
#define BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS
namespace boost {
template <typename B, typename A>
std::size_t hash_value(const boost::dynamic_bitset<B, A>& bs) {
return boost::hash_value(bs.m_bits);
}
}
namespace bimaps = boost::bimaps;
typedef boost::bimap<bimaps::unordered_set_of<unsigned long long int>,
bimaps::unordered_multiset_of<size_t> > bimap_reference;
typedef bimap_reference::value_type position;
bimap_reference reference_index_vector;
int main()
{
std::string str = "1011010001101101000001101101000011111111011010000011011010000111111111110110100011011010000011011010000111111110110100000110110100001111111111";
boost::dynamic_bitset<> bits = boost::dynamic_bitset<> (str);
std::cout << "bitmap " << bits << std::endl;
std::cout << "Number of bits " << bits.count() << std::endl;
size_t hash1 = boost::hash_value (bits);
std::cout << "Hash value " << hash1 << std::endl;
/* Insert hash value in bimap
*
*/
// reference_index_vector.insert(position(10000000000, hash1));
// for( bimap_reference::const_iterator iter = reference_index_vector.begin(), iend = reference_index_vector.end();
// iter != iend; ++iter ) {
// std::cout << iter->left << " <--> "<< iter->right <<std::endl;
// }
return 0;
}
我得到错误
在/usr/include/boost/dynamic_bitset.hp:15:0,from 3:在'std::size_t boost::hash_value(const-boost::dynamic_bitset&)的实例化中[其中B=长无符号int;A=std::分配器;std::size _t=长无签名int]':34:40:从这里开始需要/usr/include/brust/dynamic_bitset/dynamic_bitset.hp:422:17:错误:'boost:buffer_type boost::dynamic_bitset<>::m_bits'是专用buffer_type m_bits;^16:37:错误:在此上下文中
不确定出了什么问题。
- 如何哈希
boost::dynamic_bitset
- 如何将哈希转换回原始比特集
- 所需的总空间(计数为0和1或仅为1)。上述代码仅通过
bits.count()
显示80位。我尝试了以下方法来生成哈希值,但不确定需要多少空间
此外,我试图通过以下代码生成比特集的哈希值
/*Generating hash by bitset
*
*/
std::bitset<142> seq (str);
std::hash<std::bitset<142>> hash_bitset;
std::cout << "Bitset " << seq << std::endl;
std::cout << "Hash value " << hash_bitset(seq) << std::endl;
#Bitset 1011010001101101000001101101000011111111011010000011011010000111111111110110100011011010000011011010000111111110110100000110110100001111111111
#Hash value 4886653603414440856
好吧,我发现了很多关于"哈希"本质的困惑,所以有几个友好的指针可以开始:
Q2。如何将哈希转换回原始比特集。
这是不可能的。散列是有损摘要。只有当哈希是完美哈希时,才能执行此操作。由于熵定律,如果比特集容量超过平台上size_t
的大小(通常为32或64比特),则无法执行完美哈希。
Q我还尝试通过…创建一个散列。。。
std::bitset<142> seq (str); ....
我希望你意识到std::bitset<>
是一种完全不同的类型,所以它与任务并没有真正的关系。而且,由于它不是动态的,它对任务毫无帮助,即使是作为一种变通方法。
但最重要的是:
哈希表(如unordered_*<>
)使用,但它们未存储。哈希是有损的摘要,只用于在内部桶上获得良好的分布。对于实际元素相等,std::equal<T>
仍使用。
换句话说:
typedef boost::bimap<bimaps::unordered_set_of<unsigned long long int>,
bimaps::unordered_multiset_of<size_t> > bimap_reference;
不适合创建除size_t
或unsigned long long
²以外的任何对象的映射。如果你在那里存储东西的散列:
reference_index_vector.insert(position(10000000000, hash1));
,您将丢失原始信息。无法从hash1
获取位集。
编译器错误
您的hash_value
实现错误地使用了dynamic_bitset<>
的私有成员。你不能,因为它不可访问。
下面是一个使用公共接口的std::hash<>
的简单实现:
在Coliru上直播
#include <boost/dynamic_bitset.hpp>
#include <boost/functional/hash.hpp>
#include <unordered_map>
#include <sstream>
namespace std {
template <typename Block, typename Alloc> struct hash<boost::dynamic_bitset<Block, Alloc> > {
size_t operator()(boost::dynamic_bitset<Block, Alloc> const& bs) const {
size_t seed = boost::hash_value(bs.size());
std::vector<Block> blocks(bs.num_blocks());
boost::hash_range(seed, blocks.begin(), blocks.end());
return seed;
}
};
}
int main() {
boost::dynamic_bitset<> x, y;
x.resize(rand()%100, 1);
y.resize(rand()%100, 0);
std::unordered_map<boost::dynamic_bitset<>, std::string> m;
m[x] = "x";
m[y] = "y";
}
您可以使用此std::hash<>
专业化,并将boost::bimap
与之一起使用。
注意,使用公共接口不是最佳的,因为它复制了Block
s(您也使用了std::bitset<>
破解)。您可能对我之前为boost::dynamic_bitset<>
所做的Boost序列化实现感兴趣:
- 如何序列化boost::dynamic_bitset
- 这里的代码展示了如何使用Serialization实现来高效地实现哈希哈希任意精度值(boost::multiprecision::cpp_int)
为了简单起见,假设使用bucket而不是"开放寻址"样式。同样的逻辑也适用于此,但稍微复杂一些
²(顺便说一下,请说uintmax_t
或uint64_t
)
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 使用Qt C++计算类似Git的SHA1哈希
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- 用C++将哈希表写入文件并从文件中恢复
- c++找不到具有相同哈希的无序集合元素
- 哈希文件递归并保存到矢量Cryptopp中
- 对 pair<pair<int,int>pair<int,int unordered_map进行哈希处理>>
- 直接在 unordered_map 的方法中使用哈希,而不是生成哈希的用户定义对象
- 如何为字符串生成唯一但一致的 N 位哈希(小于 64 位)?
- 使用对象的基类部分模板专用化对对象进行哈希处理::哈希
- boost::包含提升单元的元组的哈希值
- 使用 Key 对 C++ 中的哈希映射进行排序. 无法排序
- C++中的并发哈希表
- 哈希映射使用 nullptr c++ 初始化节点的动态数组
- 在具有开放寻址的哈希表中插入节点 [优化逻辑]
- 与C++哈希表的基础知识混淆
- 如何为位集找到/实现一个好的哈希函数
- std::bitset 哈希函数算法
- c++使用std::bitset组合哈希函数