从包含 m 个项目的集合 S 中选择的排列到另一个长度为 N (N>m) 的列表中

Posted

技术标签:

【中文标题】从包含 m 个项目的集合 S 中选择的排列到另一个长度为 N (N>m) 的列表中【英文标题】:permutations selecting from set S containing m items, into another list with length N (N>m) 【发布时间】:2020-01-31 00:02:00 【问题描述】:

我已经阅读了一些实现,例如,What is the best way to find all combinations of items in an array?

他们实现的好处是很多都是 Generic ,而不仅仅是 int 数组(或更糟糕的是,只有正 int 数组)

但是我找不到可以接受大小为 m 的数组(名称数组“S”)的项目。从数组“S”中取出项目,将它们放入另一个大小为 n 的数组“P”中(n 小于 m,我不明白的常见限制)。

例如,

S = [-1, 1]

P[j] = [1,1,1,1], [1, -1, 1, 1], [1, -1, -1, 1], [1, -1, -1, -1], [-1, -1, -1, -1], ... [-1, 1, 1, -1], [1, -1, -1, 1], [-1, 1, -1, 1], [1, -1, 1, -1]

j = permutations = 0 ... pow(m,n), in this example pow(2, 4) = 16 

请用 C# 或 python 编写任何东西?

还有时间复杂度...

参考资料:

What is the best way to find all combinations of items in an array?

https://codereview.stackexchange.com/questions/194967/get-all-combinations-of-selecting-k-elements-from-an-n-sized-array?newreg=92ded52aec7b4f9aaf161db14d07ee7a

【问题讨论】:

【参考方案1】:

这样的东西有用吗?

def f(ms, k):
  stack = [[m] for m in ms]
  while stack:
    next = stack.pop()
    if len(next) == k:
      yield next
    else:
      stack.extend([(next[:] + [m]) for m in ms])

print([comb for comb in f([-1, 1], 4)])

【讨论】:

谢谢,抱歉没有早点回复。这写得很优雅。没有递归很好,它不仅可以处理混合类型的数组。但是,我感觉时间复杂度更像 O(pow(2,k))? @user3761555 你会期待什么?如果我们需要实际的列表/项目,我们怎么能有更少的复杂性?如果我们只想要计数,我认为我们可以按照您的建议使用 O(1)。 问题,排列本身不是线性时间就能解决的问题吗? @user3761555 对不起,我不确定我是否理解你原来的问题。请提供一个示例,其中包含您希望从该函数中获得的确切输入和输出。我以为你想产生所有的可能性。 1)“排列”首先不可能在线性时间内完成吗?,2)最初的动机是找到排列“S”来蛮力解决问题(我从一开始就理解可能蛮力是次优,但我仍然想尝试):app.codility.com/programmers/lessons/17-dynamic_programming/…【参考方案2】:

Csharp 版本(不允许混合类型。而且 size > 100 可能会导致您的机器崩溃)

        static IEnumerable<IEnumerable<T>> Permutations<T>(IEnumerable<T> set, int size)
        
            Stack<IList<T>> stack = new Stack<IList<T>>();
            foreach(var item in set)
            
                var list = new List<T>()  item ;
                stack.Push(list);
            

            while(stack.Count>0)
            
                var next = stack.Pop();
                if(next.Count==size)
                
                    yield return next;
                
                else
                

                    foreach(var item in set)
                    
                        var list = new List<T>();
                        list.AddRange(next);
                        list.Add(item);
                        stack.Push(list);
                    
                
            
        

使用方法:

            int[] possibleValues = new int[]  -1, 1 ;
            var permutations = Permutations(possibleValues, 4);
            foreach(var permutation in permutations)
            
                foreach (int x in permutation)
                
                    Console.Write($"x \t");
                
            

【讨论】:

【参考方案3】:
import itertools

size = 4

for S in list ( itertools . product ([1 , -1] , repeat = size )):

【讨论】:

以上是关于从包含 m 个项目的集合 S 中选择的排列到另一个长度为 N (N>m) 的列表中的主要内容,如果未能解决你的问题,请参考以下文章

excel中,如何实现从一个表中检索数据,并排列到另一个表中。

斯特林数

全排列算法

Xcode 4.2 如何将一个项目包含到另一个项目中?

JZOJ573920190706毒奶

C++数学与算法系列之排列和组合