동적 프로그래밍 공부 중인데
주어진 numbers를 사용해서 targetSum이 되도록 더하는 조합 중에 가장 짧은 조합을 찾는 함수 bestSum(targetSum, numbers)을 작성하는 문제인데 파이썬 이용해서 연습해봄
그래서 아 됐다 싶어서 결과 돌려보는데 이상한 일이 일어남
def bestSum(
targetSum:int,numbers:list[int],memo:dict[int, list[int]]={}) -> list[int]:if targetSum in memo:return memo[targetSum]
if targetSum == 0:return []if targetSum < 0:return None
bestComb = Nonefor n in numbers:remainder = targetSum - n
res = bestSum(remainder, numbers)if res is not None:comb = [*res, n]if bestComb is None or len(bestComb) > len(comb):bestComb = comb
memo[targetSum] = bestComb
return bestComb
print(bestSum(7, [5, 3, 4, 7]))print(bestSum(8, [2, 3, 5]))print(bestSum(100, [1, 2, 5, 25]))print(bestSum(300, [10, 30]))
마지막 print(bestSum(300, [10, 30]))의 출력은 30 열 개여야 하는데 뜬금없이 25랑 10이 튀어나옴... 뭐임?
하나씩 따로따로 할 때에는 결과 잘 나오는데...
마지막 2개 서순 바꿔서 해보면 또 이상한 결과 나오더라
대체 왜 이러는지 모르겠다
전역변수 쓴 것도 아니고 함수 각 호출이 다른 함수 호출에 간섭할 리도 없는데 대체 왜 이런 결과가 나오는지 정말정말 이해가 안 간다
옛날에 공부했던 거 가물가물 떠올리면서 c++ 문법의 개같음을 느끼며 옮겼을 때에는 또 정상적으로 나옴
당연하지 함수 하나 호출 끝나고 스택에서 없어지고 다시 호출하는데 결과에 간섭이 어떻게 되겠음....
근데 파이썬에서는 왜 이런지 제발 알려줄사람...
(IP보기클릭)106.102.***.***
(IP보기클릭)221.145.***.***
ㅠㅠ | 22.10.10 01:10 | | |
(IP보기클릭)14.38.***.***
(IP보기클릭)221.145.***.***
🍔햄버거
그런 거 같기는 한데 대체 어떤 원리로 그러는지 모르겠음... | 22.10.10 01:11 | | |
(IP보기클릭)14.38.***.***
문키퍼
그러게 본문에 내용 있었네 | 22.10.10 01:12 | | |
(IP보기클릭)14.38.***.***
문키퍼
memo 때문인가 | 22.10.10 01:19 | | |
(IP보기클릭)14.38.***.***
🍔햄버거
https://velog.io/@iandr0805/python-default-parameter | 22.10.10 01:26 | | |
(IP보기클릭)14.38.***.***
🍔햄버거
def bestSum( targetSum:int, numbers:list[int], memo:dict[int, list[int]] = None ) -> list[int]: if memo is None: memo = {} if targetSum in memo: return memo[targetSum] if targetSum == 0: return [] if targetSum < 0: return None bestComb = None for n in numbers: remainder = targetSum - n res = bestSum(remainder, numbers, memo) if res is not None: comb = [*res, n] if bestComb is None or len(bestComb) > len(comb): bestComb = comb memo[targetSum] = bestComb return bestComb print(bestSum(100, [1, 2, 5, 25])) print(bestSum(300, [10, 30])) | 22.10.10 01:27 | | |
(IP보기클릭)14.38.***.***
🍔햄버거
파이썬에서 함수 인자값 초기화 할 때 조심해야하나봐 | 22.10.10 01:28 | | |
(IP보기클릭)221.145.***.***
🍔햄버거
나도 방금 찾았음... 딴 언어에서 넘어오느라고 기본값에 mutable 넣을 때 패턴 써야하는 걸 몰랐네 암튼 시간 내줘서 감사 | 22.10.10 01:28 | | |
(IP보기클릭)14.38.***.***
문키퍼
그냥 memo를 내부에서 초기화 하지 말고 밖에서 인자로 받게 하는게 나을 듯 print(bestSum(100, [1, 2, 5, 25], {})) 이런식으로 | 22.10.10 01:30 | | |
(IP보기클릭)221.145.***.***
🍔햄버거
보통 알고리즘 문제에서 함수 만들 때 함수 인수 형태 제한 있어서 그러기는 힘들지 않을까? 이번 기회에 그냥 함수 기본값으로 mutable 안 넣는 거 머릿속에 박아놔야지 | 22.10.10 01:34 | | |
(IP보기클릭)14.38.***.***
문키퍼
하긴 언어 특성 기억할려면 그게 더 낫겠다... 알고리즘 사이트용이면 시작용 함수를 따로 빼도 될 것 같긴 한데 | 22.10.10 01:37 | | |