【问题标题】:Permutations of a series of coloured balls, without 2 of the same colour next to each other?一系列彩色球的排列,没有两个相同颜色的球相邻?
【发布时间】:2019-02-18 13:02:20
【问题描述】:

输入是一个字符串(a, b, c, d,...)。在这个字符串中,a 表示相同颜色的 a 球,b 表示另一种颜色的 b 球,依此类推。所以 (2, 1, 3) 表示 2 个红球、1 个蓝球和 3 个黄球。

输出 1 是可能排列的数量,没有 2 个相同颜色的球相邻。

输出 2 是所有这些排列的列表。

例如:

输入:(2, 1, 3)

输出 1: 10个排列

输出 2: 131323, 132313, 231313, 312313, 313123, 等等

所以我的主要问题是:如何过滤Python 程序中两个或多个相同颜色的球彼此相邻的排列?

【问题讨论】:

  • 嘿,罗莎,你在处理大量排列吗?我想你可以循环遍历排列中的数字列表,但如果你使用 100 万个以上的排列,它会太慢
  • @JuanC 排列的数量不是问题,我没有处理大量的问题。我一直在努力解决如何确定哪些排列有相同颜色的球相邻,所以我可以过滤它们。
  • 我假设输出 2 是列表格式,对吧?
  • @JuanC 是的,是的
  • @Rosa:我的回答解决了你的问题吗?

标签: python permutation


【解决方案1】:

以下代码将解决您的问题:

import numpy as np
num = 221333 ## Any random permutation
lst = list(map(int, str(num)))
req_array = np.diff(lst)
if 0 in req_array:
    print ("Yes")

以上代码的工作逻辑如下:

  1. 逐一迭代您的排列列表。以上代码适用于该列表中的 1 个此类元素
  2. number 转换为array
  3. 减去连续元素
  4. 如果数组为零,则有一个组合,其中 2 个球的颜色相同

【讨论】:

    【解决方案2】:

    绝对不是最整洁的做事方式,而是使用这个问题的答案:

    https://stackoverflow.com/a/36343769/9742036

    关于如何检查列表中的相等邻居,这应该可以解决问题。

    我们首先生成一个代表您的球组合的列表,查看它们的所有排列,然后过滤掉那些无效的。

    from itertools import permutations
    from operator import eq
    
    input = (2, 1, 3)
    
    # Produce a list to represent the objects to order. (2,1,3) -> [0, 0, 1, 2, 2, 2]
    list_of_items = []
    current_item = 1
    for value in input:
        for number in range(value):
            list_of_items.append(current_item)
    
        current_item += 1
    
    
    
    count_of_valid_permutations = 0
    set_of_valid_permutations = set()
    
    # Generate all permutations of our list
    for permutation in permutations(list_of_items):
        # Permutations treat each ball as unique, even if the same colour, so check we're not over counting.
        if permutation not in set_of_valid_permutations:
    
            # Use the eq operator and map it to the permutation to see if any neighbours are equal.
            hasEqualNeigbours = any(map(eq, permutation, permutation[1:]))
            # If not, then this is a valid permutation.
            if not hasEqualNeigbours:
                # Record the permutation as seen.
                set_of_valid_permutations.add(permutation)
                count_of_valid_permutations += 1
    
    
    print(count_of_valid_permutations)
    print(set_of_valid_permutations)
    

    【讨论】:

      【解决方案3】:

      这有点令人费解,可能有更高效的版本,但这应该可以解决问题:

      output2=['12234','22341','1234','12344']
      
      permut=[]
      for num in b: #For every element in the list output2
          for n,i in enumerate(num): #For every index and number inside every element of the list
              if n>0: #This is only for the next line to work on the first iteration
                  if num[n]==num[n-1]: #If a number is the same than the previous number
                      permut.append(num) #append into a new list the whole permutation number
                      break #Go to the next loop
                  else:
                      continue
              else:
                  continue
      

      【讨论】:

        【解决方案4】:

        假设output2 是您的排列字符串的数组,您可以通过丢弃具有(至少)两个连续颜色代码的排列来过滤数组:

        import re
        output2 = filter(lambda perm: not re.search(r"(\d)\1", perm), output2)
        

        正则表达式解释:\d 匹配任何数字。周围的括号标记一个“匹配组”。 \1 解析为第一个匹配组。因此,组合起来,(\d)\1 匹配任意两个连续相同的数字。

        如果output2 不是一个数组,而是一个逗号分隔的字符串列表,你可以像这样拆分它,以获得一个数组:

        output2 = output2.split(', ')
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多