Я хочу программу, которая записывает каждую возможную комбинацию в другую строку текстового файла - PullRequest
4 голосов
/ 28 октября 2008

Я хочу написать программу, которая печатала бы каждую комбинацию набора переменных в текстовый файл, создавая список слов. Каждый ответ должен быть записан в отдельной строке и записывать все результаты для 1 цифры, 2 цифры и 3 цифры в один текстовый файл.

Есть ли простой способ, которым я могу написать программу на Python, которая может выполнить это? Вот пример вывода, который я ожидаю при печати всех возможных комбинаций двоичных чисел для 1, 2 и 3 цифр:

Output:
0  
1

00  
01  
10  
11

000  
001  
010  
011  
100  
101  
110  
111

Ответы [ 4 ]

3 голосов
/ 28 октября 2008

Наивное решение, которое решает проблему и является достаточно общим для любого приложения, которое у вас может быть, это:

def combinations(words, length):
    if length == 0:
        return []
    result = [[word] for word in words]
    while length > 1:
        new_result = []
        for combo in result:
            new_result.extend(combo + [word] for word in words)
        result = new_result[:]
        length -= 1
    return result

По сути, это постепенно создает дерево в памяти всех комбинаций, а затем возвращает их. Однако он требует большой памяти и поэтому не подходит для крупномасштабных комбинаций.

Другое решение этой проблемы, действительно, заключается в использовании подсчета, но затем для преобразования сгенерированных чисел в список слов из списка слов. Для этого нам сначала понадобится функция (называемая number_to_list()):

def number_to_list(number, words):
    list_out = []
    while number:
        list_out = [number % len(words)] + list_out
        number = number // len(words)
    return [words[n] for n in list_out]

Фактически это система преобразования десятичных чисел в другие базы. Затем мы пишем функцию подсчета; это относительно просто и составит ядро ​​приложения:

def combinations(words, length):
    numbers = xrange(len(words)**length)
    for number in numbers:
        combo = number_to_list(number, words)
        if len(combo) < length:
            combo = [words[0]] * (length - len(combo)) + combo
        yield combo

Это генератор Python; создание генератора позволяет использовать меньше оперативной памяти. После превращения числа в список слов нужно проделать небольшую работу; это потому, что эти списки будут нуждаться в заполнении, чтобы они были на запрошенной длине Это будет использовано так:

>>> list(combinations('01', 3))
[['0', '0', '0'], ['0', '0', '1'],
['0', '1', '0'], ['0', '1', '1'],
['1', '0', '0'], ['1', '0', '1'],
['1', '1', '0'], ['1', '1', '1']]

Как видите, вы получаете список списков. Каждый из этих подсписков содержит последовательность исходных слов; Затем вы можете сделать что-то вроде map(''.join, list(combinations('01', 3))), чтобы получить следующий результат:

['000', '001', '010', '011', '100', '101', '110', '111']

Вы можете записать это на диск; однако, лучшей идеей было бы использовать встроенные оптимизации, которые есть у генераторов, и сделать что-то вроде этого:

fileout = open('filename.txt', 'w')
fileout.writelines(
    ''.join(combo) for combo in combinations('01', 3))
fileout.close()

При этом будет использоваться только столько оперативной памяти, сколько необходимо (достаточно для хранения одной комбинации). Надеюсь, это поможет.

3 голосов
/ 28 октября 2008
# Given two lists of strings, return a list of all ways to concatenate
# one from each.
def combos(xs, ys):
    return [x + y for x in xs for y in ys]

digits = ['0', '1']
for c in combos(digits, combos(digits, digits)):
    print c

#. 000
#. 001
#. 010
#. 011
#. 100
#. 101
#. 110
#. 111
2 голосов
/ 28 октября 2008

Основная функция для создания всех перестановок списка приведена ниже. В этом подходе перестановки создаются лениво с помощью генераторов.

def perms(seq):
    if seq == []:
        yield []
    else:
        res = []
        for index,item in enumerate(seq):
            rest = seq[:index] + seq[index+1:]
            for restperm in perms(rest):
                yield [item] + restperm

alist = [1,1,0]
for permuation in perms(alist):
    print permuation
2 голосов
/ 28 октября 2008

Это не должно быть слишком сложно в большинстве языков. Помогает ли следующий псевдокод?

for(int i=0; i < 2^digits; i++)
{
     WriteLine(ToBinaryString(i));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...