Python实现的一些常见简单问题(持续更新)
提纲:
1.汉诺塔
2.找到某个范围内的所有质数
3.杨辉三角
4.用闭包实现一个计数器,调用一次计数器加1
5.将类构造成可迭代对象,实现斐波那契数列
......
1.汉诺塔(汉诺塔)
用递归函数实现汉诺塔(A、B、C柱,要将圆盘从A柱移到C柱,且排列顺序不变)
思想:不管A柱有多少个圆盘(假设n个),我们可以将看成将上面的(n-1)个圆盘看成一个整体,那么问题就变得非常简单:
1)将上面的(n-1)个圆盘实现从A柱全部移动到B柱
2)把最后一个圆盘从A柱移到C柱
3)将刚刚移到B柱的(n-1)个圆盘从B柱全部移动到C柱。
这就是整个的过程,那么我们可以看到,上述1)和3)其实也是一次汉诺塔的完整过程,只不过是圆盘数目不同。因此,这里利用递归函数就能快速简单地解决问题。
代码如下;
def move(n,a,b,c): ''' n:圆盘数 a,b,c分别代表三个柱子 ''' if n == 1: print(a, '-->', c) else: move(n-1,a,c,b) print(a, '-->', c) move(n-1,b,a,c) if __name__ == '__main__': move(3,'A','B','C') # 输出: # A --> C # A --> B # C --> B # A --> C # B --> A # B --> C # A --> C
2.找到某个范围内的所有质数(质数)
有的语言中实现质数需要用到循环,对于每一个数去判断是不是质数。然而,质数是一个无限的序列,当判断的范围非常大的时候,程序运行占用内存较大。在Python中生成器可以按照某种计算规则推算出列表的后续元素不需要建立一个完整的列表,是一种一边循环一边计算的机制能节省内存。
用生成器找到某个范围内的所有质数:
#构造一个从3开始的奇数序列: def _odd_iter(): n = 1 while True: n = n + 2 yield n #筛选函数,返回的是True/False,这里x是从it中依次取所有元素 def _not_divisible(n): return lambda x: x % n > 0 #定义一个生成器,不断返回下一个素数 def primes(): yield 2 it = _odd_iter()#初始序列 while True: n = next(it) yield n it = list(filter(_not_divisible, it))#把it中不满足要求的元素filter掉,注意_not_divisible函数会将it中的每一个元素作为参数进行判断 #因为primes也是生成器,即一个无限序列,因此调用时要设置一个退出循环的条件 # 打印100以内的素数: for n in primes(): if n < 100: print(n) else: break
3.杨辉三角(杨辉三角)
#用生成器实现输出杨辉三角 def triangles(): lis = [1] i = 0 while i < 10: yield lis lis = iter(lis) i += 1 def iter(list): # 上一次迭代的list i = 1 next_list = [1] while i < len(list): next_list.append(list[i-1] + list[i]) i += 1 next_list.append(1) return next_list n = 0 results = [] for t in triangles(): print(t) results.append(t) n = n + 1 if n == 10: break if results == [ [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], [1, 7, 21, 35, 35, 21, 7, 1], [1, 8, 28, 56, 70, 56, 28, 8, 1], [1, 9, 36, 84, 126, 126, 84, 36, 9, 1] ]: print('测试通过!') else: print('测试失败!')
4.用闭包实现一个计数器,调用一次计数器加1
#用闭包实现一个计数器,调用一次计数器加1 def counter(): cnt = 1 def c(): nonlocal cnt x = cnt cnt += 1 return x return c counter1 = counter() print(counter1())#1 print(counter1())#2 print(counter1())#3 print(counter1())#4 print(counter1())#5
5.将类构造成可迭代对象,实现斐波那契数列
#迭代器协议:对象必须提供__next__方法 #用__iter__来实现迭代器协议的对象 #要使一个类成为可迭代对象,就要定义这两个方法 class Fib: def __init__(self): self._a = 1#起始的两个值 self._b = 1 def __iter__(self): return self def __next__(self): self._a, self._b = self._b, self._a + self._b return self._a f=Fib() print(next(f))#1 print(next(f))#2 print(next(f))#3 print(next(f))#5 print(next(f))#8 # print('==================================') # for i in f: # print(i)#这里会从8之后的13开始迭代,因此迭代器只能遍历一次