函数与递归
"""
1. 求{an}的前n项和数列{bn}.
an = n **2
2. ⼆分查找法.
首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,
如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,
如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。
重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
"""
import numpy as np
n_max = 20
an_0 = [i **2 for i in range(n_max)]
def get_sum_an(n, *args):
an = args[0]
if n == 0:
return an[0]
else:
return an[n] + get_sum_an(n-1, *args)
def binary_search(target, *args, c=0):
arg = args[0]
arg.sort() # 排序的时候明明也遍历过了吧
label = len(arg) // 2
if target == arg[label]:
print(f'{arg},{label}')
print('Eureka!')
else:
print(f'{arg},{label}')
print(f'{arg[label]}!={target}')
if label != 0:
if target < arg[label]:
binary_search(target, arg[:label])
if target > arg[label]:
binary_search(target, arg[label:])
bn_0 = [get_sum_an(i, an_0) for i in range(n_max)]
print("an =", an_0)
print("bn =", bn_0)
cn = np.random.randint(0,100,20).tolist()
print("cn =", cn)
binary_search(22, cn)
C:\Users\user\AppData\Local\Programs\Python\Python38\python.exe C:/Users/user/AppData/Roaming/JetBrains/PyCharmCE2020.3/scratches/scratch.py
an = [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361]
bn = [0, 1, 5, 14, 30, 55, 91, 140, 204, 285, 385, 506, 650, 819, 1015, 1240, 1496, 1785, 2109, 2470]
cn = [91, 35, 52, 14, 91, 19, 16, 22, 86, 59, 59, 40, 81, 78, 77, 63, 2, 33, 28, 43]
[2, 14, 16, 19, 22, 28, 33, 35, 40, 43, 52, 59, 59, 63, 77, 78, 81, 86, 91, 91],10
52!=22
[2, 14, 16, 19, 22, 28, 33, 35, 40, 43],5
28!=22
[2, 14, 16, 19, 22],2
16!=22
[16, 19, 22],1
19!=22
[19, 22],1
Eureka!
进程已结束,退出代码0
遇到的问题:
- 1 思路不连贯
get_sum_an() 函数第一次实现时本来只考虑了题给{an}的情况,但是写完后突然想对任意的{an}都能实现求部分和序列{bn},于是多设置了一个参数。
然后,实现递归时调用自身的函数没有做相应的更新,编译器报错还不字字对译,先入为主地认为是函数传参出了问题,浪费了数小时的时间。
也不算没有收获,比如借此了解了*args,**kawgs的用法(虽然这次的实例用起来使代码更复杂了),但总的来说得不偿失。 - 2 对编程语言的区间定义“左闭右开”理解不够深刻
主要体现在
binary_search(target, arg[:label])
和
binary_search(target, arg[label:])
两句arg列表的切片上,一开始我会倾向于使用[label +1:] 或 [:label-1],仿佛少判断一个元素就能节约很多资源。然而这样不能节约资源的同时,还会引发bug。
但同时练习了try: … except: … 找逻辑bug的方法。也算有所收获。