有没有办法在设置为true的位数中线性(可能很大)std::bitset
进行迭代?我想防止必须检查bitset中的每个位置。迭代应该连续返回设置为true的每个位的索引。
答案 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)好得多:
答案 4 :(得分:0)
循环整个bitset并简单地检查值并存储索引(如果为true),IS为线性。您可以使用查找表加快速度。看到这段代码:
答案 5 :(得分:0)
有时人们会使用run-length encoding来做这类事情。如果将传入的bitset编码为一个运行长度数组,则最终的运行次数不会超过set和clear位之间的转换次数,最多为2*k
。此外,在许多应用中,转换的数量远远小于k
,因此除了线性最差情况之外,您还可以获得出色的平均时间性能。
此外,可以直接添加一个数据结构,让您有效地搜索诸如“从数组中n
位置开始的下一个设置位”之类的内容:只需构建一个scan的跑长。