如何重写程序以使用递归?

刚刚开始处理递归-我还不了解其中的所有内容。我认为我没有使用基本条件,但我不知道如何编写它。该程序本身可以工作并执行我需要的一切,但是没有递归。

该程序的想法是有一个列表,需要在列表中将列表中每个第x个数字相加-x作为步骤。如果x = 0,则总和自动为零。如果x超出范围,则总和也为0

def sum_elements(nums,x) -> int::
    if x not in range(-len(nums),len(nums)) or x == 0:
        return 0
    if x > 0:
        nums = nums[x - 1::x]
        return sum(nums)
    return sum_elements(nums[::-1],-x)

if __name__ == '__main__':
    print(sum_elements([],0))  # x = 0 -> 0
    print(sum_elements([1,5,2,9,5],3))  # 2 + 5 = 7
    print(sum_elements([5,6,10,20],-2))  # 10 + 5 = 15
    print(sum_elements([5,-20))  # x = -20 -> 0
zhanghaostar 回答:如何重写程序以使用递归?

递归是指函数调用自身时,有一些(非正式的)规则在编写这些规则时总是会被记住:

1。基本情况。

每个递归函数必须具有一个基本情况,该基本情况实际上是recursive call中堆栈的结尾。

2。每个递归函数都遵守non-base(s)base case

换句话说,您的代码必须以该函数自行调用或终止递归调用的方式编写。您可以通过执行if else语句来做到这一点,或者只编写if语句来捕获基本情况。

3。该功能的输入应牢记前一个功能的状态。

在数学中,您可能还记得自己调用的函数(为解释起见,语法已切换):

f(x)_(n=0) = f(x)_(n=1) + 10

变为:

f(x)_(n=0) = ( f(x)_(n=2) + 10 ) + 10

,依此类推。本质上,您是使用代码编写的,并设置了一个基本情况,该情况可能会说(例如,在上面的示例中)“ n为10时停止”。如果是这种情况,那么当我们深入该功能并f(x)_(n=10)出现(并说返回0 + 10)时,您应该注意到级联效果,我们将如何最终形成{ {1}}。

因此,对于此功能,您有两个输入f(x)_(n=0) = 0 + 10 + 10 + 10 + ...nums。这些输入是我们在递归堆栈中进行的修改。


1。编写基本案例。

写基本情况通常是编写递归函数最简单的部分。我们知道,对于您的问题,必须抓以下情况:

  • 如果x不在x的长度范围内,那么我们必须返回nums
  • 如果0len(nums),那么我们应该返回0

所以让我们开始吧

0

但是,请注意,def sum_elements(nums,x) -> int: if len(nums) == 0 or not x in range(-len(nums),len(nums)): return 0 将返回range(len([1,2])),而range(0,2)将返回list(range(0,2))。因此,我们必须确保在[0,1]上添加1,以便我们能真正看到len(nums)是否在适当的范围内:

x

请注意,def sum_elements(nums,len(nums) + 1): return 0 等于range(-len(nums),len(nums) + 1)nums = [1,2,3]等于range(-3,4)。因此,我们不需要list(range(-3,4))[-3,-2,-1,1,3]

弄清楚基本情况之后,就可以开始实际的功能了。至此,我们已经完成了#1 和部分#2 ,但是现在我们必须编写-len(nums) + 1例。

2。标识我们的-len(nums) - 1

#2 编写,函数输入随着函数堆栈的下降而动态变化。因此,我们需要考虑如何修改non-base(s)和/或other-case(s)以适合我们的目的。但是,您首先要看的是,如果我们在堆栈中仅更改其中一个变量,将会发生什么情况。

  1. 保持nums不变,修改x:我们知道基本情况可以确保nums保持正向和负向都在x的长度范围内,很好但是,每次函数由原始 xnums运行时,我们必须递增x。如果我们创建函数并在每次调用时说出x,则不是在其自身添加原始的x_0,而是在其自身添加了较新的x + x。这是个问题。以以下示例为例:
x

注意我们如何获得:

x

以及第三次调用的def sum_elements(nums,x) -> int: print(nums,x) # Base case. if len(nums) == 0 or not x in range(-len(nums),len(nums) + 1): return 0 # Other case. We must differentiate between positive x,and negative x. if x > 0: # Since x is an index that starts at 1,not 0,we must do x-1. number = nums[x - 1] else: # For negative values of x this does not apply. [1,2][-2] = 1 number = nums[x] return number + sum_elements(nums,x + x) 值如何为# [NUMS] x [1,3,4,5,6] 2 [1,6] 4 [1,6] 8 # OUTPUT 6 。这不是布宜诺斯艾利斯。练习递归的次数越多,这个概念就会越直观,它就会注意到更改某些输入可能不是最佳方法。您应该考虑:“当函数继续向下堆栈时,该值是什么?”

  1. 保留x常量,修改8:如果这样做,我们应该确定我们不会遇到x值的问题。于是,问题就变成了我们如何修改nums列表并使用x来获得优势。我们确实知道,nums在技术上可以用作索引,如上所述。因此,如果不修改索引,而是修改该索引所来自的列表,该怎么办?以以下示例为例:
x

因此,似乎我们可以修改列表并保持常量x来检索所需的信息。太棒了!在这种情况下,第二种方法是可行的。

3。编写我们的nums = [1,4] x = 2 print(nums) # > [1,4] print(nums[x - 1]) # > 2 nums = nums[x:] # > [3,4] print(nums[x - 1]) # > 4

因此,现在我们将尝试编写一个使x不变,但修改other-case(s)的函数。我们从上面的代码中有了一个总体思路,从上一点我们知道,我们将不得不不同地处理xnums。因此,让我们写点东西:

-x

如果我们测试上面的函数,它似乎适用于任何正数x,但不适用于负数def sum_elements2(nums,x) -> int: # Base case. if len(nums) == 0 or not x in range(-len(nums),len(nums) + 1): return 0 # Other case. if x >= 0: number = nums[x - 1] nums = nums[x:] else: number = nums[x] # Not sure what goes here. return number + sum_elements(nums,x) 。但是,有意义的是,无论我们对积极方面采取什么行动,我们都必须对消极方面采取相反的行动。如果我们尝试使用x,我们很快就会意识到它是有效的。我们的最终功能变为:

x

运行示例

如果使用上述功能运行示例,则会得到:

nums = nums[:x]
,

也许这种方法可以帮助您理解。

它从第一个元素开始,其余每个x个元素相加。

这是我的假设,因为您没有提供输入及其所需的输出作为示例。

如果您需要从第x个元素开始,则可以轻松修改代码,我让您尝试一下。

def sum_elements(nums,x) -> int:
    if x>0 and x<=len(nums):
        return nums[0] + sum_elements(nums[x:],x)
    return 0

lst = [1,6]
print(sum_elements(lst,2))
print(sum_elements(lst,3))
print(sum_elements(lst,0))

产生

9
5
0

注意:它仅演示了递归,但由于多种原因,它并不是最佳选择。

它也会丢弃x的负值

本文链接:https://www.f2er.com/3161927.html

大家都在问