简体   繁体   中英

Understanding recursive canSum function

I have a function, which, given a number and a list of numbers returns if the number can be made out of the numbers in a list, where numbers can be used as many times as needed:

def canSum(target_sum, numbers, memo = {}):
    if target_sum in memo:
        return memo[target_sum]
    if target_sum == 0:
        return True
    if target_sum < 0:
        return False

    for n in numbers:
        remainder = target_sum - n
        if canSum(remainder, numbers) == True:
            memo[target_sum] = True
            return True, memo

    memo[target_sum] = False
    return False,memo

It should return True and False depending if the target_sum can be made by adding any numbers any amount of time in the numbers list.

For example canSum(4, [2]) should return True because 2+2 is 4 and so on. However I can't understand where is my mistake, all of the below should return True .

canSum(4,[2])
# (False, {2: True, 4: False})

canSum(4,[2,1])
# (False, {2: True, 1: True, 3: True, 4: False})

canSum(4,[1,2])
# (True, {1: True, 2: True, 3: True, 4: True})

canSum(10,[2])
# (False, {2: True, 4: False, 6: False, 8: False, 10: False})

canSum(10,[2,3])
# (False, {2: True, 1: False, 4: False, 3: True, 6: False, 5: True, 8: False, 7: True, 10: False})

Also, is there a difference or a need to pass memo to the recursive function call? Which does not seem to make any difference.

 if canSum(remainder, numbers) == True: # -> if canSum(remainder, numbers, memo) == True:
    memo[target_sum] = True
    return True, memo

Consider when you call canSum(0, [2]) , the function will be return literal True . and if canSum(0, [2]) == True condition's will be satisfy. but when you call canSum(2, [2]) , the function will be return a tuple of (True, {2: True}) and if canSum(2, [2]) == True condition's won't be satisfy. So when you call canSum(4, [2]) , the function will return (False, {2: True, 4: False}) .

You have to return in same format for every calls. I think this will be work.

def canSum(target_sum, numbers, memo={}):
    if target_sum in memo:
        return memo[target_sum], memo
    if target_sum == 0:
        return True, memo
    if target_sum < 0:
        return False, memo

    for n in numbers:
        remainder = target_sum - n
        if canSum(remainder, numbers)[0]:
            memo[target_sum] = True
            return True, memo

    memo[target_sum] = False
    return False, memo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM