Binary 寻找给定二进制位所有可能排列的最佳算法

Binary 寻找给定二进制位所有可能排列的最佳算法,binary,permutation,Binary,Permutation,我正在寻找一个最佳算法,找出剩余的所有可能的排列 指给定的二进制数 例如: 二进制数是:……1。算法应返回剩余的2^7个二进制数,如0000000 10000011等 谢谢, sathish您可以使用许多置换生成算法,例如: #include <stdio.h> void print(const int *v, const int size) { if (v != 0) { for (int i = 0; i < size; i++) { printf

我正在寻找一个最佳算法,找出剩余的所有可能的排列 指给定的二进制数

例如:

二进制数是:……1。算法应返回剩余的2^7个二进制数,如0000000 10000011等

谢谢,
sathish

您可以使用许多置换生成算法,例如:

#include <stdio.h>

void print(const int *v, const int size)
{
  if (v != 0) {
    for (int i = 0; i < size; i++) {
      printf("%4d", v[i] );
    }
    printf("\n");
  }
} // print


void visit(int *Value, int N, int k)
{
  static level = -1;
  level = level+1; Value[k] = level;

  if (level == N)
    print(Value, N);
  else
    for (int i = 0; i < N; i++)
      if (Value[i] == 0)
        visit(Value, N, i);

  level = level-1; Value[k] = 0;
}

main()
{
  const int N = 4;
  int Value[N];
  for (int i = 0; i < N; i++) {
    Value[i] = 0;
  }
  visit(Value, N, 0);
}
资料来源:


确保根据需要调整相关常量二进制数、7位等。

您可以使用许多置换生成算法,例如:

#include <stdio.h>

void print(const int *v, const int size)
{
  if (v != 0) {
    for (int i = 0; i < size; i++) {
      printf("%4d", v[i] );
    }
    printf("\n");
  }
} // print


void visit(int *Value, int N, int k)
{
  static level = -1;
  level = level+1; Value[k] = level;

  if (level == N)
    print(Value, N);
  else
    for (int i = 0; i < N; i++)
      if (Value[i] == 0)
        visit(Value, N, i);

  level = level-1; Value[k] = 0;
}

main()
{
  const int N = 4;
  int Value[N];
  for (int i = 0; i < N; i++) {
    Value[i] = 0;
  }
  visit(Value, N, 0);
}
资料来源:


确保根据需要调整相关常数,如二进制数、7位等。

以找到比循环所有数字更好的方法,例如,如果要循环所有8位数字

for (int i =0; i < (1<<8) ; ++i)
{
  //do stuff with i
}
如果需要以二进制格式输出,请查看您使用的任何语言中的字符串格式选项

e、 g

printf%b,i//C/C中不标准++


对于计算来说,在大多数语言中,基数应该是不相关的。

要找到所有你不会比循环所有数字做得更好的东西,例如,如果你想循环所有8位数字

for (int i =0; i < (1<<8) ; ++i)
{
  //do stuff with i
}
如果需要以二进制格式输出,请查看您使用的任何语言中的字符串格式选项

e、 g

printf%b,i//C/C中不标准++

对于计算,在大多数语言中,基应该是不相关的。

给出的示例不是排列

排列是输入的重新排序

因此,如果输入是00000001,00100000和00000010是排列,而00000011不是。

给出的示例不是排列

排列是输入的重新排序


因此,如果输入为00000001、00100000和00000010是排列,但00000011不是。

如果这仅适用于可能高达16位的小数字,则只需迭代所有输入并忽略不匹配:

int fixed = 0x01; // this is the fixed part
int mask = 0x01; // these are the bits of the fixed part which matter
for (int i=0; i<256; i++) {
    if (i & mask == fixed) {
        print i;
    }
}

如果这仅适用于可能高达16位的小数字,则只需迭代所有数字并忽略不匹配:

int fixed = 0x01; // this is the fixed part
int mask = 0x01; // these are the bits of the fixed part which matter
for (int i=0; i<256; i++) {
    if (i & mask == fixed) {
        print i;
    }
}

我把你的问题理解为:给定一个二进制数,并且总是设置一些位,创建剩余的可能的二进制数

例如,给定1xx1:youwant:1001011111111

下面是一个关于算法的例子

假设位在掩码m中定义。你还有一个散列h

要生成小于n-1的数字,请使用伪代码:

counter = 0 for x in 0..n-1: x' = x | ~m if h[x'] is not set: h[x'] = counter counter += 1 代码中的思想是遍历从0到n-1的所有数字,并将预定义位设置为1。然后,通过将结果编号映射到运行计数器的值来记忆尚未记忆的结果编号


h的关键是排列。作为奖励,h[p]将包含排列p的唯一索引号,尽管您在原始问题中不需要它,但它可能会很有用。

我将您的问题理解为:给定一些始终设置了某些位的二进制数,创建剩余的可能二进制数

例如,给定1xx1:youwant:1001011111111

下面是一个关于算法的例子

假设位在掩码m中定义。你还有一个散列h

要生成小于n-1的数字,请使用伪代码:

counter = 0 for x in 0..n-1: x' = x | ~m if h[x'] is not set: h[x'] = counter counter += 1 代码中的思想是遍历从0到n-1的所有数字,并将预定义位设置为1。然后,通过将结果编号映射到运行计数器的值来记忆尚未记忆的结果编号


h的关键是排列。作为奖励,h[p]将包含排列p的唯一索引号,尽管您在最初的问题中不需要它,但它可能很有用。

为什么要把它复杂化! 它非常简单,如下所示:

// permutation of i  on a length K 
// Example  : decimal  i=10  is permuted over length k= 7 
//  [10]0001010-> [5] 0000101-> [66] 1000010 and 33, 80, 40, 20  etc.

main(){
int i=10,j,k=7; j=i;
do printf("%d \n", i= ( (i&1)<< k + i >>1); while (i!=j);
    }

你为什么把事情弄得这么复杂! 它非常简单,如下所示:

// permutation of i  on a length K 
// Example  : decimal  i=10  is permuted over length k= 7 
//  [10]0001010-> [5] 0000101-> [66] 1000010 and 33, 80, 40, 20  etc.

main(){
int i=10,j,k=7; j=i;
do printf("%d \n", i= ( (i&1)<< k + i >>1); while (i!=j);
    }

如果您真的在寻找置换,那么下面的代码应该可以

例如,查找给定二进制字符串模式的所有可能排列

1000的排列为1000、0100、0010、0001:

void permutation(int no_ones, int no_zeroes, string accum){
    if(no_ones == 0){
        for(int i=0;i<no_zeroes;i++){
            accum += "0";
        }

        cout << accum << endl;
        return;
    }
    else if(no_zeroes == 0){
        for(int j=0;j<no_ones;j++){
            accum += "1";
        }

        cout << accum << endl;
        return;
    }

    permutation (no_ones - 1, no_zeroes, accum + "1");
    permutation (no_ones , no_zeroes - 1, accum + "0");
}

int main(){
    string append = "";

    //finding permutation of 11000   
    permutation(2, 6, append);  //the permutations are 

    //11000
    //10100
    //10010
    //10001
    //01100
    //01010

    cin.get(); 
}

如果您真的在寻找置换,那么下面的代码应该可以

例如,查找给定二进制字符串模式的所有可能排列

1000的排列为1000、0100、0010、0001:

void permutation(int no_ones, int no_zeroes, string accum){
    if(no_ones == 0){
        for(int i=0;i<no_zeroes;i++){
            accum += "0";
        }

        cout << accum << endl;
        return;
    }
    else if(no_zeroes == 0){
        for(int j=0;j<no_ones;j++){
            accum += "1";
        }

        cout << accum << endl;
        return;
    }

    permutation (no_ones - 1, no_zeroes, accum + "1");
    permutation (no_ones , no_zeroes - 1, accum + "0");
}

int main(){
    string append = "";

    //finding permutation of 11000   
    permutation(2, 6, append);  //the permutations are 

    //11000
    //10100
    //10010
    //10001
    //01100
    //01010

    cin.get(); 
}

如果您打算为n位生成所有字符串组合,那么可以使用回溯来解决问题

给你:

//Generating all string of n bits assuming A[0..n-1] is array of size n
public class Backtracking {

    int[] A;

    void Binary(int n){
        if(n<1){
            for(int i : A)
            System.out.print(i);
            System.out.println();
        }else{
            A[n-1] = 0;
            Binary(n-1);
            A[n-1] = 1;
            Binary(n-1);
        }
    }
    public static void main(String[] args) {
        // n is number of bits
        int n = 8;

        Backtracking backtracking = new Backtracking();
        backtracking.A = new int[n];
        backtracking.Binary(n);
    }
}

如果您打算为n位生成所有字符串组合,那么可以使用回溯来解决问题

给你:

//Generating all string of n bits assuming A[0..n-1] is array of size n
public class Backtracking {

    int[] A;

    void Binary(int n){
        if(n<1){
            for(int i : A)
            System.out.print(i);
            System.out.println();
        }else{
            A[n-1] = 0;
            Binary(n-1);
            A[n-1] = 1;
            Binary(n-1);
        }
    }
    public static void main(String[] args) {
        // n is number of bits
        int n = 8;

        Backtracking backtracking = new Backtracking();
        backtracking.A = new int[n];
        backtracking.Binary(n);
    }
}

这是家庭作业吗?如果没有,一些上下文将是有用的。你的意思是给定比特数?你的例子中没有错误吗?这是家庭作业吗?如果没有,一些上下文将是有用的。你的意思是给定比特数?你的例子中不是有错误吗?不过,为了公平起见,萨提斯确实提到了其他的2^7
数字。我同意这不是一个置换算法,但它似乎符合请求的精神。固定大小数字的置换与计数是相同的,还是我遗漏了什么?@jk:是的,但您必须将每个计数器值映射到结果集的一个值。你没有在任何地方提供结果集。+1,我认为这与措辞拙劣的问题是正确的。OP似乎需要给定位数的所有二进制组合,这是计算它们的方式。不过,公平地说,Sathis确实提到了其他2^7个数字。我同意这不是一个置换算法,但它似乎符合请求的精神。固定大小数字的置换与计数是相同的,还是我遗漏了什么?@jk:是的,但您必须将每个计数器值映射到结果集的一个值。你没有在任何地方提供结果集。+1,我认为这与措辞拙劣的问题是正确的。OP似乎需要给定位数的所有二进制组合,这是计算它们的方式。