첫 번째 질문에 대한 대답은 간단합니다. C(n,r)
입니다. 여기서 r
개의 항목을 모두 세트로 선택해야합니다. 수식은 다른 장소 간의 here이다
C(n,r) = n!/(r! (n-r)!)
조합으로 조합 번호 i
관한 부호화 데에 달려 다른 모든 컴퓨팅 않고 i'th
조합을 선택하는 기능. 즉
(EDIT)
해결책은 파이썬이 보이는 문제 더 생각해 데 ... 훨씬 더 어려운 것 많은 생각이 필요합니다 :
from math import factorial
def combination(n,r):
return factorial(n)/(factorial(r) * factorial(n-r))
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def showComb(n,r,i,a):
if r < 1:
return ""
rr = r-1
nn = max(n-1,rr)
lasti = i
i -= combination(nn,rr)
j = 0
while i > 0:
j += 1
nn = max(nn-1,1)
rr = min(rr,nn) # corrected this line in second edit
lasti = i
i -= combination(nn,rr)
return a[j] + showComb(n-j-1,r-1,lasti,a[(j+1):])
for i in range(10):
print(showComb(5,3,i+1,alphabet))
을 ... 질문에 표시된 목록을 출력합니다.
내가 사용한 접근법은 나머지 세트 요소의 조합 수를 사용하여 주어진 숫자의 첫 번째 요소가 어느 것인지 찾아내는 아이디어를 사용하여 i'th
출력 세트의 첫 번째 요소를 찾는 것입니다. i
.
즉 C (5,3)의 경우 첫 번째 C (4,2) (= 6) 출력 세트의 첫 문자는 'A'이고 그 다음 C (3,1) (= 3) 출력 세트가 'B'이면 C (1,1) (= 1) 세트의 첫 문자가 'C'입니다.
그런 다음 함수는 나머지 요소를 재귀 적으로 찾습니다. showComb()
은 tail-recursive이므로 원하는 경우 루프로 표시 할 수 있지만 재귀 버전은이 경우 이해하기 쉽습니다.
추가 테스트를 들어, 다음의 코드는 유용 할 수있다 :이 경우, 모든 실시 예 120이 올바른지 확인
import itertools
def showCombIter(n,r,i,a):
return ''.join(list(itertools.combinations(a[0:n],r))[i-1])
print ("\n")
# Testing for other cases
for i in range(120):
x = showComb(10,3,i+1,alphabet)
y = showCombIter(10,3,i+1,alphabet)
print(i+1,"\t",x==y,"\t",x,y)
....
나는 r
될 것입니다 정확히 시간 복잡도하지만 showComb()
에 대한 호출의 수를 계산하지 않은 및 while
루프는 n
배 이하를 실행합니다. 따라서, 질문의 용어에서, 나는 우리가 factorial()
함수가 상수 시간에 계산 될 수 있다고 가정한다면 복잡성은 O (M + N)보다 작을 것이라고 확신합니다. 이것은 나쁜 근사값이라고 생각하지 않습니다. 구현이 순진하지 않는 한.
멋진데! 나는 당신의 해결책을 고치고 있었고 루프를'for range (120) : print (showComb (10,3, i + 1, alphabet))'로 바꾸려고했습니다. 그것은 잘못된 조합을 생성하고 충돌합니다. – dragonroot
@dragonroot : 시험에 감사드립니다! 예, 코드에서 'n-r'이 2보다 클 때 나타나는 버그가있었습니다. 위의 편집 된 답변에서이를 수정했습니다. – Simon
이제 완벽하게 작동합니다! – dragonroot