繁体   English   中英

如何获取列表的所有排序,使列表等于另一个列表?

[英]How to get all orderings of a list such that the list is equal to another list?

我有列表A和B,可以有重复项,例如:

A = ['x', 'x', 7]
B = [7, 'x', 'x']

现在我想要所有将列表B置于列表A中的索引排列:

[1, 2, 0]    # because [B[1], B[2], B[0]] == A
[2, 1, 0]    # because [B[2], B[1], B[0]] == A

有没有办法实现这一点,而不是迭代所有可能的排列? 我已经用过

import itertools
for p in itertools.permutations(range(len(B))):
    if A == permute(B,p):

迭代所有可能的排列并检查我想要的排列,但我希望更快地拥有正确的排列。

您应该将问题分解为两个:

  • 首先找到将B映射到A的特定排列sigma_0
  • 找到将B映射到自身的所有排列的集合S_B

然后你正在寻找的集合只是{sigma_0 \\circ \\sigma, sigma \\in S_B}

现在问题变成:如何确定S_B 要做到这一点,您可以观察到如果您将集合{0,1,2,..,n} (在您的情况下为n=2 )写为A_1 \\cup .. A_k ,其中每个A_i对应于索引在B中对应于第i个元素(在您的情况下,您将有A_1 = {1,2}A_2 = {0} ),那么S_B每个元素都可以以独特的方式写为产品tau_1 \\circ .. tau_k其中每个tau_i是一个作用于A_i的排列。

因此,在您的情况下, S_B = {id, (1,2)} ,您可以使用sigma_0 = (0,2) 因此,你所追求的集合是{(0,2), (2,0,1)}

这是一种方法。 我的perms函数生成所有有效的排列。 首先,我收集B中每个元素的索引,然后通过总是为A中的每个项目选择一个仍然可用的索引来递归构建并产生排列,直到准备好产生排列。

from collections import defaultdict

def perms(A, B):
    indexes = defaultdict(set)
    for i, e in enumerate(B):
        indexes[e].add(i)
    def find(perm):
        k = len(perm)
        if k == len(A):
            yield perm
            return
        I = indexes[A[k]]
        for i in list(I):
            I.remove(i)
            yield from find(perm + (i,))
            I.add(i)
    yield from find(())

用法:

A = ['x', 'x', 7]
B = [7, 'x', 'x']

for perm in perms(A, B):
    print(perm)

输出:

(1, 2, 0)
(2, 1, 0)

你可以分三步完成。 首先,从列表B创建一个字典,其中项目为键,索引为值。 在您的情况下,列表B的字典:

B = [7, 'x', 'x']

  7 - [0]
'x' - [1, 2]

然后,浏览列表A并构建一个索引,将List A索引映射到相应的List B索引。 那是:

A = ['x', 'x', 7]

0 - [1, 2]
1 - [1, 2]
2 - [0]

从那里,您可以生成所有有效的映射。 应该很容易编写代码,给定上面的索引,将生成[1, 2, 0][2, 1, 0]

这是Python中的一些东西。 我使用字符串进行散列,因为我不熟悉如何在Python中将集合和数组作为递归参数传递,尽管它们可能更有效。

A = ['x', 'x', 7, 'y', 8, 8]
B = [7, 'x', 8, 'x', 8, 'y']
H = {}

# record the indexes of elements in B
for i in xrange(0,len(B)):
  if B[i] in H:
    H[ B[i] ].append(str(i)) 
  else:
    H[ B[i] ] = [str(i)]

# build permutations in the order that the elements are encountered in A
def perms(perm,i,visited,l):
  if i==l:
    print perm
    return
  for j in H[ A[i] ]:
    if j not in visited:
      perms(perm + j,i + 1,visited + j,l)

perms("",0,"",len(A)) 

输出:

130524
130542
310524
310542

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM