Python使用#a = #b从字母{a,b,c}回溯字符串长度n

时间:2014-02-18 13:15:28

标签: python algorithm backtracking

我想制作一个算法,在给定的n中找到字母{a,b,c}上的字符串,其中数字'a'与'b'的出现次数相同

我出来了

n=3 #length String
h=-1 #length prefix
L=['a','b','c'] #alphabet
S=['','','',''] #solution
par=0 # it's zero if a and b have same occurence


def P(n,h,par,L,S):
    if h==n:
        if par==0:
            print(S)
    else:
        for i in L:
            if i=='a':
                par+=1
            if i=='b':
                par-=1
            S[h+1]=i
            P(n,h+1,par,L,S)
            #Update the stack after recursion
            if S[h+1]=='a':
                par-=1
            if S[h+1]=='b':
                par+=1


P(n,h,par,L,S)

我为糟糕的字符串实现道歉但是它有效并且它仅用于研究目的,问题是:有哪些方法可以避免算法的某些工作?因为它只为这个字母生成了所有n长度的字符串后才检查#a和#b。 我的目标是达到O(n *(要打印的字符串数))

2 个答案:

答案 0 :(得分:1)

这是你要做的事情:

from itertools import combinations_with_replacement

alphabet = "abc"

def combs(alphabet, r):
    for comb in combinations_with_replacement(alphabet, r):
        if comb.count('a') == comb.count('b'):
           yield comb

为此,

list(combs(alphabet, 3)) == [('a', 'b', 'c'), ('c', 'c', 'c')]

list(combs(alphabet, 4)) == [('a', 'a', 'b', 'b'), 
                             ('a', 'b', 'c', 'c'), 
                             ('c', 'c', 'c', 'c')]

这将产生所有组合并拒绝一些;根据{{​​3}}:

  

(n+r-1)! / r! / (n-1)!时返回的商品数量为n > 0

其中n == len(alphabet)

答案 1 :(得分:0)

您可以通过更改以下内容来减少浪费的工作:

        if i=='a':
            par+=1
        if i=='b':
            par-=1

        oldpar = par
        if i=='a':
            par+=1
        if i=='b':
            par-=1
        # there are n-h-1 characters left to place
        # and we need to place at least abs(par) characters to reach par=0
        if abs(par)>n-h-1:
            par = oldpar
            continue