[Alg]-字符串的组合

全组合

  递归法

  二进制位法

指定位数组合

 

字符串组合:包括全组合和指定位数组合。

全组合

求一个字符串可以产生的所有组合;如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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值