【译文】递归函数,2024年最新缓存架构技术

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Python全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img



既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Python知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024c (备注Python)
img

正文

如果 ñ 不是 自我。备忘录:

自我。备忘录[ n ] = 自我。__call__ ( n - 1 ) + self 。__call__ ( n - 2 )

返回 self 。备忘录[ n ]

# 我们创建一个可调用对象来创建斐波那契数列:

fib = FibonacciLike ()

# 这将创建一个可调用对象来创建 Lucas 数列:

lucas = FibonacciLike ( 2 , 1 )

对于 范围(1 , 16 ):

打印(我, FIB (我), 卢卡斯(我))

输出:

1 1 1

2 1 3

3 2 4

4 3 7

5 5 11

6 8 18

7 13 29

8 21 47

9 34 76

10 55 123

11 89 199

12 144 322

13 233 521

14 377 843

15 610 1364

卢卡斯数或卢卡斯级数是一个整数序列,以数学家弗朗索瓦·爱德华·阿纳托尔·卢卡斯 (1842-91) 的名字命名,他研究了该序列和密切相关的斐波那契数。卢卡斯数与斐波那契数有相同的创生法则,即前两个数之和,但0和1的取值不同。

广义斐波那契数列


现在我们将证明我们的方法也适用于计算任意广义斐波那契数列。斐波那契数列取决于前面的两个值。我们现在通过以下方式定义 k-Fib 序列来概括这个概念

给定一个固定的自然数kk >= 2。还给出了k初始值一世0,一世1,…一世克-1

满意 F克(0)=一世0,…F克(克-1)=一世克-1

该功能还需要 克 系数 C0,C1,…C克-1

F克(n) 被定义为

F克(n)=一个0⋅F克(n-1)+一个1⋅F克(n-2)…一个克-1⋅F克(n-克)

和 克<=n

kFibonacci****类

def __init__ ( self , k , initials , coefficients ):

self . memo = dict ( zip ( range ( k ), initials ))

self . coeffs = 系数

self 。k = k

def __call__ ( self , n ):

k = self 。ķ

如果 ñ 不是 自我。备忘录:

结果 = 0

系数_ , 我 拉链(自我。coeffs , 范围(1 , ķ + 1 )):

结果 + = 系数_ * 自我。__call__ ( n - i )

self. 备注[ n ] = 结果

返回 self 。备忘录[ n ]

fib = kFibonacci ( 2 , ( 0 , 1 ), ( 1 , 1 ))

lucas = kFibonacci ( 2 , ( 2 , 1 ), ( 1 , 1 ))

对于 范围(1 , 16 ):

打印(我, FIB (我), 卢卡斯(我))

输出:

1 1 1

2 1 3

3 2 4

4 3 7

5 5 11

6 8 18

7 13 29

8 21 47

9 34 76

10 55 123

11 89 199

12 144 322

13 233 521

14 377 843

15 610 1364

Pell 数字的序列以 1, 2, 5, 12, 29, …

功能是

磷(n)=2⋅磷(n-1)+磷(n-2) 和 磷(0)=1 和 磷(1)=1

用我们的kFibonacci类很容易制定这个序列:

P = kFibonacci ( 2 , ( 1 , 2 ), ( 2 , 1 ))

for i in range ( 10 ):

print ( i , P ( i ))

输出:

0 1

1 2

2 5

3 12

4 29

5 70

6 169

7 408

8 985

9 2378

我们可以通过在两个佩尔数 P(i) 和 P(i+1) 之间添加前两个佩尔数之和来创建另一个有趣的系列。我们得到:

磷(0),磷(1),磷(0)+磷(1),磷(2),磷(1)+磷(2),磷(3),磷(2)+磷(3),…

对应于: 1,2,3,5,7,12,17,29,…

def nP ( n ):

如果 n < 2 :

return P ( n )

else :

i = n // 2 + 1

if n % 2 : # n 是奇数

return P ( i )

else :

return P ( i - 1 ) + P ( i - 2 )

对于 范围(20 ):

打印(为nP (我), 结束= “” )

输出:

1, 2, 3, 5, 7, 12, 17, 29, 41, 70, 99, 169, 239, 408, 577, 985, 1393, 2378, 3363, 5741,

如果你仔细观察这些数字,你会发现在这个序列中还有另一个规则。我们可以将 nP 定义为

n磷(n)=2⋅n磷(n-2)+n磷(n-4) 和 n>3 和起始值 1,2,3,5

这是我们kFibonacci班级的另一个简单应用:

nP = kFibonacci ( 4 , ( 1 , 2 , 3 , 5 ), ( 0 , 2 , 0 , 1 ))

for i in range ( 20 ):

print ( nP ( i ), end = ", " )

输出:

1, 2, 3, 5, 7, 12, 17, 29, 41, 70, 99, 169, 239, 408, 577, 985, 1393, 2378, 3363, 5741,

一个有趣的数学事实:对于每个奇数 n 的商 磷(n) 经过 磷(n-1) 是一个近似值 2. 如果n是偶数,商是一个近似值1+12

sqrt2 = 2 ** 0.5

print ( "Square root of 2: " , sqrt2 )

print ( "Square root of 3: " , 1 + 1 / sqrt2 )

for i in range ( 1 , 20 ):

print ( nP ( i ) / nP ( i - 1 ), end = ", " )

输出:

2 的平方根:1.4142135623730951

3 的平方根:1.7071067811865475

2.0,1.5,1.6666666666666667,1.4,1.7142857142857142,1.4166666666666667,1.7058823529411764,1.4137931034482758,1.7073170731707317,1.4142857142857144,1.707070707070707,1.4142011834319526,1.707112970711297,1.4142156862745099,1.707105719237435,1.4142131979695431,1.7071069633883704,1.4142136248948696,1.7071067499256616,

更多关于 Python 中的递归


河内塔

如果您想了解更多关于递归的知识,我们建议您尝试解决以下练习。在你尽力而为之前,请不要盯着解决方案。如果您已经考虑了一段时间的任务,但仍然无法解决该练习,您可以参考我们的示例解决方案。

在我们教程的“高级主题”部分,我们对游戏或谜题“河内之塔”进行了全面的处理。当然,我们通过使用递归函数的函数来解决它。“河内问题”很特别,因为递归解决方案几乎将自己强加于程序员,而游戏的迭代解决方案很难找到和掌握。

练习

练习 1

想想函数 f(n) = 3 * n 的递归版本,即 3 的倍数

练习 2

编写一个递归 Python 函数,返回前 n 个整数的总和。(提示:该函数将类似于阶乘函数!)

练习 3

编写一个实现帕斯卡三角形的函数:

1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1

练习 4

斐波那契数列隐藏在帕斯卡三角形内。如果您将以下三角形的彩色数字相加,您将得到第 7 个斐波那契数:

1 1 1 1 2 1 1 3 3 **1** 1 4 **6** 4 1 1 **5** 10 10 5 1 **1** 6 15 20 15 6 1

使用帕斯卡三角形编写一个递归程序来计算斐波那契数列。

练习 5

在 Python 中为 Eratosthenes 的筛子实现递归函数。

Eratosthenes 筛法是一种简单的算法,用于查找指定整数以内的所有素数。它是由古希腊数学家埃拉托色尼创造的。求所有小于或等于给定整数n的素数的算法:

  1. 创建一个从 2 到 n 的整数列表:2, 3, 4, …, n

  2. 从我设置为 2 的计数器开始,即第一个质数

  3. 从 i+i 开始,按 i 递增并从列表中删除这些数字,即 2 i、3 i、4*i 等。

  4. 找出 i 后面的列表的第一个数字。这是下一个质数。

  5. 将 i 设置为在上一步中找到的数字

  6. 重复步骤 3 和 4,直到 i 大于 n。(作为改进:去n的平方根就够了)

  7. 所有仍在列表中的数字都是素数

你可以很容易地看到,如果我们严格使用这个算法,我们将是低效的,例如,我们将尝试去除 4 的倍数,尽管它们已经被 2 的倍数去除了。所以它足以产生所有的倍数直到 n 的平方根的素数。我们可以递归地创建这些集合。

练习 6

写一个递归函数fib_indexfib(),返回斐波那契数列中某个数的索引,如果该数是该数列的元素,则返回-1,如果不包含该数,即

F一世乙(F一世乙_一世nd电子X(n))==n

练习 7

两个连续斐波那契数的平方和也是斐波那契数,例如2和3是斐波那契数列的元素,2 2 + 3 3 = 13对应斐波那契(7)。 用前面的函数求位置斐波那契数列中两个连续数的平方和。

数学解释:设 a 和 b 是两个连续的斐波那契数,a 先于 b。以数字“a”开头的斐波那契数列如下所示:

0个

1个

2 a + b

3 a + 2b

4 2a + 3b

5 3a + 5b

6 5a + 8b

我们可以看到斐波那契数列作为 a 和 b 的因子出现。此序列中的第 n 个元素可以使用以下公式计算:

F(n)=F一世乙(n-1)⋅一个+F一世乙(n)⋅乙

由此我们可以得出结论,对于自然数 n,n>1,以下成立:

F一世乙(2⋅n+1)=F一世乙(n)2+F一世乙(n+1)2

练习 8

tribonacci号码是像斐波那契数,但不是与两个预定条件开始,该序列与三个预定术语开始的,每个术语之后是前述三项的总和。前几个 tribonacci 数是:

0, 0, 1, 1, 2, 4, 7, 13, 24, 44, 81, 149, 274, 504, 927, 1705, 3136, 5768, 10609, 19513, 356812, …

所述tetranacci号码与四个预定术语开始,每个术语之后是前述4项的总和。前几个四连数是:

0, 0, 0, 1, 1, 2, 4, 8, 15, 29, 56, 108, 208, 401, 773, 1490, 2872, 5536, 10671, 20569, 39648, …

对于pentanacci、hexanacci、heptanacci、octanacci 等,这以相同的方式继续。

为 tribonacci 和tetranacci 数编写函数。

练习 9:

如果有人想检查递归函数中的参数怎么办?例如阶乘函数。好的,请编写一个递归版本的 factorial 来检查参数。也许你以完美的方式做到了,但也许不是。你能改进你的版本吗?摆脱不必要的测试?

解决方案


练习 1 的解决方案

在数学上,我们可以这样写:

F(1)=3,

F(n+1)=F(n)+3

一个 Python 函数可以这样写:

def mult3 ( n ):

如果 n == 1 :

return 3

else :

return mult3 ( n - 1 ) + 3

对于 范围(1 ,10 ):

打印(mult3 (我))

输出:

3

6

9

12

15

18

21

24

27

练习 2 的解决方案

def sum_n ( n ):

if n == 0 :

return 0

else :

return n + sum_n ( n - 1 )

练习 3 的解决方案:生成帕斯卡三角形:

def pascal ( n ):

if n == 1 :

return [ 1 ]

else :

line = [ 1 ]

previous_line = pascal ( n - 1 )

for i in range ( len ( previous_line ) - 1 ):

line 。追加( previous_line [ i ] + previous_line [ i +1 ])

行 += [ 1 ]

返回

打印(帕斯卡(6 ))

输出:

[1, 5, 10, 10, 5, 1]

或者,我们可以使用列表推导编写一个函数:

def pascal ( n ):

if n == 1 :

return [ 1 ]

else :

p_line = pascal ( n - 1 )

line = [ p_line [ i ] + p_line [ i + 1 ] for i in range ( len ( p_line ) - 1 )]

行。插入( 0 ,1 )

线。追加( 1 )

返回

打印(帕斯卡(6 ))

输出:

[1, 5, 10, 10, 5, 1]

练习 4 的解答

从帕斯卡三角形中产生斐波那契数列:

def fib_pascal ( n , fib_pos ):

if n == 1 :

line = [ 1 ]

fib_sum = 1 if fib_pos == 0 else 0

else :

line = [ 1 ]

( previous_line , fib_sum ) = fib_pascal ( n - 1 , fib_pos + 1 )

用于 范围len个( previous_line ) - 1 ):

行。append ( previous_line [ i ] + previous_line [ i + 1 ])

line += [ 1 ]

if fib_pos < len ( line ):

fib_sum += line [ fib_pos ]

return ( line , fib_sum )

def fib ( n ):

返回 fib_pascal ( n , 0 )[ 1 ]

# 现在打印出前十个斐波那契数:

for i in range ( 1 , 10 ):

print ( fib ( i ))

输出:

1

1

2

3

5

8

13

21

34

练习 5 的解答

下面的程序按照任务的规则以迭代的方式实现了埃拉托色尼筛法。它将打印出前 100 个质数。

from math import sqrt

def screen ( n ):

# 返回 2 和 n 之间的所有素

数 = list ( range ( 2 , n + 1 ))

max = sqrt ( n )

num = 2

while num < max :

i = num

while i <= n :

i += num

if i in primes :

primes. 删除( i )

for j in primes :

if j > num :

num = j

break

return primes

打印(筛(100 ))

输出:

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 ]

但是我们教程的这一章是关于递归和递归函数的,我们需要一个递归函数来计算素数。要理解以下解决方案,您可以参考我们关于列表理解的章节:

数学 导入 sqrt

def primes ( n ):

if n == 0 :

return []

elif n == 1 :

return []

else :

p = primes ( int ( sqrt ( n )))

no_p = [ j for i in p for j in range ( i * 2 , n + 1 , i )]

p = [X X 范围(2 , Ñ + 1 ) 如果 X no_p ]

返回 p

打印(素数(100 ))

输出:

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 ]

练习 6 的解答

备忘录 = { 0 :0 , 1 :1 }

DEF FIB (Ñ ):

如果 Ñ 备忘录:

备忘录[ Ñ ] = FIB (ñ - 1 ) + FIB (ñ - 2 )

返回 备忘录[ Ñ ]

def fib_index ( * x ):

“”" 用 fib(i) == n “”" 查找自然数 i

if len ( x ) == 1 :

# 由用户开始

# 查找从 0

开始的__索引return fib_index ( x [ 0 ], 0 )

else :

n = fib ( x [ 1 ])

m = x [ 0 ]

如果 n > m :

return - 1

elif n == m :

return x [ 1 ]

else :

return fib_index ( m , x [ 1 ] + 1 )

# 上一示例中带有 fib() 和 find_index() 函数的代码

print ( " a | a | b | 平方和 | 索引" 的索引" )

print ( "============================== ========================” )

范围(15 ):

方形 = FIB (我)** 2 + FIB (我+ 1 )** 2

打印( f " { i : 12d } | { fib ( i ) : 6d } |{ fib ( i + 1 ) : 9d } | {正方形:14d } | { fib_index ( square ) : 5d } " )

输出:

索引 | 一个| 乙 | 平方和 | 指数

================================================== ===

0| 0| 1| 1| 1

1| 1| 1| 2| 3

2| 1| 2| 5| 5

3| 2| 3| 13| 7

4| 3| 5| 34| 9

5| 5| 8| 89| 11

6| 8| 13| 233| 13

7| 13| 21| 610| 15

8| 21| 34| 1597| 17

9| 34| 55| 4181| 19

10| 55| 89| 10946| 21

11| 89| 144| 28657| 23

12| 144| 233| 75025| 25

13| 233| 377| 196418| 27

14| 377| 610| 514229| 29

练习 8 的解答

我们将使用kFibonacci我们在本章中定义的类。

tribonacci = kFibonacci ( 3 , ( 0 , 0 , 1 ), ( 1 , 1 , 1 ))

对于 范围(20 ):

打印(tribonacci (我), 结束= “” )

输出:

0, 0, 1, 1, 2, 4, 7, 13, 24, 44, 81, 149, 274, 504, 927, 1705, 3136, 5768, 10609, 19513,

四面体 = kFibonacci ( 4 , ( 0 , 0 , 0 , 1 ), ( 1 , 1 , 1 , 1 ))

对于 范围(20 ):

打印(tetranacci (我), 结束= “” )

输出:

0, 0, 0, 1, 1, 2, 4, 8, 15, 29, 56, 108, 208, 401, 773, 1490, 2872, 5536, 10671, 20569,

我们可以像这样轻松地创建它们:

前缀 = [ ‘摩擦’ , ‘四’ , ‘的Pentra’ , ‘六’ , ‘庚’ , ‘八’ ]

ķ , 前缀 拉链范围len个(前缀)), 前缀):

CMD = 前缀 + “ nacci = kFibonacci("

cmd += str ( k + 3 ) + “, (” + "0, " * ( k + 2 ) + "1), "

cmd += “(” + "1, " * ( k + 2 ) + “1))”

打印( cmd )

exec ( cmd )

打印( " \n测试八角函数:" )

for i in range ( 20 ):

打印(八角( i ), end = ", " )

输出:

tribonacci = kFibonacci(3, (0, 0, 1), (1, 1, 1))

四面体 = kFibonacci(4, (0, 0, 0, 1), (1, 1, 1, 1))

pentranacci = kFibonacci(5,​​ (0, 0, 0, 0, 1), (1, 1, 1, 1, 1))

六面体 = kFibonacci(6, (0, 0, 0, 0, 0, 1), (1, 1, 1, 1, 1, 1))

heptanacci = kFibonacci(7, (0, 0, 0, 0, 0, 0, 1), (1, 1, 1, 1, 1, 1, 1))

Octanacci = kFibonacci(8, (0, 0, 0, 0, 0, 0, 0, 1), (1, 1, 1, 1, 1, 1, 1, 1))

测试八角函数:

0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 4, 8, 16, 32, 64, 128, 255, 509, 1016, 2028,

练习 9 的解答

最后

Python崛起并且风靡,因为优点多、应用领域广、被大牛们认可。学习 Python 门槛很低,但它的晋级路线很多,通过它你能进入机器学习、数据挖掘、大数据,CS等更加高级的领域。Python可以做网络应用,可以做科学计算,数据分析,可以做网络爬虫,可以做机器学习、自然语言处理、可以写游戏、可以做桌面应用…Python可以做的很多,你需要学好基础,再选择明确的方向。这里给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

👉Python所有方向的学习路线👈

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

👉Python必备开发工具👈

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

👉Python全套学习视频👈

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

👉实战案例👈

学python就与学数学一样,是不能只看书不做题的,直接看步骤和答案会让人误以为自己全都掌握了,但是碰到生题的时候还是会一筹莫展。

因此在学习python的过程中一定要记得多动手写代码,教程只需要看一两遍即可。

👉大厂面试真题👈

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注python)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
用,可以做科学计算,数据分析,可以做网络爬虫,可以做机器学习、自然语言处理、可以写游戏、可以做桌面应用…Python可以做的很多,你需要学好基础,再选择明确的方向。这里给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

👉Python所有方向的学习路线👈

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

👉Python必备开发工具👈

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

👉Python全套学习视频👈

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

👉实战案例👈

学python就与学数学一样,是不能只看书不做题的,直接看步骤和答案会让人误以为自己全都掌握了,但是碰到生题的时候还是会一筹莫展。

因此在学习python的过程中一定要记得多动手写代码,教程只需要看一两遍即可。

👉大厂面试真题👈

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注python)
[外链图片转存中…(img-ACN7d2Ik-1713220375924)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值