以各种方式替换字符串中的字符

时间:2012-11-07 17:29:07

标签: python

我正在寻找一个带字符串的函数的帮助,并以各种方式替换该字符串中的每个字符。我不太确定如何说出我的问题,这样才有意义,所以我会告诉你它应该做什么。

stars('1')
returns ['*']

stars('12')
returns ['*1', '1*', '**']

stars('123')
returns ['*23', '1*3', '12*', '**3', '*2*', '**1', '***']

stars('1234')
returns ['*234', '1*34', '12*4', '123*', '**34', '*2*4', '*23*', '1**4', '1*3*', 
         '12**', '***4', '**3*', '*2**', '1***', '****']

这一切都是手工完成的,但即使我犯了错误,你也应该了解我现在正在寻找的东西。最后的案例(所有*)不是必需的,但我把它放在那里以确保问题得到理解。

到目前为止,我已经提出了这个问题,但它并没有发挥作用。

def stars(n):
    lst = []
    length = len(n)
    for j in xrange(0, length):
        p = list(n)
        for k in xrange(j, length):
            p[k] = '*'
            lst += [''.join(p)]
    return lst

输出:

'1' returns ['*']
'12' returns ['*2', '**', '1*']
'123' returns ['*23', '**3', '***', '1*3', '1**', '12*']
'1234' returns ['*234', '**34', '***4', '****', '1*34', '1**4', '1***', '12*4', '12**', '123*']

非常感谢任何帮助。如果可能的话,想用Python解答,但如果你不懂Python,那么伪代码或其他语言是可以接受的。如果写得清楚,我相信我可以自己将它转换成Python。

4 个答案:

答案 0 :(得分:8)

我认为Python中的规范方法是使用itertools模块:

>>> from itertools import product, cycle
>>> s = 'abcde'
>>> [''.join(chars) for chars in product(*zip(s, cycle('*')))]
['abcde', 'abcd*', 'abc*e', 'abc**', 'ab*de', 'ab*d*', 'ab**e', 'ab***', 
 'a*cde', 'a*cd*', 'a*c*e', 'a*c**', 'a**de', 'a**d*', 'a***e', 'a****', 
 '*bcde', '*bcd*', '*bc*e', '*bc**', '*b*de', '*b*d*', '*b**e', '*b***',
 '**cde', '**cd*', '**c*e', '**c**', '***de', '***d*', '****e', '*****']

然后你可以在没有任何星星的情况下抛出第一个,但这看起来有点神奇。

ISTM如果你不想使用内置的笛卡尔积函数,你还有另外两种方法:你可以使用递归,或者你可以利用你想要打开和关闭每颗星的事实,二进制开关。这意味着用n个字母你将有2 ^ n(-1,如果你删除无星形的情况下)返回的可能性,以及是否在某处放置一个星形对应于相应的位是否相应在数字设置中(例如'abc'你从1到7包括循环,1 = 001所以你在最后一个地方放了一颗星,7 = 111所以你到处都放了一颗星等等。 )

这最后一个很容易实现,所以我会留给你。 :^)

答案 1 :(得分:2)

您可以将此视为查找和迭代原始字符串中所有字符子序列的问题。 (对于每个子序列,用'*'替换其中的字符,并将其余部分单独替换。)

对于给定的子序列,每个字符都在其中,因此对于N字符串,有2 ^ N个子序列。可能迭代它们的最简单方法是迭代从0到(2 ^ N)-1的整数,并使用它们的二进制表示作为是否应该替换字符的指示

对于N = 3,它看起来像这样:

0  000 abc
1  001 ab*
2  010 a*c
3  011 a**
4  100 *bc
5  101 *b*
6  110 **c
7  111 ***

在Python中,你可以这样做:

def stars(input):
    l = len(input)
    for i in xrange(2**l):
        yield ''.join([('*' if i&(2**(l-pos-1)) else ch) for pos, ch in enumerate(input)])

尝试一下:

>>> print list(stars('abc'))
['abc', 'ab*', 'a*c', 'a**', '*bc', '*b*', '**c', '***']

答案 2 :(得分:1)

这是使用combinations的方式:

from itertools import combinations
def stars(str):
    N,L = len(str), []
    for k in range(0,N+1):
        for com in combinations(range(N),k):
            S = list(str)
            for x in com: S[x] = '*'
            L.append(''.join(S))
    return L

尝试一下:

>>> stars('abc')
['abc', '*bc', 'a*c', 'ab*', '**c', '*b*', 'a**', '***']
>>> stars('1234')
['1234', '*234', '1*34', '12*4', '123*', '**34', '*2*4', '*23*', '1**4', '1*3*', '12**', '***4', '**3*', '*2**', '1***', '****']

答案 3 :(得分:0)

或者特定于Python,请看这个函数:http://docs.python.org/2/library/itertools.html#itertools.combinations