Лучший алгоритм для поиска всех возможных перестановок заданных двоичных битов

Я ищу оптимальный алгоритм, чтобы узнать все возможные перестановки заданного двоичного числа.

Например:

Двоичное число: ........1. алгоритм должен возвращать оставшиеся 2 ^ 7 оставшихся двоичных чисел, например 00000001,00000011 и т. д.

Спасибо, сатиш


person sathishs    schedule 12.11.2009    source источник
comment
Это домашнее задание? Если нет, некоторый контекст был бы полезен.   -  person Bart Kiers    schedule 12.11.2009
comment
Вы имеете в виду, учитывая количество битов? а в вашем примере нет ошибки?   -  person pgras    schedule 12.11.2009


Ответы (8)


Приведенный пример не перестановка!

Перестановка — это переупорядочивание входных данных.

Таким образом, если ввод 00000001, 00100000 и 00000010 являются перестановками, а 00000011 — нет.

person Will    schedule 12.11.2009

Если это только для небольших чисел (вероятно, до 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;
    }
}
person Aaron Digulla    schedule 12.11.2009

чтобы найти все, что вы не собираетесь делать лучше, чем перебирать все числа, например. если вы хотите перебрать все 8-битные числа

for (int i =0; i < (1<<8) ; ++i)
{
  //do stuff with i
}

если вам нужно вывести в двоичном формате, посмотрите на параметры форматирования строки, которые у вас есть на любом языке, который вы используете.

e.g.

printf("%b",i); // не стандартно в C/C++

для расчета база должна быть нерелевантной в большинстве языков.

person jk.    schedule 12.11.2009
comment
Однако, справедливости ради, сатиши упоминали и другие числа 2^7. Я согласен, что это не алгоритм перестановки, но, похоже, он соответствует духу запроса. - person Boojum; 12.11.2009
comment
перестановки числа фиксированного размера идентичны подсчету, или я что-то пропустил? - person jk.; 12.11.2009
comment
@jk: Да, но вы должны сопоставить каждое значение счетчика со значением набора результатов. Вы нигде не предоставляете набор результатов. - person Aaron Digulla; 12.11.2009
comment
+1, я думаю, что это правильно соответствует плохо сформулированному вопросу. Кажется, что OP хочет все двоичные комбинации для заданного количества бит, вот как вы их вычисляете. - person laura; 12.11.2009

Я прочитал ваш вопрос как: «данное двоичное число с некоторыми битами всегда установлено, создайте оставшиеся возможные двоичные числа».

Например, учитывая 1xx1: вы хотите: 1001, 1011, 1101, 1111.

Алгоритм O(N) выглядит следующим образом.

Предположим, что биты определены в маске 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, хотя он вам не понадобился в исходном вопросе, он может быть полезен.

person Slinky    schedule 24.08.2010

Зачем усложняешь! Это так же просто, как следующее:

// 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);
    }
person P. K. Mohanty    schedule 28.04.2011

Существует множество алгоритмов генерации перестановок, которые вы можете использовать, например этот:

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

источник: http://www.bearcave.com/ random_hacks/permute.html

Убедитесь, что вы адаптируете соответствующие константы к вашим потребностям (двоичное число, 7 бит и т. д.).

person Yuval Adam    schedule 12.11.2009

Если вы действительно ищете перестановки, то следующий код должен подойти.

Например, чтобы найти все возможные перестановки данной двоичной строки (шаблона).

Перестановки 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(); 
}
person kofhearts    schedule 29.12.2012

Если вы намерены сгенерировать все комбинации строк для 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);
    }
}
person mohit verma    schedule 09.10.2014