繁体   English   中英

解释std :: vector <unsigned int> 作为位向量-有效的算法?

[英]Interpreting a std::vector<unsigned int> as bitvector - efficient algorithm?

我想解释

std::vector<unsigned int> numbers

作为位向量,即numbers[0]的MSB是第1位, numbers[1]的MSB是第33位,依此类推。 我想找到这个矢量问鼎的所有序列,并存储在数据结构中的相应位置。 (这里也定义了一个

例如:我将值15和112存储在数字中。 因此,位29至32和位58至60等于1。 挑战在于优化此功能的运行时间。

这是我的处理方法:我考虑过使用两个for -loops。 第一个循环遍历“数字”的元素(我们称其为element_loop),而第二个循环用于计算单个元素内所有位的位置(我们称其为bit_loop)。 我想到了为此目的检测序列的“上升”和“下降沿”。

在每个bit_loop周期的开始,将掩码初始化为十六进制。 0x80000000 使用此掩码,我检查第一位是否等于1。 如果是,则存储当前位置(0)。 接下来,使用二进制表示形式“ 10 00 ...”的掩码在下一个循环中检测“下降沿”。 如果否,则将掩码右移一位“ 01 00 ...”,以便在下一个周期中检测到“上升沿”。 (我只关心几个粗体数字)

一旦检测到边缘,我将存储当前位置并以适当的方式将蒙版移动一位。 因此,经过pos。 边缘( 01 )我切换到负数。 边缘检测( 10 ),反之亦然。 在遍历32位无符号数字的同时,我将所有边沿位置存储在某种矢量中。 该向量可以是2维。 数组,第一列是一个序列的开始,第二列是序列的结束。 此外,对于从一个元素到另一个元素的转换,我将需要一些特殊的处理。

这是我的一般问题:您如何看待这种方法? 有没有一种方法可以更有效地处理此问题? 非常感谢您的提前帮助。

有很多按位技巧可以有效地进行位扫描,但是如果您使用的是C ++,则可以利用std::bitsetboost::dynamic_bitset来遍历位的位置。 但是,您描述的算法会为每个块向后迭代,因此您希望使用32 - (32 - i)来反转位置。

根据体系结构,每个位大约需要一个周期。

有一些有效的(恒定时间)方法,可以使用特殊的处理器指令或各种巧妙的技巧来查找单词中的第一位(例如请参见设置的最低有效位的位置 )。

稍加注意,您可以向后工作,并使用它们来扫描第一个零,然后进行一些屏蔽和位翻转并搜索下一个零,依此类推。

可能会为您提供更快的算法,尤其是在序列平均较长的情况下,因此快速扫描的收益超过了比特旋转的成本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM