我希望生成boost::dynamic_bitset
哈希,以便将值存储在boost::bimaps
中。我尝试了以下代码Test code here.
#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.hpp:15:0中包含的文件中,从3开始:实例化'std :: size_t boost :: hash_value(const boost :: dynamic_bitset&amp;)[B = long unsigned int; A = std :: allocator; std :: size_t = long unsigned int]':34:40:从这里需要/usr/include/boost/dynamic_bitset/dynamic_bitset.hpp:422:17:错误:'boost :: dynamic_bitset&lt;&gt; :: buffer_type boost: :dynamic_bitset&lt;&gt; :: m_bits'是私有buffer_type m_bits; ^ 16:37:错误:在此上下文中
不确定出了什么问题。
boost::dynamic_bitset
bits.count()
的80位。我尝试了以下方法来生成哈希值,但不确定需要多少空间。另外,我尝试通过以下代码
生成bitset的哈希值/*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
答案 0 :(得分:3)
好吧,我发现了很多关于“哈希”本质的混淆,所以有一些友好的指示可以开始:
问。 2.如何将散列转换回orignial bitset。
那是不可能的。哈希是有损摘要。只有当哈希值为Perfect Hash时才会执行此操作,如果位集容量超过平台上size_t
的大小(通常为32或64位),则由于熵定律,不会发生这种情况。
问。我还尝试通过...创建哈希
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
得到bitset。
您的hash_value
实施错误地使用了dynamic_bitset<>
的私人成员。你不能,因为它无法访问。
以下是使用公共接口的std::hash<>
的简单实现:
<强> Live On 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<>
hack执行了此操作)。您可能对我之前为boost::dynamic_bitset<>
所做的Boost序列化实现感兴趣:
¹为简单起见,假设桶代替“开放寻址”风格。同样的逻辑适用于那里,但有点复杂
²(顺便说一下,请说uintmax_t
或uint64_t
)