开发者

Bitwise shift to generate all possible permutations in C [duplicate]

开发者 https://www.devze.com 2023-04-06 00:28 出处:网络
This question already has answers here: Closed 11 years ago. Possible Duplicate: Creating multiple numbers with certain number of bits set
This question already has answers here: Closed 11 years ago.

Possible Duplicate:

Creating multiple numbers with certain number of bits set

I'm attempting to write some code which will put each possible combination of numbers in an array by shifting the bits across.

For example, I wanted to find all possible combinations of 3 bits (where the max a digit can be is 6) the array should contain:

000111
001011
001101
001110
010011
010101
010110
011001
011010
011100
100011

And so on...

From what I've interpreted, when the last position bit is 1 we shift the number by 1 (x >> 1) and add a 1 at the start.开发者_StackOverflow However, I'm unsure how to code the rest. I'm using C to write this.

Also - as far as I can tell this is a colex sequence, however, I'm all ears if there is another sequence that will give me the same end result (array with all possible combinations of k-bits with a constraint of N).


You can solve this by generating the sequences recursively.

Let us define a recursive function f(int index, int bits, int number) that will take in the current index of the bit and the number of bits left to place, and the number generated so far. Then, you have the option of setting the current bit to 1 or to 0, and recursing from there.

Overall, the time complexity should be O(number of sequences), or O(N choose B), where N is the number of digits and B is the number of bits set to 1.

The function goes something like this:

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); 

For N,B = 6,3 the output matches yours, and is in sorted order. Link to working example: http://codepad.org/qgd689ZM


There's probably a more efficient way, but you could just loop through the numbers and reject numbers that don't have a bit count of 3? See this answer for bit counting.


No need for any fancy recursion. Some simple math will suffice (a division by a value which will always be a power of two is required).

    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

Nice and easy.

0

精彩评论

暂无评论...
验证码 换一张
取 消