不知道是不是翻译故意弄的,信仰之跃这个名词确实挺好玩的,主要是想说清楚递归我们应该怎么思考。确实如果我们纠结于每一次递归的调用的话,很快你的大脑就会爆炸。
简单又聪明的处理方法就是,信仰之跃。当作f(n-1)是对的,怎么推出f(n),然后有终止条件就好了。
其实活生生就是归纳法,数学里那个。
贴一下查一个斐波那契数列的代码
1 def fibonacci(n): 2 if n == 0 : 3 return 0 4 elif n == 1: 5 return 1 6 else: 7 return fibonacci(n-1) + fibonacci(n-2)
自己想拓展一下,根据这个函数,弄一个斐波那契生成器,想了想好像不知道怎么写,先写yige列表的
1 def fibonacci(n): 2 if n == 0 : 3 return 0 4 elif n == 1: 5 return 1 6 else: 7 return fibonacci(n-1) + fibonacci(n-2) 8 9 10 def fibonacciList(n): 11 list = [] 12 for i in range(n): 13 list.append(fibonacci(i)) 14 return list 15 16 17 for num in fibonacciList(10): 18 print(num)
再改一下生成器版本,竟然成功了...
1 def fibonacci(n): 2 if n == 0 : 3 return 0 4 elif n == 1: 5 return 1 6 else: 7 return fibonacci(n-1) + fibonacci(n-2) 8 9 10 def fibonacciList(n): 11 # list = [] 12 for i in range(n): 13 yield fibonacci(i) 14 # return list 15 16 17 for num in fibonacciList(10): 18 print(num)
到练习,第一个虽然不难,但还是纪念一下,一次搞清楚输出,算是进步了
1 def b(z): 2 prod = a(z,z) 3 print(z,prod) 4 return prod 5 6 def a(x, y): 7 x = x + 1 8 return x*y 9 10 def c(x,y,z): 11 total=x+y+z 12 square = b(total)**2 13 return square 14 15 x = 1 16 y=x+1 17 print(c(x,y+3,x+y))
回文递归版,修正空字符报true的逻辑,但是感觉不够优雅,比较的东西不一样,也许容易埋坑
1 def first(word): 2 return word[0] 3 4 def last(word): 5 return word[-1] 6 7 def middle(word): 8 return word[1:-1] 9 10 11 def is_palindrome(word): 12 if word == '': 13 return False 14 elif len(word) == 0 or len(word) == 1: 15 return True 16 else: 17 if first(word) == last(word): 18 19 return is_palindrome(middle(word)) 20 else: 21 return False 22 23 24 print(is_palindrome('xy')) 25 print(is_palindrome('x')) 26 print(is_palindrome('')) 27 print(is_palindrome('xyz')) 28 print(is_palindrome('xyx'))
一个判断是否是幂函数的函数,用递归的思想来做简直太妙了
原则上其实就是让A不停的除以B,如果他能一直整除下去,那最后他俩就会相等,如果相等他们就是幂的关系,简直厉害了,纪念一下
1 def is_power(a, b): 2 if a == b: 3 return True 4 else: 5 if a % b == 0: 6 return is_power(a/b, b) 7 else: 8 return False
最后一个练习,辗转相除法,虽然我不知道逻辑,但按照指示写出来是很简单的
1 def gcd(a,b): 2 if b == 0: 3 return a 4 else: 5 return gcd(b, a%b)
但是这会导致一个巨大的问题,如果我gcd(3,0)也会产生3,其实这个是错误的,函数应该在一开始判断,a和b是否是0或负数,就报错,但后面如果变成0就可以不用报错了,这个其实就很像回文的情况,如果是空字符就应该报错。
现在这个问题还不知道怎么解决,暂时感觉无法解决,只能约束好这个调用者传正数了。
刚刚在洗澡的时候,突然想到一个办法,现在测试了几个数据,下面代码是可以解决上述问题的,有赖大神们指点。
1 def gcd(a,b): 2 if a == 0 or b == 0: 3 return 'zero' 4 elif a % b == 0: 5 return b 6 else: 7 return gcd(b, a%b)
下一章的练习就摘抄一下最后一个练习,刚开始的时候没有把循环每次都k+1,导致了死循环。
虽说不是很难,但看上去还是挺唬人的
1 import math 2 3 def fac(n): 4 if n == 0: 5 return 1 6 else: 7 return fac(n-1)*n 8 k = 0 9 zaxiang = 2 * math.sqrt(2) / 9801 10 sum = 0 11 12 while True: 13 num = (fac(4*k)*(1103+26390*k))/(pow(fac(k),4)*pow(396,4*k)) 14 sum = sum + num*zaxiang 15 if num < 1e-15: 16 break 17 k = k + 1 18 19 print(1/sum)
到字符串这一节了,刚刚竟然陷入危机了,想了大概10分钟才把这个程序跑对,十分丢脸啊,不知道是不是因为太晚了的缘故。
总之show code,不管多烂吧。
1 def find(word, letter, where): 2 index = where 3 while index < len(word): 4 if word[index] == letter: 5 return index 6 index += 1 7 return -1 8 9 def count(s, a): 10 count = 0 11 index = 0 12 13 while True: 14 index = find(s,a,index) 15 16 if index == -1: 17 break 18 count += 1 19 return count 20 21 print(count('ffffuck','f')) 22 print(find('fuck','u', 0)) 23 print(find('fuck','u', 3))
最关键的是循环每次都要修改查找的位置
书看到超过三分之一了,如果周末不加班的话,我能看完么?
晚安!