按位移位生成C中所有可能的置换

按位移位生成C中所有可能的置换,c,algorithm,bit-manipulation,permutation,combinations,C,Algorithm,Bit Manipulation,Permutation,Combinations,可能重复: 我正试图编写一些代码,通过移位位,将每个可能的数字组合放入一个数组中 例如,我想找到数组应包含的所有可能的3位组合(其中a位的最大值为6): 000111 001011 001101 001110 010011 010101 010110 011001 011010 011100 100011 000111 001011 001101 001110 010011 010101 010110 011001 011010 011100 100011 等等 根据我的解释,当最后一个位置位

可能重复:

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

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

000111 001011 001101 001110 010011 010101 010110 011001 011010 011100 100011 000111 001011 001101 001110 010011 010101 010110 011001 011010 011100 100011 等等

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


另外-据我所知,这是一个colex序列,但是,如果有另一个序列会给我相同的最终结果(具有所有可能的k位组合且约束为N的数组),我洗耳恭听。

可能有一种更有效的方法,但是你可以循环使用这些数字,然后拒绝没有3的数字?有关位计数,请参阅。

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

让我们定义一个递归函数
f(int-index,int-bits,int-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); 
void f(整数索引、整数位、整数编号){
如果(索引==0){
如果(位==0){//已使用所有必需位
emit_answer(number);//将数字放入数组中,打印它,无论什么。
}   
返回;
}   
如果(index-1>=bits){//如果我们可以在这里放一个0
f(索引-1,位,数字);
}   
如果(位>0){//如果我们还有1要放

f(索引-1,位-1,数字|)(1不需要任何花哨的递归。一些简单的数学就足够了(需要除以一个总是2的幂的值)

函数nextBits(ByVal prevVal作为整数) Dim lsOne为整数=((prevVal-1)而非prevVal)+1 Dim nextZero为整数=(prevVal+lsOne)而非prevVal 将低位设置为整数=((nextZero\lsOne\2)-1) 返回prevVal+lsOne+低位 端函数
非常简单。

然后你必须通过2^N组合,这可能会非常慢。然后,他只需要6位,所以应该可以。这非常慢,O(2^N),就像quasiverse指出的。我的解决方案应该生成所有有效序列,没有任何浪费。好的,当然。它是O(2^6)不过,我认为如果速度真的是一个问题,他可以提前计算出数字并保存下来。那就是O(1):-p更不用说这个解决方案相对于其他一些解决方案的可读性了。耸耸肩,.Uhh…我的大脑受到了代码的伤害。还有,\运算符是什么?也许解释一下为什么这样做会有帮助。请给代码添加更多解释。OP似乎对C代码感兴趣,这看起来更像是VB-ish。对不起,我测试了这个在VB.NET中使用e算法并复制/粘贴代码。相同的算法应该可以很容易地适用于任何其他公共语言。VB.NET的一个方面我忘记了人们不会知道,它使用不同的运算符进行分数除法和整数除法,因此
15/4
产生3.75,但是
15\4
产生3。Pyth等价的是
/
运算符,C等价的是带有整数操作数的
/
运算符(如果想要除以两个整数得到分数结果,则需要显式强制转换或强制转换)@Hritik:我认为这个问题看起来像是家庭作业,所以我想我想引导这个人走向正确的方向,而不是给出一个他们不用思考或理解就可以使用的解决方案。尝试一些不同的值,看看每个变量最终以二进制形式出现,应该会揭示出发生了什么。谢谢@evgeny.Pla通过这一点,我学到了一些东西。关于dupe——对于那些感兴趣的人,请点击dupe链接并阅读斯坦福资源。对我帮助很大。 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