字符串组合:包括全组合和指定位数组合。
全组合
求一个字符串可以产生的所有组合;如abc,它的组合有a、b、c、ab、ac、bc、abc。
以下所有算法默认都无法处理字符串中有重复字符的情况,因此最终结果使用set存放,以自动去除重复的子串。
递归法
遍历字符串,每个字符可以取或者不取。
def getAllCombineRecursion(rank:list)->set:
result = set()
def getCom(com:list):
get = ''.join(com)
print((get if get else '""'))
result.add(get)
def helper(rank:list, com:list):
if not rank:
getCom(com)
return
com.append(rank[0])
helper(rank[1:], com)
# not include current
com.remove(rank[0])
helper(rank[1:], com)
helper(rank, [])
return result
若不需要包括空组合(不包括任何字符串),则在getCom时判断一下列表是否为空即可。
二进制位法
全组合中,每个元素有两种选择:取或不取;对应二进制即为1或0。因此可以使用对应二进制位是否为1来处理。即取0到2n-1(n为字符串长度)间的数字,依次根据其对应二进制来获取组合。
def getAllCombineBits(rank:list)->set:
result = set()
def getCom(com:list):
get = ''.join(com)
print((get if get else '""'))
result.add(get)
for i in range(0, pow(2,len(rank))):
com = []
index = 0
while i:
if i&1:
com.append(rank[index])
i >>= 1
index += 1
getCom(com)
return result
若不需要包括空组合(不包括任何字符串),只需要range时从1开始即可。
指定位数组合
在长度为n的字符串中求m个字符的组合。依次遍历字符串:
- 包含当前第一个字符,然后在剩下的n-1个字符中选取m-1个字符;
- 不包含当前第一个字符,然后在剩下的n-1个字符中选择m个字符;
前面全组合,也可以看作是依次获取0~n个字符子串的所有组合。
def getMCombine(rank:list, m:int)->set:
result = set()
def getCom(com:list):
get = ''.join(com)
print((get if get else '""'))
result.add(get)
def helper(rank:list, count:int, com:list):
if count==0:
getCom(com)
return
if not rank:
print('List empty: not enough char: ', count)
return
if count>len(rank):
print('not enough char: ', count, len(rank))
return
com.append(rank[0])
helper(rank[1:], count-1, com)
com.remove(rank[0])
helper(rank[1:], count, com)
helper(rank, m, [])
return result