def permute2(seq): if not seq: # 모든 시퀀스 섞기: 제너레이터 yield seq # 빈 시퀀스 else: for i in range(len(seq)): rest = seq[:i] + seq[i + 1:] # 현재 노드 삭제 for x in permute2(rest): # 나머지들의 순열 yield seq[i:i + 1] + x # 앞쪽에 노드 추가
#!/usr/bin/python3.3 import math print(math.factorial(10)) from permute import permute2 seq = list(range(10)) p2 = permute2(seq) print(next(p2)) print(next(p2)) seq = list(range(50)) p3 = permute2(seq) print(next(p3)) import random seq = list(range(20)) p4 = permute2(seq) print(next(p4)) print(next(p4)) random.shuffle(seq) print(next(p4)) print(next(p4))
import math from permute import permute1, permute2 math.factorial(10) seq = list(range(10)) # p1 = permute1(seq) # print(len(p1), p1[0], p1[1]) p2 = permute2(seq) print(next(p2)) print(next(p2))
else: for i in range(len(seq)): rest = seq[:i] + seq[i + 1:] # 현재 노드 삭제 for x in permute2(rest): # 나머지들의 순열 yield seq[i:i + 1] + x # 앞쪽에 노드 추가 from scramble import scramble from permute import permute1, permute2 list(scramble('abc')) # 단순 뒤섞기: N # ['abc', 'bca', 'cab'] permute1('abc') # 가장 큰 순열: N # ['abc', 'acb', 'bac', 'bca', 'cab', 'cba'] list(permute2('abc')) # 모든 조합 생성 # ['abc', 'acb', 'bac', 'bca', 'cab', 'cba'] G = permute2('abc') # 반복(iter()는 불필요함) next(G) # 'abc' next(G) # 'acb' for x in permute2('abc'): print(x) # 자동 반복 # ...6 라인 출력... permute1('spam') == list(permute2('spam')) # True len(list(permute2('spam'))), len(list(scramble('spam'))) # (24, 4)
# 제너레이터를 남용하지 말자: EIBTI # 또 다른 측면에서: 메모리, 지연 시간, 간결성, 표현력 import math math.factorial(10) # 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 # 3628800 from permute import permute1, permute2 seq = list(range(10)) p1 = permute1(seq) # 2GHz 쿼드 코어 장비에서 37초가 걸리며, # 360만 수를 가진 리스트를 만듦 len(p1), p1[0], p1[1] # (3628800, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 9, 8]) p2 = permute2(seq) # 제너레이터를 즉시 반환하며, next(p2) # 요청 시에 각각의 결과를 빠르게 생성함 # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] next(p2) # [0, 1, 2, 3, 4, 5, 6, 7, 9, 8] p2 = list(permute2(seq)) # 비록 비현실적이지만 약 28초가 걸림 p1 == p2 # True math.factorial(50) # 30414093201713378043612608166064768844377641568960512000000000000 p3 = permute2(list(range(50))) next(p3) # permute1은 여기서 고려 대상이 아님! # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49] import random