简体   繁体   English

Python 递归 function 参数问题

[英]Python recursion function parameters issue

I'm calling a function inside itself many times to solve the subset sum problem, using as it called, the recursion solution;我在内部多次调用 function 来解决子集和问题,使用所谓的递归解决方案; anyway, I can't figure out why n (which is the number of elements of the array) value is getting decreasing at first, until it reach 0, which is I get it, but then, after calling it again within itself, it makes n value incremented.无论如何,我无法弄清楚为什么 n (这是数组的元素数)值一开始会减少,直到它达到 0,这就是我明白了,但是,在它内部再次调用它之后,它使 n 值递增。 Why is that happening, as the whole function doesn't even have an increment contribution for the n value?为什么会发生这种情况,因为整个 function 甚至对 n 值都没有增量贡献? Where n gets its increasing value from? n 从哪里获得递增的值?

Here is the code:这是代码:

def printAllSubsetsRec(arr, n, currentSubset, sum):
    # If remaining sum is 0, then print all
    # elements of current subset.

    if (sum == 0):
        i = 0
        sumOfValue = 0
        for value in currentSubset:
            i += 1
            sumOfValue += value
            if (i == len(currentSubset)):
                print(value, " = ", sumOfValue)
            else:
                print(value, end=" + ")
        return True

    # If there are no elements in the array and the sum is not equal to 0.
    if (n == 0 and sum != 0):
        return None


    # I consider two cases for every element:
    # a) Excluding last element.
    # b) Including last element in current subset.
    # -------------------------------------------------

    # Excluding the last element:
    printAllSubsetsRec(arr, n - 1, currentSubset, sum)

    v = [] + currentSubset
    v.append(arr[n - 1])

    # Including the last element:
    printAllSubsetsRec(arr, n - 1, v, sum - arr[n - 1])


#Main:
arr = [10, 7, 5, 18, 12, 20, 15]
sum = 35
n = len(arr)
currentSubset = []
printAllSubsetsRec(arr, n, currentSubset, sum)

The output should be: output 应该是:

18 + 7 + 10 = 35 18 + 7 + 10 = 35

12 + 18 + 5 = 35 12 + 18 + 5 = 35

20 + 5 + 10 = 35 20 + 5 + 10 = 35

15 + 20 = 35 15 + 20 = 35

Thanks in advance!提前致谢!

Recursion is a functional heritage and so using it with functional style yields the best results.递归是一种函数式遗产,因此将其与函数式风格一起使用会产生最佳结果。 This means avoiding things like mutation, variable reassignment, and other side effects -这意味着要避免诸如突变、变量重新分配和其他副作用之类的事情——

  • logical if without a corresponding else逻辑if没有对应的else
  • mutation and reassignment of i and sumOfValue isumOfValue的突变和重新分配
  • side effects like print print等副作用

Recursion doesn't have to be difficult or painful.递归不一定是困难或痛苦的。 Using functional disciplines we can write subsets(t,n) with inductive reasoning -使用功能学科,我们可以用归纳推理编写subsets(t,n) -

  1. If the target sum n is zero, yield the empty solution如果目标和n为零,则产生空解
  2. (inductive) otherwise n is negative or positive. (归纳)否则n为负或正。 If n is negative or the input array t is empty, we are out-of-bounds.如果n为负数或输入数组t为空,则超出范围。 stop iteration.停止迭代。
  3. (inductive) n is positive and t has at least one element. (感性) n为正且t至少有一个元素。 For all s of the subproblem (t[1:],nt[0]) , prepend t[0] to s and yield.对于子问题(t[1:],nt[0])的所有s ,将t[0]添加到s并产生。 And yield all results of the subproblem (t[1:],n)产生子问题的所有结果(t[1:],n)
def subsets(t, n):
  if n == 0:
    yield ()                              #1
  elif n < 0 or not t:
    return                                #2
  else:
    for s in subsets(t[1:], n - t[0]):    #3
      yield (t[0], *s)
    yield from subsets(t[1:], n)
for s in subsets([10, 7, 5, 18, 12, 20, 15], 35):
  print(s)
(10, 7, 18)
(10, 5, 20)
(5, 18, 12)
(20, 15)

Notice -注意 -

  • All operations do not mutate or reassign variables所有操作都不会改变或重新分配变量
  • Side effects like print are traded for yield print等副作用以yield为代价
  • Caller is free to utilize and transform the results any way desired调用者可以随意使用和转换结果

To format the results as an mathematical expression -要将结果格式化为数学表达式 -

for s in subsets([10, 7, 5, 18, 12, 20, 15], 35):
  print(" + ".join(map(str, s)), "=", 35)
10 + 7 + 18 = 35
10 + 5 + 20 = 35
5 + 18 + 12 = 35
20 + 15 = 35

To collect all outputs of a generator into a list, use list -要将生成器的所有输出收集到列表中,请使用list -

print(list(subsets([10, 7, 5, 18, 12, 20, 15], 35)))
[(10, 7, 18), (10, 5, 20), (5, 18, 12), (20, 15)]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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