Где в моем коде возникают повторы?
Я собираюсь немного изменить ваш код: он будет возвращать результаты, а не печатать их; он переставит свои аргументы так, что target_array
не нужно будет передавать; он будет использовать еще более простой пример ввода с дубликатами:
def subset_sum(array, target_sum, start=0, target_array=[]): # dangerous default value
solutions = []
for idx in range(start, len(array)):
target_array.append(array[idx])
if sum(target_array) == target_sum:
solutions.append(list(target_array))
target_array.pop()
solutions.extend(subset_sum(array, target_sum, start + 1))
break
solutions.extend(subset_sum(array, target_sum, idx + 1))
target_array.pop()
return solutions
print(*subset_sum([1, 2, 3], 4))
Но у него все та же проблема с дублированием:
> python3 test.py
[1, 3] [1, 3]
>
Теперь я добавлю оператор отладочной печати:
target_array.pop()
print(f"print(*subset_sum({array}, {target_sum}, {start}, {target_array}))")
solutions.extend(subset_sum(array, target_sum, start + 1))
Теперь, когда мы запустим его, мы получим:
> python3 test.py
print(*subset_sum([1, 2, 3], 4, 1, [1]))
print(*subset_sum([1, 2, 3], 4, 2, [1]))
[1, 3] [1, 3]
>
Мы можем подтвердить, заменив наш первоначальный вызов двумя вышеприведенными, что оба они производят одинаковый результат. Проведя небольшое исследование на основе print
, мы можем определить, что первое является результатом рекурсивного вызова внутреннего цикла, а второе — результатом рекурсивного вызова внешнего цикла. В вызове нет дублирования (аргументы), но два разных вызова дают одинаковый результат.
Вы можете рвать на себе волосы, пытаясь это исправить, или просто заменить solutions
на set
вместо list
и позволить Python отфильтровать дубликаты в исходном примере вызова:
def subset_sum(array, target_sum, start=0, target_array=[]): # dangerous default value
solutions = set()
for idx in range(start, len(array)):
target_array.append(array[idx])
if sum(target_array) == target_sum:
solutions.add(tuple(target_array))
target_array.pop()
solutions |= subset_sum(array, target_sum, start + 1)
break
solutions |= subset_sum(array, target_sum, idx + 1)
target_array.pop()
return solutions
print(*subset_sum([1, 2, 3, 4], 4))
С выходом:
> python3 test.py
(1, 3) (4,)
>
person
cdlane
schedule
13.06.2019