我试图在Python中编写一个函数,给定一个字符串和一个可选字符,从给定的字符串生成所有可能的字符串。大局是利用这个功能最终帮助将CFG变成乔姆斯基普通形式。
例如,给定一个字符串' ASA'和可选字符' A',我希望能够生成以下数组:
['SA', 'AS', 'S']
因为这些是可以通过省略原始字符串中的一个或两个来生成的所有可能的字符串。
作为参考,我查看了以下问题:generating all possible strings given a grammar rule,但问题似乎略有不同,因为语法规则是在原始字符串中定义的。
这是我对如何解决问题的想法:有一个带有字符串和可选字符的递归函数,循环遍历字符串以找到第一个可选字符,然后创建一个具有第一个可选字符的新字符串字符省略,将其添加到返回数组,并使用刚刚生成的字符串和相同的可选字符再次调用自身。
然后,在所有递归返回后,返回到原始字符串并省略第二次出现的可选字符,并重复该过程。
这将继续,直到省略所有可选字符。
我想知道是否有更好的方法可以做到这一点,而不是使用我刚才描述的逻辑类型。
答案 0 :(得分:0)
这是基于组合方法,它返回列表元素的所有可能组合(不考虑顺序)的列表。将角色出现的索引列表传递给它,其余的很简单:
def indexes(string, char):
return [i for i in range(len(string)) if string[i] == char]
def combinations(chars, max_length=None):
if max_length is None:
max_length = len(chars)
if len(chars) == 0:
return [[]]
nck = []
for sub_list in combinations(chars[1:], max_length):
nck.append(sub_list)
if len(sub_list) < max_length:
nck.append(chars[:1] + sub_list)
return nck
def substringsOmitting(string, char):
subbies = []
for combo in combinations(indexes(string, char)):
keepChars = [string[i] for i in range(len(string)) if not i in combo]
subbies.append(''.join(keepChars))
return subbies
if __name__ == '__main__':
print(substringsOmitting('ASA', 'A'))
output: ['ASA', 'SA', 'AS', 'S']
它也包含字符串本身。但这应该是一个很好的起点。
答案 1 :(得分:0)
正如评论中提到的,它也可以用itertools完成。这是一个快速演示:
import itertools
mystr='ABCDABCDAABCD'
optional_letter='A'
indices=[i for i,char in enumerate(list(mystr)) if char==optional_letter]
def remover(combination,mystr):
mylist=list(mystr)
for index in combination[::-1]:
del mylist[index]
return ''.join(mylist)
all_strings=[remover(combination,mystr)
for n in xrange(len(indices)+1)
for combination in itertools.combinations(indices,n)]
for string in all_strings: print string
首先查找角色出现的所有索引,然后从字符串中删除这些索引的所有组合。如果您在sring中连续有两个可选字母,您将获得重复项,可以使用以下方法删除:
set(all_strings)