小编典典

生成所有长度为n且设置了k位的二进制字符串

algorithm

查找包含k位集合的所有长度为n的二进制字符串的最佳算法是什么?例如,如果n = 4且k = 3,则存在…

0111
1011
1101
1110

我需要一种很好的方法来生成给定的任意n和k,因此我更喜欢使用字符串来完成。


阅读 362

收藏
2020-07-28

共1个答案

小编典典

此方法将生成具有正好N个“ 1”位的所有整数。

来自https://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation

按词典顺序计算下一位排列

假设我们有一个将N位设置为1的整数的模式,并且我们希望在词典学意义上对N
1位进行下一个排列。例如,如果N是3和位模式是00010011,下一个模式是000101010001011000011001000110100001110000100011,等等。以下是计算下一个排列的快速方法。

>     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
指令,但是其他架构也可以使用等效指令。如果不是,则考虑使用一种方法对前面提到的连续零位进行计数。这是另一个版本,由于其除法运算符而趋向于变慢,但它不需要计数尾随零。

>     unsigned int t = (v | (v - 1)) + 1;
>     w = t | ((((t & -t) / (v & -v)) >> 1) - 1);

感谢阿根廷的Dario Sneidermanis,他于2009年11月28日提供了此信息。

2020-07-28