简体   繁体   English

排列,但有一些数字保持在一个顺序

[英]Permutations but with some numbers kept in an order

Ok, I have had a browse around and I have looking for either a C or python solution to this problem. 好的,我已经浏览了一下,我已经找到了解决这个问题的C或python解决方案。 I would prefer python...although it is my weaker language (of 2 very weak languages). 我更喜欢python ...虽然它是我较弱的语言(2种非常弱的语言)。

A set of numbers, such as 0 0 1 7 0 0 3 0 0 4 一组数字,例如0 0 1 7 0 0 3 0 0 4

  1. Find all permutations of the set. 找到集合的所有排列。
  2. The numbers >0 must stay in that order (NOT POSITION!) 数字> 0必须保持该顺序(不是位置!)
  3. There MUST be a 0 between numbers, a 0 is not required at the start and end of the set though. 数字之间必须有0,但在集合的开头和结尾不需要0。 As long as there is AT LEAST ONE 0 between numbers >0. 只要数字> 0之间至少有一个0。

So firstly, I thought of just finding all possible permutations and then removing the chaff (checking that if n>0 , !n+1>0) for each permutation and then the first number >0 == 1, 2nd # >0 ==7 etc. etc. 首先,我想到找到所有可能的排列然后去除每个排列的箔条(检查n> 0,!n + 1> 0),然后第一个数字> 0 == 1,第二个#> 0 = = 7等

I then stopped and thought that was daft, say there were 12 numbers, that would give 12! 然后我停下来,认为这是愚蠢的,说有12个数字,这将给12! permutations. 排列。 This in the order of 500,000,000 permutations of which I would have to run through again to get rid of chaff. 这是500,000,000排列的顺序,我将不得不再次通过以摆脱箔条。

Say I had 40-50 sets of these number sets to go through, that is a fair whack of time. 假设我有40到50套这些数字套装可以通过,这是一个公平的时间。

Is there a more logical way? 有更合乎逻辑的方式吗? I thought of somehow having python do permutations somehow taking those rules in to account (if n>0, n+1 MUST == 0) and (n=first number, n2=2nd etc.) 我想到某种方式让python做排列以某种方式考虑这些规则(如果n> 0,n + 1必须== 0)和(n =第一个数字,n2 =第2个等)

An example of a smaller set would be (NOT ALL PERMUTATIONS, but gives idea): 一个较小的集合的例子是(不是所有的PERMUTATIONS,但给出了想法):

1,2,3,0,0,0,0,0 1,2,3,0,0,0,0,0

  1. 1,0,2,0,3,0,0,0 1,0,2,0,3,0,0,0
  2. 0,1,0,2,0,3,0,0 0,1,0,2,0,3,0,0
  3. 0,0,1,0,2,0,3,0 0,0,1,0,2,0,3,0
  4. 0,0,1,0,0,2,0,3 0,0,1,0,0,2,0,3
  5. 0,1,0,0,2,0,3,0 0,1,0,0,2,0,3,0

etc. etc. So 1,2,3 is in order but the "0"s are just shifted about? 所以1,2,3是有序的,但是“0”只是左右移动了?

Thanks! 谢谢!

Basically you want to reduce the number of combinations you have to compute by grouping things according to their invariants. 基本上,您希望通过根据不变量对事物进行分组来减少必须计算的组合数。 Since the non-zero numbers must be in a fixed order let's start with that: 由于非零数字必须是固定的顺序,所以我们从那开始:

   1 2 3

Since there must be 0's between them add them in 因为它们之间必须有0,所以加入它们

   1 0 2 0 3

Now what you are left with is three 0's to place and you need to figure how many combinations give distinct sequences. 现在剩下的就是要放置三个0,你需要确定有多少组合给出了不同的序列。 Clearly from this example the possible positions you have are: before the 1, between the 1 and 2, between the 2 and 3 and after the 3. You have 4 positions in which to decide how to split up the remaining three 0's. 显然,从这个例子中你可能的位置是:在1之前,在1和2之间,在2和3之间以及在3之后。你有4个位置来决定如何分割剩下的3个0。 This is a combination problem with repetition , for which the solution here is (3 + 4 - 1) Choose 3 (which is 20). 这是重复组合问题,这里的解是(3 + 4 - 1) Choose 3 (即20)。

Hopefully the way that I went through this example problem is enough for you to generalize this to arbitrary sequences, so I will leave that as an exercise to the reader. 希望我通过这个示例问题的方式足以让你将其推广到任意序列,所以我将把它作为练习留给读者。

def find_permutations(l):
    n = [e for e in l if e] # Strip zeros.
    # Interspace non-zeros with zeros.
    m = [j for i in n for j in (i,0)][:-1]
    def fill(m):
        if len(m) == len(l):
            yield tuple(m)
        else:
            # Recursively fill with zeros.
            for i in range(len(m)+1):
                for o in fill(m[:i] + [0] + m[i:]):
                    yield tuple(o)
    return sorted(set(fill(m)))

I think this should cover it. 我认为这应该涵盖它。 So for instance (in python 3), you could do: 所以例如(在python 3中),您可以这样做:

>>> [print(p) for p in find_permutations([1,2,3,0,0,0,0,0])]
(0, 0, 0, 1, 0, 2, 0, 3)
(0, 0, 1, 0, 0, 2, 0, 3)
(0, 0, 1, 0, 2, 0, 0, 3)
(0, 0, 1, 0, 2, 0, 3, 0)
(0, 1, 0, 0, 0, 2, 0, 3)
(0, 1, 0, 0, 2, 0, 0, 3)
(0, 1, 0, 0, 2, 0, 3, 0)
(0, 1, 0, 2, 0, 0, 0, 3)
(0, 1, 0, 2, 0, 0, 3, 0)
(0, 1, 0, 2, 0, 3, 0, 0)
(1, 0, 0, 0, 0, 2, 0, 3)
(1, 0, 0, 0, 2, 0, 0, 3)
(1, 0, 0, 0, 2, 0, 3, 0)
(1, 0, 0, 2, 0, 0, 0, 3)
(1, 0, 0, 2, 0, 0, 3, 0)
(1, 0, 0, 2, 0, 3, 0, 0)
(1, 0, 2, 0, 0, 0, 0, 3)
(1, 0, 2, 0, 0, 0, 3, 0)
(1, 0, 2, 0, 0, 3, 0, 0)
(1, 0, 2, 0, 3, 0, 0, 0)

Was this similar to what you had in mind? 这与你的想法相似吗?

Edit: basically what the function called fill does is insert a zero between each number of the list, and recurse. 编辑:基本上称为fill的函数是在列表的每个数字之间插入一个零,并递归。 Whenever enough numbers are recorded in the fill function (list length of recursively generated numbers equals list length of original input) a tuple of numbers is returned. 只要在fill函数中记录了足够的数字(递归生成的数字的列表长度等于原始输入的列表长度),就会返回一个数字元组。

The only reason for converting to tuples when returning is that the type must be hashable to use in a set, as seen on the last line of the find_permutations function. 返回时转换为元组的唯一原因是类型必须可以在一个集合中使用,如find_permutations函数的最后一行find_permutations sorted is for niceness. sorted是为了好。

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

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