查找包含k位集合的所有长度为n的二进制字符串的最佳算法是什么?例如,如果n = 4且k = 3,则存在…
0111 1011 1101 1110
我需要一种很好的方法来生成给定的任意n和k,因此我更喜欢使用字符串来完成。
此方法将生成具有正好N个“ 1”位的所有整数。
来自https://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation
按词典顺序计算下一位排列 假设我们有一个将N位设置为1的整数的模式,并且我们希望在词典学意义上对N 1位进行下一个排列。例如,如果N是3和位模式是00010011,下一个模式是00010101,00010110,00011001,00011010,00011100,00100011,等等。以下是计算下一个排列的快速方法。
假设我们有一个将N位设置为1的整数的模式,并且我们希望在词典学意义上对N 1位进行下一个排列。例如,如果N是3和位模式是00010011,下一个模式是00010101,00010110,00011001,00011010,00011100,00100011,等等。以下是计算下一个排列的快速方法。
00010011
00010101
00010110
00011001
00011010
00011100
00100011
> unsigned int v; // current permutation of bits > unsigned int w; // next permutation of bits > > unsigned int t = v | (v - 1); // t gets v's least significant 0 bits set > to 1 > // Next set to 1 the most significant bit to change, > // set to 0 the least significant ones, and add the necessary 1 bits. > w = (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctz(v) + 1));
__builtin_ctz(v)x86 CPU固有的GNU C编译器返回尾随零的数目。如果您将Microsoft编译器用于x86,则固有值为_BitScanForward。它们都发出bsf 指令,但是其他架构也可以使用等效指令。如果不是,则考虑使用一种方法对前面提到的连续零位进行计数。这是另一个版本,由于其除法运算符而趋向于变慢,但它不需要计数尾随零。
__builtin_ctz(v)
_BitScanForward
bsf
> unsigned int t = (v | (v - 1)) + 1; > w = t | ((((t & -t) / (v & -v)) >> 1) - 1);
感谢阿根廷的Dario Sneidermanis,他于2009年11月28日提供了此信息。