递归是指函数调用自身时,有一些(非正式的)规则在编写这些规则时总是会被记住:
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
。
- 如果
0
是len(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)
以适合我们的目的。但是,您首先要看的是,如果我们在堆栈中仅更改其中一个变量,将会发生什么情况。
- 保持
nums
不变,修改x
:我们知道基本情况可以确保nums
保持正向和负向都在x
的长度范围内,很好但是,每次函数由原始 x
或nums
运行时,我们必须递增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
。这不是布宜诺斯艾利斯。练习递归的次数越多,这个概念就会越直观,它就会注意到更改某些输入可能不是最佳方法。您应该考虑:“当函数继续向下堆栈时,该值是什么?”
- 保留
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)
的函数。我们从上面的代码中有了一个总体思路,从上一点我们知道,我们将不得不不同地处理x
和nums
。因此,让我们写点东西:
-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