如何查找多个数组项的所有组合

时间:2012-11-26 13:46:17

标签: arrays algorithm sorting

让我们说这些是起始数组:

[a,b,c]
[d]
[e,f]

什么算法可以生成以下数组?

[a,d,e]
[a,d,f]
[b,d,e]
[b,d,f]
[c,d,e]
[c,d,f]

启动数组的数量可能会有所不同。

5 个答案:

答案 0 :(得分:2)

取决于语言,但正式类似这样(当你指定了3个数组时)

for el1 in first_array do
  for el2 in second_array do
    for el3 in third_array do
      begin
        create new element in result array as [e1, el2, el3]
      end

答案 1 :(得分:1)

您能想到的最简单的算法是您可以拥有的最佳算法。由于答案的大小,所有阵列的倍数维度可以在这里做出很大的改进。我个人建议使用递归,因为数组的数量不能太大而不会使得到的数组的数量真的很大。

答案 2 :(得分:1)

分别有n个 1 ,n 2 ... n k 元素的k个数组。
编写所有组合非常希望在mixed radix中写下所有数字 因此,只需将所有可能的数字从0循环到(n 1 n 2 ... n k -1)并将其写入带有从数组中取出的“数字”的混合基数表示 - 只需要两个嵌套循环。

答案 3 :(得分:0)

另一种方法是图形方法,从原始集开始,顺时针移动其内容并存储组合。示例首先旋转最后一行,然后在最后一次旋转后移动最后一行 - 在这种情况下为d,但不能旋转它,因此您将旋转第一行。这就像二进制和。

[a,b,c]     [a,b,c]---->[b,c,a]     [b,c,a]---->[c,a,b]     [c,a,b]              
[d]         [d]         [d]         [d]         [d]         [d]    
[e,f]------>[f,e]------>[e,f]------>[f,e]------>[e,f]------>[f,e]

PD:你只会保存每个数组的第一个元素。

答案 4 :(得分:0)

在开发人员需要知道前面的数组数量并相应地创建循环数量的意义上,上述建议的解决方案存在很大的问题。

以下C#解决方案会根据您实际拥有的数组数量和类型无关的动态地进行处理:

    static void Main(string[] args)
    {
        List<List<char>> masterListChar = new List<List<char>>();
        List<char> c1 = new List<char>() { 'a', 'b', 'c' };
        List<char> c2 = new List<char>() { 'd' };
        List<char> c3 = new List<char>() { 'e', 'f'};
        masterListChar.Add(c1);
        masterListChar.Add(c2);
        masterListChar.Add(c3);

        //PrintCombinations(masterListInt);
        PrintCombinations(masterListChar);
        Console.ReadKey();
    }

    public static void PrintCombinations<T>(List<List<T>> masterArray)
    {
        T[] combination = new T[masterArray.Count];
        WalkOnSubArray(combination, masterArray, 0);
    }

    public static void WalkOnSubArray<T>(T[] combination, List<List<T>> masterArray, int masterIndex)
    {
        List<T> currentArray = masterArray[masterIndex];
        for (int i = 0; i < currentArray.Count; ++i)
        {
            combination[masterIndex] = currentArray[i];

            if(masterIndex != masterArray.Count - 1)
                WalkOnSubArray(combination, masterArray, masterIndex + 1);
            else
                Console.WriteLine(String.Join(",", combination));
        }
    }