在std :: bitset中迭代真位的有效方法?

时间:2011-01-17 00:55:25

标签: c++ algorithm data-structures iteration bitset

有没有办法在设置为true的位数中线性(可能很大)std::bitset进行迭代?我想防止必须检查bitset中的每个位置。迭代应该连续返回设置为true的每个位的索引。

6 个答案:

答案 0 :(得分:14)

标准位向量不支持对真位进行有效迭代 - 运行时始终为O(n),其中n是总位数,不依赖于k。但是,一个称为van Emde Boas Tree的特殊结构支持迭代时间O(k lg lg n),其中n是位数,k是真位数。

作为一点无耻的自我推销,我有an implementation of a vEB-tree on my personal website。如果我在这里做广告不合适,请告诉我,我会把它取下来。

答案 1 :(得分:4)

为了使其成为线性,你需要一个链表/数组/索引集的设置为true。保留这样的二级索引不是std :: bitset所需的性能/存储权衡的一部分,并且鉴于它会在没有您特定要求的情况下使每个人处于不利地位,实现将无法提供此功能。你可以考虑自己用这样的容器补充你的bitset,或者使用boost的多索引容器库。

答案 2 :(得分:1)

您可以使用u64累加器和32条目表(例如

)一次检查最多32位

u32 kTable[]
{
0x01, 0x03, 0x07, 0x0F ..., 0xFFFFFFFF
};

只需将32位读入u64累加器并根据偏移量将其向下移动并检查表中的位。您可以以二进制方式执行此操作,以使最大值为5的比较数。对于非线性方式的数据,这将更慢。然后它变成了记录时间。

答案 3 :(得分:1)

只有两个选项在总位上比O(N)好得多:

  1. 使用BSF in x86等某些架构中提供的专业位扫描指令。
  2. 有O(log2(N))算法用于查找单词中设置的最低位。当bitset密集而不是稀疏时,这当然不能很好地扩展。恢复我的一些模糊记忆,我发现FXT library细节中的来源可以在FXT book (pdf)的1.3.2节中找到。

答案 4 :(得分:0)

循环整个bitset并简单地检查值并存储索引(如果为true),IS为线性。您可以使用查找表加快速度。看到这段代码:

http://xiangqi-engine.cvs.sourceforge.net/viewvc/xiangqi-engine/tsito2/src/Utility.cpp?revision=1.5&view=markup

答案 5 :(得分:0)

有时人们会使用run-length encoding来做这类事情。如果将传入的bitset编码为一个运行长度数组,则最终的运行次数不会超过set和clear位之间的转换次数,最多为2*k。此外,在许多应用中,转换的数量远远小于k,因此除了线性最差情况之外,您还可以获得出色的平均时间性能。

此外,可以直接添加一个数据结构,让您有效地搜索诸如“从数组中n位置开始的下一个设置位”之类的内容:只需构建一个scan的跑长。