参考:Python 实现递归算法 - 另一个自己 - CSDN博客
用递归实现以下算法:
- Factorial
- Hannoi Tower
- Fibonacci
- 迷宫
使用递归计算组合(permutation)
- 对于一个元素的集合,直接返回值即可
- 对于多个元素的集合
- 遍历所有元素
- 对于任意一个元素与其他元素合并
代码如下:
利用 set 可以进行简单的 + - 操作
返回结果为 迭代器,也是可以遍历的
def naive_recursive_permute(S):
if len(S) <= 1:
yield list(S)
else:
for x in S:
for P in naive_recursive_permute(S - {x}):
yield [x] + P
list(naive_recursive_permute({0}))
list(naive_recursive_permute({0, 1}))
list(naive_recursive_permute({0, 1, 2}))
list(naive_recursive_permute({0, 1, 2, 3}))
output:
[[0]]
Out[2]:
[[0, 1], [1, 0]]
Out[2]:
[[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]]
Out[2]:
[[0, 1, 2, 3],
[0, 1, 3, 2],
[0, 2, 1, 3],
[0, 2, 3, 1],
[0, 3, 1, 2],
[0, 3, 2, 1],
[1, 0, 2, 3],
[1, 0, 3, 2],
[1, 2, 0, 3],
[1, 2, 3, 0],
[1, 3, 0, 2],
[1, 3, 2, 0],
[2, 0, 1, 3],
[2, 0, 3, 1],
[2, 1, 0, 3],
[2, 1, 3, 0],
[2, 3, 0, 1],
[2, 3, 1, 0],
[3, 0, 1, 2],
[3, 0, 2, 1],
[3, 1, 0, 2],
[3, 1, 2, 0],
[3, 2, 0, 1],
[3, 2, 1, 0]]
可以填写选择几个数字的排列
函数名字是组合
def combination(m_list, nb):
if nb == 1:
for m in m_list:
yield [m]
else:
for k in range(len(m_list)):
for i in combination(m_list[0:k]+m_list[k+1:], nb-1):
yield [m_list[k]] + i
list(combination([1, 2, 3, 4], 1))
list(combination([1, 2, 3, 4], 2))
list(combination([1, 2, 3, 4], 3))
list(combination([1, 2, 3, 4], 4))
output:
[[1], [2], [3], [4]]
Out[52]:
[[1, 2],
[1, 3],
[1, 4],
[2, 1],
[2, 3],
[2, 4],
[3, 1],
[3, 2],
[3, 4],
[4, 1],
[4, 2],
[4, 3]]
Out[52]:
[[1, 2, 3],
[1, 2, 4],
[1, 3, 2],
[1, 3, 4],
[1, 4, 2],
[1, 4, 3],
[2, 1, 3],
[2, 1, 4],
[2, 3, 1],
[2, 3, 4],
[2, 4, 1],
[2, 4, 3],
[3, 1, 2],
[3, 1, 4],
[3, 2, 1],
[3, 2, 4],
[3, 4, 1],
[3, 4, 2],
[4, 1, 2],
[4, 1, 3],
[4, 2, 1],
[4, 2, 3],
[4, 3, 1],
[4, 3, 2]]
Out[52]:
[[1, 2, 3, 4],
[1, 2, 4, 3],
[1, 3, 2, 4],
[1, 3, 4, 2],
[1, 4, 2, 3],
[1, 4, 3, 2],
[2, 1, 3, 4],
[2, 1, 4, 3],
[2, 3, 1, 4],
[2, 3, 4, 1],
[2, 4, 1, 3],
[2, 4, 3, 1],
[3, 1, 2, 4],
[3, 1, 4, 2],
[3, 2, 1, 4],
[3, 2, 4, 1],
[3, 4, 1, 2],
[3, 4, 2, 1],
[4, 1, 2, 3],
[4, 1, 3, 2],
[4, 2, 1, 3],
[4, 2, 3, 1],
[4, 3, 1, 2],
[4, 3, 2, 1]]
组合实现(对于 [a, a, b, c] 这种情况,可以事先处理为 [a1, a2, b, c] 进行操作,操作后在将 a1/a2 转化为 a)
def combination(m_list, nb):
if nb == 1:
for m in m_list:
yield tuple([m])
else:
for k in range(len(m_list)):
for i in combination(m_list[0:k]+m_list[k+1:], nb-1):
yield tuple(sorted([m_list[k]] + list(i)))
set(list(combination([1, 2, 3, 4], 1)))
set(list(combination([1, 2, 3, 4], 2)))
set(list(combination([1, 2, 3, 4], 3)))
set(list(combination([1, 2, 3, 4], 4)))
output:
{(1,), (2,), (3,), (4,)}
Out[67]:
{(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)}
Out[67]:
{(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)}
Out[67]:
{(1, 2, 3, 4)}
迷宫(所有路径)
从某一点为起点,到达终点,利用 DFS 方法
伪代码如下:
# 首先需要定义四个方向的步长
# four directions
# up, right, down, left
item = [(-1, 0), (0, 1), (1, 0), (0, -1)]
def find_a_way(point_start, point_end):
# 将点进栈并赋值为 False ,防止后面回来
stack.push(point_start)
grid[point_start] = False
# 接下来根据两种情况进行判断
if point_start == point_end:
# 这就是终点了,需要输出路径,并统计数目
stack.output()
count += 1
else:
# 按照四个方向遍历
for i in range(len(item)):
point_tmp = (point_start[0]+item[i][0], point_start[1]+item[i][1])
# 如果这个点是 True,就继续往下走
if grid[point_tmp] == True:
find_a_way(point_tmp, point_end)
# 将进栈的数据再吐出来,并重新复制为 True
stack.pop()
grid[point_start] = True
首先判断上,如果可以,就卡开 find_a_way(point_tmp, point_end) 的位置,继续运行代码,然后看下一个点
如果碰巧上不可以,再看看右,如果右可以,继续卡在下一个 find_a_way(point_tmp, point_end) 的位置,此时每个点都会进栈并且标记为 False
...
以此类推,最终到达终点了,这时候进栈的数据可以打印出来了,然后运行 stack.pop() 和 grid[point_start] = True,把终点吐出来,并标记为 True
然后是返回来到 上一个 find_a_way(point_tmp, point_end) 的位置,然后继续运行下一个可行的方向,所有方向运行完以后,继续运行 stack.pop() 和 grid[point_start] = True,把这个点吐出来,并标记为 True
返回到上一点的下一个方向的时候,他又把上面的过程走了一遍。。。真的好复杂,有点乱了。。。
...
以此类推,最终退回到第一个点的 find_a_way(point_tmp, point_end) 的位置,继续运行 stack.pop() 和 grid[point_start] = True,把这个点吐出来,并标记为 True
一个路径执行完毕