字符串組合:包括全組合和指定位數組合。
全組合
求一個字符串可以產生的所有組合;如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