문제

최근 나는 기능을 생성하는 특정 시퀀스로 사소하지 않은 제약 조건이 있습니다.문제로 온 천연 재귀적인 솔루션입니다.지금 그것을 발생,심지어 상대적으로 작은 입력,시퀀스가 여러 가지 수천,따라서 나는 것을 선호하는 알고리즘을 사용으로 발전기를 사용하는 대신 그것을 채우기 위해 목록으로 모든 시퀀스입니다.

여기에는 예입니다.한다고 가정하여 계산의 모든 순열과 함께 문자열을 재귀적 기능입니다.다음과 같은 순진한 알고리즘은 추가로 인수는'저장'추가합니다 en 을 때마다 그것은 그것을 발견하지 못하고 있습니다.:

def getPermutations(string, storage, prefix=""):
   if len(string) == 1:
      storage.append(prefix + string)   # <-----
   else:
      for i in range(len(string)):
         getPermutations(string[:i]+string[i+1:], storage, prefix+string[i])

storage = []
getPermutations("abcd", storage)
for permutation in storage: print permutation

(주시기 바랍에 대해 걱정하지 않는 비효율성,이것은 예입니다.)

지금 내가 원하는 기능으로 발전기,즉수익률 순열 끝에 추가하는 대신해관 목록:

def getPermutations(string, prefix=""):
   if len(string) == 1:
      yield prefix + string             # <-----
   else:
      for i in range(len(string)):
         getPermutations(string[:i]+string[i+1:], prefix+string[i])

for permutation in getPermutations("abcd"):
   print permutation

이 코드는 일(는 기능이 동작과 같은 빈 발전기).

나는 뭔가?는 방법이 있을 돌 위에 재귀적 알고리즘으로 발전기 대체하지 않고 그것으로 반복적인 중 하나?

도움이 되었습니까?

해결책

def getPermutations(string, prefix=""):
    if len(string) == 1:
        yield prefix + string
    else:
        for i in xrange(len(string)):
            for perm in getPermutations(string[:i] + string[i+1:], prefix+string[i]):
                yield perm

또는 어큐뮬레이터:

def getPermutations(string):
    if len(string) == 1:
        yield string
    else:
        for i in xrange(len(string)):
            for perm in getPermutations(string[:i] + string[i+1:]):
                yield string[i] + perm

다른 팁

이렇 len(string)-깊은 재귀,과는 일반적으로 좋은 방법을 처리하기 발전기 내부는 발전기:

from types import GeneratorType

def flatten(*stack):
    stack = list(stack)
    while stack:
        try: x = stack[0].next()
        except StopIteration:
            stack.pop(0)
            continue
        if isinstance(x, GeneratorType): stack.insert(0, x)
        else: yield x

def _getPermutations(string, prefix=""):
    if len(string) == 1: yield prefix + string
    else: yield (_getPermutations(string[:i]+string[i+1:], prefix+string[i])
            for i in range(len(string)))

def getPermutations(string): return flatten(_getPermutations(string))

for permutation in getPermutations("abcd"): print permutation

flatten 우리는 계속 할 수 있습 진행 상황에서 다른 발전기 간단히 yielding 는 대신,그것을 반복하고 yielding 각 품목을 수 있습니다.


Python3.3 추가 yield from 구문 할 수있는 자연을 위해 대표단위-발전기:

def getPermutations(string, prefix=""):
    if len(string) == 1:
        yield prefix + string
    else:
        for i in range(len(string)):
            yield from getPermutations(string[:i]+string[i+1:], prefix+string[i])

인테리어를 호출하 getPermutations-그것은 발전기,too.

def getPermutations(string, prefix=""):
   if len(string) == 1:
      yield prefix + string            
   else:
      for i in range(len(string)):
         getPermutations(string[:i]+string[i+1:], prefix+string[i])  # <-----

당신이 필요하를 반복하는 것에 대한 반복(보@MizardX 게시는 예리하게 저해 초!)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top