Сделайте заданное число путем добавления заданных чисел


Я создал код, который проверяет, является ли число может быть сделано путем добавления различных количеств заданных чисел и если это так возвращает количествах. Это лучший способ, чтобы сделать это, или есть более эффективный способ?

Вот моя функция:

def sumFinder(quantities, final_num):
    if len(quantities) == 1:
        for i in range(final_num//quantities[0]+1):
            num = quantities[0] * i
            if num == final_num:
                return [i]
        return False
    for i in range(final_num//quantities[0]+1):
        num = quantities[0]*i
        found_nums = sumFinder(quantities[1:], final_num-num)
        if found_nums:
            return [i] + found_nums
    return False

Это пример его работы:

for num in range(100):
    answer = sumFinder([4, 6, 9, 20], num)
    if answer:
        a, b, c, d = answer
        answer = "4({}) + 6({}) + 9({}) + 20({})".format(a, b, c, d)
    print(num, "=", answer)


Комментарии
1 ответ

Избежать повторяющихся значений

При тестировании кода, значения 4, 6, 9, 20 появляются в разных местах. Вы могли бы переписать свой код для генерации форматированного ответ из списка:

num_list = [4, 6, 9, 20]
for num in range(100):
answer = sumFinder(num_list, num)
if answer:
answer = " + ".join("{} * {}".format(a, b) for a, b in zip(num_list, answer))
print(num, "=", answer)

Документ функции и использовать правильный тип

Ваша функция возвращает обоих списках и логическое. Может быть, это будет понятнее, чтобы сделать его вернуть списке (если список нашел) и None в противном случае. Это может быть соответствующим образом задокументированы в строкой документации.

def sumFinder(quantities, final_num):
"""Return a list such that dot-product(list, quantities) == final_num. Return None when no list is found."""
if len(quantities) == 1:
for i in range(final_num//quantities[0]+1):
num = quantities[0] * i
if num == final_num:
return [i]
return None
for i in range(final_num//quantities[0]+1):
num = quantities[0]*i
found_nums = sumFinder(quantities[1:], final_num-num)
if found_nums:
return [i] + found_nums
return None

Ручка пустой ввод

Вы получаете доступ к первому элементу ввода, не проверив длину. Возможно, это будет понятнее документ это как недопустимое входное или вы могли бы справиться с этим должным образом, возвращая [] if final_sum == 0 else None.

Устранения дублирования логики

Когда пустое это дело обрабатывается, в случае с 1 элемента не должны быть обработаны специальным образом.

С несколькими незначительными изменениями, вы можете написать:

def sumFinder(quantities, final_num):
"""Return a list such that dot-product(list, quantities) == final_num. Return None when no list is found."""
if not quantities:
return [] if final_num == 0 else None
first, remain = quantities[0], quantities[1:]
for i in range(final_num//first+1):
found_nums = sumFinder(remain, final_num - first * i)
if found_nums is not None:
return [i] + found_nums
return None

Имена

Питон имена обычно snake_cased. Кроме того, find_sum было бы лучше имя sum_finder что звучит как имя класса.

final_num можно было бы переименовать target, nи т. д.

quantities можно было бы переименовать lst

2
ответ дан 12 февраля 2018 в 01:02 Источник Поделиться