python - 对字符列表进行组合输出

问题:
对字符列表进行组合输出
输入:a,b,c,d
输出:'a', 'ab', 'abc', 'abcd', 'ac', 'acd', 'ad', 'abd', 'b', 'bc', 'bcd', 'bd', 'c', 'cd', 'd'

解决方案:
采用递归:
1'a', 'ab', 'abc', 'abcd', 'ac', 'acd', 'ad', 'abd'
2'b', 'bc', 'bcd', 'bd'
3'c', 'cd'
4'd'

讨论:
1、资源上存在浪费。在计算字符组合时,会重复计算相同的组合。将去重复放在字符组合处理过程中。
2、字符串长度为25时,处理时间约2秒。长度为62时,处理时间2323.19秒:
15 ['a', 'ab', 'abc', 'abcd', 'ac', 'acd', 'ad', 'abd', 'b', 'bc', 'bcd', 'bd', 'c', 'cd', 'd']
['t', '8', 'R', '4', 'o', 'm', 'p', 'S', 'D', 'V', 
'x', 'v', 'z', 's', 'P', 'H', 'N', 'u', 'C', '2',
 'f', 'k', '9', 'U', 'L', 'i', 'l', 'A', 'O', 'W',
 'c', '0', 'F', 'a', 'b', 'd', 'G', 'Q', 'r', '1', 
'J', 'Y', 'h', '7', 'y', '3', 'B', 'E', 'K', 'T', 
'q', '5', 'M', 'g', 'j', 'X', 'I', 'Z', 'w', '6', 
'n', 'e']
处理组合耗时 2323.19 秒
597618


源代码:
# -*- coding:utf-8 -*-
'''
对字符列表进行组合输出
输入:a,b,c,d
输出:'a', 'ab', 'abc', 'abcd', 'ac', 'acd', 'ad', 'abd', 'b', 'bc', 'bcd', 'bd', 'c', 'cd', 'd'
采用递归:
1'a', 'ab', 'abc', 'abcd', 'ac', 'acd', 'ad', 'abd'
2'b', 'bc', 'bcd', 'bd'
3'c', 'cd'
4'd'
'''
import string
import random
import time
from datetime import datetime, timedelta

def str2list(str0):
    '''字符串转列表,list0=list(str0)'''
    pass
def list2str(list1):
    '''列表转为字符串,str0=''.join(list1)'''
    str0 = ''
    for i in list1:
        str0 += str(i)
    return str0

def norepeat(list1):
    '''去掉重复'''
    list0 = []
    list0.append(list1[0])
    for i in list1:
        if i not in list0:
            list0.append(i)
    return list0

# result = [] #取消全局变量
def list_handle(list1, result):
    '''获取所有组合'''
    length = len(list1)
    # print 'list长度为%d\n' % length
    if 1 == length:
        result.append(str(list1[0]))
    else:
        # 第三次迭代,考虑abd场景
        cnt = 1
        while(1):
            str0 = list2str(list1[0:cnt])
            if str0 not in result:
                result.append(str0)
            for m in range(cnt, length, 1):
                str1 = ''
                while (length > m):
                    str1 += str(list1[m])
                    str_tmp = str0 + str1
                    if str_tmp not in result:
                        result.append(str_tmp)
                    m += 1
            # print 'cnt---', cnt
            # print result
            cnt += 1
            if length == cnt:
                break
        list_handle(list1[1:length], result)

        # 第二次迭代,考虑a,ab,abc,abcd的场景
        # str0 = str(list1[0])
        # result.append(str0)
        # for m in range(1,length,1):
        #     str1 = ''
        #     while(length > m):
        #         str1 += str(list1[m])
        #         result.append(str0 + str1)
        #         m += 1
        #
        # str0 = str(list1[0]) + str(list1[1])
        # m = 3
        # str1 = ''
        # while(length > m):
        #     str1 += str(list1[m])
        #     result.append(str0 + str1)
        #     m += 1
        # m = 3
        # str1 = ''
        # while(length > m):
        #     str1 += str(list1[m])
        #     result.append(str0 + str1)
        #     m += 1

        # 第一次迭代,直观的写出输出的方式
        # str1 = str(list1[1])
        # result.append(str0 + str(list1[length-3]))
        # str2 = str(list1[2])
        # result.append(str0 + str(list1[length-2]))
        # result.append(str0 + str(list1[length-3]) + str(list1[length-2]))
        # str3 = str(list1[3])
        # result.append(str0 + str(list1[length-1]))
        # result.append(str0 + str(list1[length-3]) + str(list1[length-1]))
        # result.append(str0 + str(list1[length-2]) + str(list1[length-1]))
        # result.append(str0 + str(list1[length-3]) + str(list1[length-2]) + str(list1[length-1]))

if __name__ == '__main__':
    list_in = ['a','b','c','d']
    result = []
    list_handle(list_in, result)
    print len(result),result
    # print len(norepeat(result)), norepeat(result)

    str0 = ''.join(random.sample(string.ascii_letters + string.digits, 25))
    print list(str0)
    result = []
    begin_time = datetime.now()
    list_handle(list(str0), result)
    end_time = datetime.now()
    delta_time = end_time - begin_time
    print '处理组合耗时 %.2f ' % delta_time.total_seconds()
    print len(result)

    # begin_time = datetime.now()
    # list_norepeat = norepeat(result)
    # end_time = datetime.now()
    # delta_time = end_time - begin_time
    # print '去掉重复耗时 %.2f ' % delta_time.total_seconds()
    # print len(list_norepeat)

'''
输出结果:
---
list长度为4

cnt--- 1
['a', 'ab', 'abc', 'abcd', 'ac', 'acd', 'ad']
cnt--- 2
['a', 'ab', 'abc', 'abcd', 'ac', 'acd', 'ad', 'ab', 'abc', 'abcd', 'abd']
cnt--- 3
['a', 'ab', 'abc', 'abcd', 'ac', 'acd', 'ad', 'ab', 'abc', 'abcd', 'abd', 'abc', 'abcd']
list长度为3

cnt--- 1
['a', 'ab', 'abc', 'abcd', 'ac', 'acd', 'ad', 'ab', 'abc', 'abcd', 'abd', 'abc', 'abcd', 'b', 'bc', 'bcd', 'bd']
cnt--- 2
['a', 'ab', 'abc', 'abcd', 'ac', 'acd', 'ad', 'ab', 'abc', 'abcd', 'abd', 'abc', 'abcd', 'b', 'bc', 'bcd', 'bd', 'bc', 'bcd']
list长度为2

cnt--- 1
['a', 'ab', 'abc', 'abcd', 'ac', 'acd', 'ad', 'ab', 'abc', 'abcd', 'abd', 'abc', 'abcd', 'b', 'bc', 'bcd', 'bd', 'bc', 'bcd', 'c', 'cd']
list长度为1

22 ['a', 'ab', 'abc', 'abcd', 'ac', 'acd', 'ad', 'ab', 'abc', 'abcd', 'abd', 'abc', 'abcd', 'b', 'bc', 'bcd', 'bd', 'bc', 'bcd', 'c', 'cd', 'd']
15 ['a', 'ab', 'abc', 'abcd', 'ac', 'acd', 'ad', 'abd', 'b', 'bc', 'bcd', 'bd', 'c', 'cd', 'd']
'''
'''
改进后:将去掉重复的处理放在字符组合过程中。
15 ['a', 'ab', 'abc', 'abcd', 'ac', 'acd', 'ad', 'abd', 'b', 'bc', 'bcd', 'bd', 'c', 'cd', 'd']
['U', 'T', 'd', 'i', '7', 'm', 'J', 'V', 'B', 'O', 'w', 'y', 'c', 'H', '2', 'h', 'o', 'S', '4', 't', 'K', 'Z', 'A', 'g', 'f']
处理组合耗时 1.61 
15275
'''
                        

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值