按位移位以在C中生成所有可能的排列

时间:2011-09-17 01:44:09

标签: c algorithm bit-manipulation permutation combinations

  

可能重复:
  Creating multiple numbers with certain number of bits set

我正在尝试编写一些代码,通过将位移位来将每个可能的数字组合放在一个数组中。

例如,我想找到数组应该包含的所有可能的3位组合(其中最大数字可以是6):

000111
001011
001101
001110
010011
010101
010110
011001
011010
011100
100011

等等......

根据我的解释,当最后一个位置位为1时,我们将数字移1(x> 1)并在开始时加1。但是,我不确定如何编写其余的代码。我用C来写这个。

另外 - 据我所知,这是一个colex序列,但是,如果有另一个序列会给我相同的最终结果,我会全力以赴(带有约束的k位的所有可能组合的数组) N)。

3 个答案:

答案 0 :(得分:6)

您可以通过递归生成序列来解决此问题。

让我们定义一个递归函数f(int index, int bits, int number),它将接收该位的当前index和剩余的bits的数量,并生成number远。然后,您可以选择将当前位设置为1或0,并从那里进行递归。

总的来说,时间复杂度应为O(序列数)或O(N选择B),其中N是数字位数,B是设置为1的位数。

这个功能是这样的:

void f(int index, int bits, int number) {
    if (index == 0) {
        if (bits == 0) {   // all required bits have been used
            emit_answer(number); // chuck number into an array, print it, whatever.
        }   
        return;
    }   

    if (index-1 >= bits) {  // If we can afford to put a 0 here
        f(index-1, bits, number);
    }   

    if (bits > 0) {  // If we have any 1s left to place
        f(index-1, bits-1, number | (1 << (index-1)));
    }   
}

// to call:
f(6, 3, 0); 

对于N,B = 6,3,输出与您的输出匹配,并按排序顺序排列。链接到工作示例:http://codepad.org/qgd689ZM

答案 1 :(得分:2)

可能有一种更有效的方法,但你可以循环查看数字并拒绝没有3位数的数字?请参阅this answer进行位计数。

答案 2 :(得分:2)

无需任何花哨的递归。一些简单的数学就足够了(需要除以一个总是2的幂的值)。

    Function nextBits(ByVal prevVal As Integer)
        Dim lsOne As Integer = ((prevVal - 1) And Not prevVal) + 1
        Dim nextZero As Integer = (prevVal + lsOne) And Not prevVal
        Dim lowBits As Integer = ((nextZero \ lsOne \ 2) - 1)
        Return prevVal + lsOne + lowBits
    End Function

很好,也很容易。