【问题标题】:Python help: generating all possible strings given optional characterPython帮助:给定可选字符生成所有可能的字符串
【发布时间】:2015-11-28 10:02:37
【问题描述】:

我正在尝试用 Python 编写一个函数,给定一个字符串和一个可选字符,从给定的字符串生成所有可能的字符串。大局是使用此函数最终帮助将 CFG 转换为 chomsky 范式。

例如,给定一个字符串“ASA”和可选字符“A”,我希望能够生成以下数组:

['SA', 'AS', 'S']

因为这些都是可以通过省略原始字符串的一个或两个 A 来生成的所有可能的字符串。

作为参考,我查看了以下问题:generating all possible strings given a grammar rule,但问题似乎略有不同,因为语法规则是在原始字符串中定义的。

这是我对如何解决问题的想法:有一个递归函数,它接受一个字符串和一个可选字符,遍历字符串以找到第一个可选字符,然后创建一个具有第一个可选字符的新字符串省略字符,将其添加到返回数组,并使用刚刚生成的字符串和相同的可选字符再次调用自身。

然后,在所有递归返回后,返回原始字符串并省略第二次出现的可选字符,并重复该过程。

这将一直持续到所有出现的可选字符都被省略为止。

我想知道是否有比使用我刚才描述的逻辑类型更好的方法来做到这一点。

【问题讨论】:

  • 但是你有没有尝试过?
  • 您的解决方案非常有效。至于另一个,您可能会尝试围绕itertools 模块(组合、排列等)“玩”:首先,找到“可选字符”的所有出现,然后在其索引的所有可能的唯一组合上创建迭代器。
  • 谢谢!我能够创建一个类似于我描述的功能。一旦一切都启动并运行,我一定会稍后看看 itertools,看看我是否可以让事情变得更有效率。感谢您提及!

标签: python arrays string


【解决方案1】:

正如 cmets 中提到的,它也可以使用 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)

【讨论】:

    【解决方案2】:

    这是基于组合方法的,它返回一个列表中所有可能的元素组合(不考虑顺序)的列表。将你的角色出现的索引列表传递给它,剩下的就很简单了:

    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']
    

    它也包含字符串本身。但这应该是一个很好的起点。

    【讨论】:

      猜你喜欢
      • 2012-02-28
      • 2019-05-19
      • 2017-11-23
      • 1970-01-01
      • 2021-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多