【问题标题】:extending permutation algorithm (including duplicates) [duplicate]扩展排列算法(包括重复)[重复]
【发布时间】:2014-08-14 14:01:25
【问题描述】:

我正在寻找一种算法,可以给出所有可能的字母组合

让我解释得更好。如果我有

base-letters = ["a","b","c"];
depth = 2; //max chars allowed

那么预期的结果将是这 12 个元素 (3^1 + 3^2 = 12):

["a", "b", "c", "aa","ab","ac","ba","bb","bc","ca", "cb", "cc"]

如果我的深度值 = 3,我希望 (3^1) + (3^2) + (3^3) = 39 个元素

["a", "b", ... , "aa", "ab", ... , "aaa", "aab", ..., "aba", ...]

现在,如果我理解正确,排列算法是相似的,但不考虑 重复 字母(如“aa”、“bb”、“aab”、“aba”),以及 可变深度值(可能与基字母长度不同)。

【问题讨论】:

  • 这可以使用递归来完成。

标签: algorithm combinations permutation


【解决方案1】:

您可以定义一个递归函数 F(s),它接受一个长度小于或等于您的最大长度的字符串 s,然后首先调用 F(s),其中 s 等于空字符串。函数 F 计算字符串的长度,如果它等于最大长度,则打印字符串 s 并返回。如果字符串的长度小于最大值,则 F(s) 打印出字符串 s,然后遍历字母表中所有可能的字母,对于每个字母,它将字母添加到字符串 s 的末尾以生成长度为 1 的字符串 s',然后调用 F(s')。这具有非常低的内存使用率,基本上是最快的方法,至少在渐近方面是这样。

【讨论】:

    【解决方案2】:

    在 Python 中,使用 itertools's permutations function(如果您需要将代码翻译成您的母语,请使用代码配方)

    >>> import itertools
    >>> base_elements = ['a', 'b', 'cow']
    >>> max_depth = 2
    >>> result = [''.join(element) for element in itertools.chain.from_iterable([itertools.permutations(base_elements, depth) for depth in range(1, max_depth+1)])]
    >>> print(result)
    ['a', 'b', 'cow', 'ab', 'acow', 'ba', 'bcow', 'cowa', 'cowb']
    

    如果您只想要唯一值,那么与其将每个输出元素连接成一个字符串,不如创建一个集合。这将删除重复项。然后从最终集合中删除重复项。

    >>> result = frozenset([frozenset(element)
                            for element in itertools.chain.from_iterable(
                              [itertools.permutations(base_elements, depth)
                               for depth in range(1, max_depth+1)]
                            )])
    

    或者更干净,

    def permutations(base_elements, max_depth):
        result = set()
        for depth in range(1, max_depth+1):
            for element in itertools.permutations(base_elements, depth):
                result.add(frozenset(element))
        return result
    

    【讨论】:

      【解决方案3】:

      看来这段代码会给你你需要的东西:

      def all_strs(iterable, depth):
          results = []
          if depth==1:
              for item in iterable:
                  results.append(str(item))
              return results
          for item in iterable:
              for s in all_strs(iterable, depth-1):
                  results.append(str(item) + s)
          return results
      
      if __name__ == "__main__":
          print all_strs('abc', 2)
          print all_strs([1, 2, 3], 3)
      
          s = 'abc'
          results = []
          for i in range(len(s)):
              results += print all_strs(s, i+1)
          print results
      

      输出是: ['aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca', 'cb', 'cc']

      ['111', '112', '113', '121', '122', '123', '131', '132', '133', '211', '212', '213 ','221','222','223','231','232','233','311','312','313','321','322','323', '331', '332', '333']

      ['a', 'b', 'c', 'aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca', 'cb', 'cc ','aaa','aab','aac','aba','abb','abc','aca','acb','acc','baa','bab','bac', 'bba'、'bbb'、'bbc'、'bca'、'bcb'、'bcc'、'caa'、'cab'、'cac'、'cba'、'cbb'、'cbc'、'cca ', 'ccb', 'ccc']

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-13
        • 2010-09-22
        • 1970-01-01
        • 1970-01-01
        • 2012-10-31
        • 1970-01-01
        相关资源
        最近更新 更多