All ways to partition a string

后端 未结 5 1996
深忆病人
深忆病人 2021-01-01 00:08

I\'m trying to find a efficient algorithm to get all ways to partition a string

eg for a given string \'abcd\' =>
\'a\' \'bcd\'
\'a\' \'b\' \'cd\'
\'a\'

5条回答
  •  滥情空心
    2021-01-01 00:38

    This is a solution which minimizes developer time by taking advantage of a built-in iterator. It should be reasonably quick for problem sizes for which the answer itself is not infeasibly large.

    There is a one-to-one correspondence between partitions of a string and subsets of potential cutpoints. If the length of the string is n then there are n-1 places where you could cut the string. A straightforward way would be to iterate through such subsets, and for each such subset, slice the string in that way. Here is a Python approach which uses the standard modules itertools:

    import itertools
    
    def multiSlice(s,cutpoints):
        k = len(cutpoints)
        if k == 0:
            return [s]
        else:
            multislices = [s[:cutpoints[0]]]
            multislices.extend(s[cutpoints[i]:cutpoints[i+1]] for i in range(k-1))
            multislices.append(s[cutpoints[k-1]:])
            return multislices
    
    def allPartitions(s):
        n = len(s)
        cuts = list(range(1,n))
        for k in range(n):
            for cutpoints in itertools.combinations(cuts,k):
                yield multiSlice(s,cutpoints)
    

    For example:

    >>> parts = allPartitions('World')
    >>> for p in parts: print(p)
    
    ['World']
    ['W', 'orld']
    ['Wo', 'rld']
    ['Wor', 'ld']
    ['Worl', 'd']
    ['W', 'o', 'rld']
    ['W', 'or', 'ld']
    ['W', 'orl', 'd']
    ['Wo', 'r', 'ld']
    ['Wo', 'rl', 'd']
    ['Wor', 'l', 'd']
    ['W', 'o', 'r', 'ld']
    ['W', 'o', 'rl', 'd']
    ['W', 'or', 'l', 'd']
    ['Wo', 'r', 'l', 'd']
    ['W', 'o', 'r', 'l', 'd']
    

    Note that this approach produces generates ['World'] as a partition of 'World'. This corresponds to slicing with an empty set of cut points. I regard that as a feature rather than a bug since the standard mathematical definition of partition allows for a partition of a set into one piece. If this in undesirable for your purposes, the fix is easy enough -- just iterate over the nonempty subsets of the cut points. In terms of the above code, this fix amounts to adding two characters to allPartitions: replace

    for k in range(n):
    

    by

    for k in range(1,n):
    

提交回复
热议问题