Все возможные комбинации в C

Я пытаюсь найти эффективный алгоритм в C, который предоставляет мне все комбинации данной кодировки.

Алгоритм не должен быть рекурсивным. Наконец, число цифр должно быть гибким. Например:

char set[] = "a1"; -> a1 aa 1a 11 

Я нашел решение Perl, но использует substr() . Я думаю, что это было не так быстро.

Для большинства алгоритмов в C я нашел только перестановки …

Статья на немецком форуме C ++ утверждает, что решения C ++ – STL быстрее, чем «исходные» рекурсивные алгоритмы.

    Если заданный размер был фиксированным N, это было бы просто – вы могли бы просто иметь N for циклов, каждый из которых вложен в предыдущий. Поскольку вы не можете этого сделать, и вы не можете использовать рекурсию, вам нужно вычислить общее количество итераций (похоже, это N ^ M), используйте один единственный цикл, а затем используйте / и% для вычисления того, что индекс массива каждого персонажа. Вам также лучше использовать длинные, потому что N ^ M становится очень быстрым.

    В Википедии есть код C для n-арного кода Grey . Он должен быть преобразован в вашу проблему, используя цифры в качестве смещений в вашем массиве ввода. Вам нужно будет сделать динамическое распределение для обработки произвольной длины ввода. Связанный подход состоит в том, чтобы делать вложенные циклы, где у вас есть массив счетчиков циклов, пока ваш вход, и другой счетчик, для которого из тех, которые вы в настоящее время увеличиваете. Например, распечатывая все шестизначные номера базы-шесть, необходимо изменить для динамического распределения, но показывает принцип:

     int i; int length = 5; int max = 6; int counters[length]; for (i=0; i=0; i--) printf("%d", counters[i]); printf("\n"); for(i=0; i= length) break; } 

    Python очень близок к псевдокоду.

    Вы можете прочитать источник Python для itertools.permutations и просто реплицировать на C.

    Вот демо, которое это работает:

     #!/usr/bin/env python import itertools s='a1' print set(itertools.permutations(s*len(s), len(s))) 

    Выход:

     set([('1', '1'), ('a', '1'), ('a', 'a'), ('1', 'a')]) 

    Вот еще более простой способ:

     >>> s='a1' >>> ['{}{}'.format(x,y) for x in s for y in s] ['aa', 'a1', '1a', '11'] >>> s='abc' >>> ['{}{}{}'.format(x,y,z) for x in s for y in s for z in s] ['aaa', 'aab', 'aac', 'aba', 'abb', 'abc', 'aca', 'acb', 'acc', 'baa', 'bab', 'bac', 'bba', 'bbb', 'bbc', 'bca', 'bcb', 'bcc', 'caa', 'cab', 'cac', 'cba', 'cbb', 'cbc', 'cca', 'ccb', 'ccc'] 

    Чтобы раскрыть список, используйте NESTED LOOPS, например:

     >>> for x in s: ... for y in s: ... for z in s: ... print '{}{}{}'.format(x,y,z) 

    Ну, я бы подсчитал возможные комбинации, пропустил числа и конвертировал.

    Например: чтобы сгенерировать все комбинации из 3-х символов из 10 символов {‘0’, ‘1’, …, ‘9’}, я бы сделал цикл от 0 до 999 и вывел «000» в «999».

    Точно так же (kinda), чтобы сгенерировать все комбинации 3-го размера из 5 символов {‘a’, ‘b’, …, ‘e’}, я бы сделал цикл от 0 до 5 * 5 * 5-1 и вывод номер цикла в базе 5, но с предоставленными символами.

    Напишите функцию, которая преобразует целое число в шестнадцатеричное число строки, а затем преобразует этот алгоритм в базу 36 (az плюс 0-9). Используйте один для цикла для подсчета от 1 до (цифра счетчика времени базы) и каждый раз вызывайте свою функцию.

    • 1 становится 1
    • 10 становится
    • 35 становится z
    • 36 становится 10
    • 46 становится 1a