解决递归问题的核心
如何将问题分解为两个同类型的但范围更小的子问题,如何合并两个子问题的结果,子问题在何时停止。
划分问题时,可以划分为两个同等量级的,但范围更小的问题。也可以划分为一个最小量级的,和另个是该问题的补集的问题。
举例
求一个字符串所有可能的子串。如"abcd"的所有可能子串为['a', 'ab', 'abc', 'abcd', 'b', 'bc', 'bcd', 'c', 'cd', 'd']
划分:将字符串划分为第一个字符 + 后续字符串。
合并:后续字符串的解 + 第一个字符与后续字符串的解逐个相加
子问题停止:只有一个字符时
# coding: utf-8
import random
import string
def get_all_sub(s):
"""
求字符串的所有子串
:param s:
:return:
"""
#判断是否停止
if len(s) == 1:
return [s], [s]
#分解
first_char = s[0]
left_str = s[1:]
#合并
all_sub = []
head_sub = []
all_sub.append(first_char)
head_sub.append(first_char)
left_str_all_sub, left_str_head_sub = get_all_sub(left_str)
for i in left_str_all_sub: #合并剩余字符串的所有子串
all_sub.append(i)
for i in left_str_head_sub: #第一个字符与剩余字符串中以其第一个字符开头的所有可能子串合并
head_sub.append(first_char+i)
head_sub = list(set(head_sub))
all_sub = list(set(all_sub + head_sub))
return all_sub, head_sub
def main():
ran_str = ''.join(random.sample(string.ascii_letters, 4))
print(ran_str)
print(sorted(get_all_sub(ran_str)[0]))
if __name__ == '__main__':
main()
输出:
atOB
['B', 'O', 'OB', 'a', 'at', 'atO', 'atOB', 't', 'tO', 'tOB']
出现的问题:
在合并时将第一个字符串与剩余字符串所有的子串合并,而不是仅与其以第一个字符开头的字串合并。