2012-06-05 2 views
1

누구나 내게이 순열 algo을 설명 할 수 있을까? 나는 그것이 pemutations는 것을 알고 있지만, 나는 그것이 작동하는 이유를 알아낼 수 없습니다. 그것은 호출 기능에 대한 변경은 호출자의 배열에 영향을 미치지 않도록 s (목록), 변경할 수 있음을 의미 파이썬 코드 때문에나에게 순열에 대해이 고인을 설명 할 수 있습니까?

s = [1,2,3,4,5,6,7,8,9] 
def perm(s, i): 
    if i == len(s): 
     print s 
    for j in range(i, len(s)): 
     s[i], s[j] = s[j], s[i] 
     perm(s, i + 1) 
     s[i], s[j] = s[j], s[i] //why it swaps back?  
+0

@ Jason 전화가 어느 시점에서 돌아옵니다. –

+0

@Jason 재귀 호출이 돌아 오면 다시 전환됩니다. –

+0

@Jason 재귀 호출은 동일한 스왑 백 라인을 사용하여 스스로 실행 취소합니다. –

답변

2

이 함수는 배열 s을 각 가능한 순열로 변형 한 다음 순열을 인쇄하고 뒤의 돌연변이를 되돌립니다. 각 위치 i에서

, 그것은, 위치 i의 모든 나중에 값을 시도 혼자 i보다 인덱스 모든 항목을 잎 고정 값의 설정 및 위치 i에서 무엇을 위해 각 선택 모든 순열을 찾기 위해 재귀를 사용 . 가장 높은 인덱스에는 남은 선택 항목이 없지만 순열 중 하나를 찾았으므로 그 결과로 결과가 인쇄됩니다.

이 재귀를 이해하면 함수의 시작과 끝,이 경우 스왑의 흥미로운 지점에 코드에 "디버그 인쇄물"을 추가하는 것이 도움이된다는 것을 알았습니다.

분명히 가장 우아한 파이썬이 아니기 때문에 (일부 디버그 프린트는 기능으로 추출되어야 함) 이러한 "디버그 프린트"가 추가 된 코드의이 버전을 실행하면 도움이 될 수 있습니다.

def perm(s, i): 
    print '{padding}starting perm({list}, {index})'.format(list=s, index=i, padding=' '*i) 
    if i == len(s): 
     print s 
    for j in range(i, len(s)): 
     print '{padding}swapping s[{index1}]={entry1} and s[{index2}]={entry2}'.format(index1=i, entry1=s[i], index2=j, entry2=s[j], padding=' '*i) 
     s[i], s[j] = s[j], s[i] 
     perm(s, i + 1) 
     print '{padding}swapping back s[{index1}]={entry1} and s[{index2}]={entry2}'.format(index1=i, entry1=s[i], index2=j, entry2=s[j], padding=' '*i) 
     s[i], s[j] = s[j], s[i] 
    print '{padding}returning from perm({list}, {index})'.format(list=s, index=i, padding=' '*i) 
0

는 다시 스왑.

다시 스왑되지 않으면 배열이 "이상한"상태 (이전 호출에서 남음)가됩니다.

대안, 돌연변이를 필요가 없습니다 즉,이다 : 아마도

s = [1,2,3,4,5,6,7,8,9] 
def perm(s, i): 
    s = list(s) # copy before mutating 
    if i == len(s): 
     print s 
    for j in range(i, len(s)): 
     s[i], s[j] = s[j], s[i] 
     perm(s, i + 1) 

또는 명확 : 이것은을 downvoted 이유를 확실

 
    s = [1,2,3,4,5,6,7,8,9] 
      def perm(s, i): 
        if i == len(s): 
            print s 
        for j in range(i, len(s)): 
            s[i], s[j] = s[j], s[i] 
            perm(list(s), i + 1) # pass a copy 

코멘트은. 사용자가 동시에 질문에 대한 의견을 제출했지만 삭제했습니다. 나는 그들이 실수라고 생각하고, 나는 그 주석을 삭제하는 것이 그들이 그것을 깨달았다는 것을 의미한다고 생각하지만, 나는 왜 그들이 downvote를 제거하지 않았는지 보지 못한다. 만약 이것이 틀렸다면 누군가가 설명 할 수 있도록 설명해주십시오.

+0

+1 하찮은 downvote 카운터. –

관련 문제