2位组之间的快速汉明距离

时间:2011-10-21 15:47:07

标签: c++

我正在编写一种软件,它非常依赖于(1)访问单个位和(2)2位集A和B之间的汉明距离计算(即A和B之间不同的位数)。位集非常大,介于10K和1M位之间,我有很多位。由于在编译时无法知道位集大小,我正在使用vector < bool >,但我计划很快迁移到boost::dynamic_bitset

以下是我的问题:

(1)关于哪些实现具有最快单位访问时间的任何想法?

(2)为了计算汉明距离,天真的方法是循环单个比特并计算2个比特集之间的差异。但是,我的感觉是,循环遍历字节而不是位可能要快得多,执行R = byteA XOR byteB,并查看具有255个条目的表,其中“本地”距离与R相关联。另一个解决方案是存储a 255 x 255矩阵并直接访问而无需操作到byteA和byteB之间的距离。所以我的问题:任何想法如何从std::vector < bool >或boost :: dynamic_bitset实现?换句话说,你知道是否有办法访问bytes数组,或者我必须从头开始重新编码所有内容?

3 个答案:

答案 0 :(得分:4)

(1)可能vector<char>(或甚至vector<int>),但在典型硬件上浪费至少7/8的空间。如果使用一个或多个字节来存储它们,则无需解压缩位。我不知道,vector<bool>dynamic_bitset中的哪一个更快。这可能取决于C ++的实现。

(2)boost::dynamic_bitset有一个operator^和一个count成员,它们可以用来计算汉明距离,但速度很快,虽然是内存消耗方式。您还可以使用to_block_range访问底层缓冲区;要使用它,您需要将汉明距离计算器实现为OutputIterator

答案 1 :(得分:2)

如果从头开始编写代码,一次可能比一个字节做得更好:从每个bitset一次一个字。 XOR的成本应该非常低,然后使用特定于实现的内置popcount,或者你可以找到最快的位错误的popcount(可能涉及或不涉及256项查找)。

[修改:看起来好像这适用于boost::dynamic_bitset::to_block_rangeBlock选为intlong。很遗憾它写入一个OutputIterator而不是给你一个InputIterator - 我不能立即看到如何使用它来迭代两个bitset,除非使用额外的线程或者复制其中一个首先将bitset输出到int数组。无论哪种方式,如果它已经将程序控制权交给您,您可以采取一些本可以避免的复制开销。该任务的线程非常复杂,当然也有自己的开销,复制数据可能不比使用operator^count()更好。]

答案 2 :(得分:0)

我知道这会因为异端邪说而受到贬低,但这里是:你可以使用&amp; vector [0]获得指向矢量实际数据的指针; (对于矢量ymmv)。然后,您可以使用c风格的函数迭代它;意思是,将指针转换为int指针或类似的东西,执行上面的汉明算术,并一次将指针移动一个字长。这只会起作用,因为您知道这些位是连续打包在一起的,并且容易受到攻击(例如,如果修改了矢量,它可能会移动内存位置)。