问题
I'm asked to write a recursive function in python:
def exact_change( target_amount, L ):
where the input target_amount is a single non-negative integer value and the input L is a list of positive integer values. Then, exact_change should return either True or False: it should return True if it’s possible to create target_amount by adding up some-or-all of the values in L. It should return False if it’s not possible to create target_amount by adding up some-or-all of the values in L.
For example, L could represent the coins you have in your pocket and target_amount could represent the price of an item – in this case, exact_change would tell you whether or not you can pay for the item exactly.
exact_change( 42, [25, 1, 25, 10, 5, 1] )
True
exact_change( 42, [25, 1, 25, 10, 5] )
False
I've looked up some of the 'change-making problem' solutions, but I can't really figure out how to program this function.
Can anybody help me?
回答1:
By sorting L in reverse we try to use up the biggest coins first. This should take care about situations mentioned by @MathiasEttinger. For sure re-sorting the already sorted L at each recursive call is redundant, but sorting has to happen somewhere (it would be nice if it could happen before the first call to exact_change).
from copy import copy
def exact_change(target_amount, L):
L = sorted(L, reverse=True)
for v in L:
if v == target_amount:
return True
else:
if v < target_amount:
L.remove(v)
return exact_change(target_amount-v, L)
else:
return False
print exact_change( 42, [25, 1, 25, 10, 5, 1] )
print exact_change( 42, [25, 1, 25, 10, 5] )
回答2:
The simplest form of having exact change is when the target_amount is included in the list of coins. One way to recursively reduce the problem to that situation is to iterate over the list of coins, and for each one, subtract it from the target_amount, remove it from the available list of coins, and check if the new target amount can be reached by the new list of coins (recursively):
def exact_change(target_amount, coins):
list_len = len(coins)
if list_len == 0:
return False
if target_amount in coins:
return True
for i in range(0, list_len):
reduced = coins[0:i] + coins[i+1:]
if exact_change(target_amount - coins[i], reduced):
return True
return False
回答3:
You could use something like itertools.combinations
from itertools import combinations
def exact_match(number, l):
le = len(l)
for i in xrange(1, le + 1):
combs = list(combinations(l, i))
for comb in combs:
if sum(comb) == number:
return True
return False
来源:https://stackoverflow.com/questions/32883885/exact-change-in-python-via-recursion