2008-10-27 6 views
4

단어 집합을 만드는 텍스트 파일에 변수 집합의 모든 조합을 인쇄하는 프로그램을 작성하고 싶습니다. 각 답변은 별도의 줄에 작성해야하며 1 자리, 2 자리 및 3 자리의 모든 결과를 단일 텍스트 파일에 작성해야합니다.모든 가능한 조합을 텍스트 파일의 다른 줄에 쓰는 프로그램을 원합니다.

이 작업을 수행 할 수있는 Python 프로그램을 작성하는 간단한 방법이 있습니까? 여기에 모든 진수를 인쇄 할 때 내가 기대하고있는 출력의 예는 1, 2, 3 자리에 대한 가능한 조합이다

Output: 
0 
1 

00 
01 
10 
11 

000 
001 
010 
011 
100 
101 
110 
111 
+0

프로그래밍 경험이 있다면 무엇보다도이 프로그램은 매우 쉽습니다. 두 번째로, 왜 이것을하고 싶습니까? 나는 그것에 대한 어떠한 정당한 이유도 생각할 수 없다. 아마도 당신이 우리에게 이유를 말할 수 있다면, 우리는 당신을 더 잘 조종하도록 도울 수 있습니다. – davr

+2

나는 배후에있는 기본 개념을 이해하는 것 외에 다른 프로그래밍 경험이 없다. 이것은 이론적 관점에서 프로그래밍을 더 잘 이해할 수있게 도와주는 내 호기심 때문이었습니다. –

+1

이것은 프로그래밍의 이론적 개념을 더 잘 이해할 수있는 방법은 아닙니다. 그렇게하고 싶다면, 책을 읽고, 웹을 검색하고, 스스로 문제를 해결하려고 노력하십시오. 우리가 당신을 위해 숙제를 해주기를 바랍니다. – Sandman

답변

3

문제를 해결하고 당신이 가진 수있는 응용 프로그램을위한 충분한 일반적이다 순진 해결책은 이것이다 그들을 반환합니다. 그러나 메모리 집약적이므로 대량의 조합에는 비실용적입니다.

문제에 대한 또 다른 해결책은 실제로 카운팅을 사용하지만 생성 된 숫자를 단어 목록의 단어 목록으로 변환하는 것입니다. 이렇게하려면 우리가 먼저 기능 (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 

이것은 파이썬 생성기입니다. 생성기로 사용하면 RAM을 적게 차지합니다. 숫자를 단어 목록으로 변환 한 후에해야 할 일이 조금 있습니다. 이 목록은 요청 된 길이가되도록 패딩이 필요할 것이기 때문입니다. 다음과 같이 사용됩니다 :

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

이는 (하나 개의 조합을 저장하기에 충분한) 필요한만큼의 RAM을 사용합니다. 이게 도움이 되길 바란다.

2

그것은 대부분의 언어에 너무 열심히해서는 안됩니다. 다음 의사 코드가 도움이됩니까?

for(int i=0; i < 2^digits; i++) 
{ 
    WriteLine(ToBinaryString(i)); 
} 
+0

이진 숫자 문자열에서 작동하며 대부분의 숫자 문자열에서 작동하도록 만들 수 있습니다. 그것은 일련의 단어들과 같은보다 임의적 인 것들에 쉽게 적응하지 못할 것입니다. –

+0

집합의 각 단어를 n-base 번호 시스템에서 숫자로 처리하면 이 작동합니다. – vrdhn

3
# 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 
+0

세트가 큰 경우 스토리지를 많이 사용하지만 디스크에 저장하는 것이 동시에 비용이 많이 든다고 효과적으로 주장 할 수 있습니다. –

+0

목록 이해력 대신 발전기 이해력으로 해결할 수있는 방법이 있지만 입력 반복기의 사본을 만들어야합니다. (한 번만 반복자를 사용할 수 있습니다. 하스켈이 아니라는 것을 당 파이썬!) –

+0

대신 생성자가없는 명백한 재귀 코드를 작성합니다. –

2

리스트의 모든 순열을 생성하는 기본 기능은 아래에 주어진다. 이 방법에서, 순열은 생성자를 사용하여 느리게 생성됩니다.

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 

는 기본적으로,이 점차적으로 모든 조합의 메모리에 트리를 구축하고 :

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 
+0

[1,0] 대신 [1,1,0]을 사용 하시겠습니까? 그렇다면 설명하십시오. –

+0

질문은 퍼뮤 테이션이 아닌 파워 세트에 관한 것 같습니다. 이 코드는 n! 결과, 2 ** n 결과가 아닙니다. –

관련 문제