【问题标题】:C# OR Javascript Permutations of two arrays multiple timesC# OR Javascript 多次排列两个数组
【发布时间】:2014-01-29 10:55:29
【问题描述】:

几天来,我一直在工作,放弃然后重新解决这个问题。我已经研究了很多不同的方法,但是我要么无法正确实现它,要么它不适合我需要它做的事情。

基本上:我有两个数组,前缀和后缀

 prefix = { 0, 0, 3, 8, 8, 15} 
 suffix = { 0, 3, 2, 7, 7, 9, 12, 15 }

我需要:

  • 最少使用 3 个组合(2+1 或 1+2),最多使用 6 个 (3+3)。
  • 不要多次使用词缀(除非重复(即前缀有两个 8))

最终目标是看看哪些组合可以等于 X。

例如

X = 42
3 + 8 + 8 + 2 + 9 + 12 = 42
0 + 8 + 8 + 7 + 7 + 12 = 42
| Prefix |  | Suffix |

15 + 12 + 15 = 42
0 + 15 + 0 + 12 + 15 = 42

我已尝试研究 Permutations、IEnumerables、Concat 等,但找不到可以成功完成此操作的方法。

这些是我需要使用的“完整”数组。

public int[] Prefix = {0, 6, 6, 8, 8, 8, 8, 8, 8, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 16, 15, 15, 18, 18, 18, 18, 18, 18, 23 };
public int[] Suffix = {0, 3, 3, 9, 11, 11, 11, 17, 18, 18, 20, 25, 25, 27, 30, 30};

感谢任何帮助,如果我不清楚任何事情,我会尽可能澄清,谢谢!

编辑:还建议我运行它以等同于所有可能的结果并将其存储在哈希表中以在使用正确值时使用?不确定哪个效果最好。

【问题讨论】:

  • 这个任务没有内置的解决方案,你必须自己想出一个算法。
  • 就我个人而言,我建议使用暴力破解 X。
  • 你可以使用 4+2 或 5+1 词缀吗?
  • @Douglas 我相信每个词缀最多 3 个,最少 1 个,总计数最少 3 个。
  • 您打算排除重复项吗?例如,在您的样本中,Prefix 有六个 8 条目,12 有七个条目,Suffix 有三个 11 条目。如果您要求解 31 的总和,我认为仅基于这些条目就会产生 126 个重复的结果。

标签: c# arrays permutation concat


【解决方案1】:

抱歉,代码量这么大。虽然它不是印度的,但可以完成 100% 的工作:

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    static class Program
    {
        static void Main(string[] args)
        {
            Console.Write("Sum: ");

            var sum = int.Parse(Console.ReadLine());

            var prefix = new[] { 1, 2, 3, 4, 5, 6 };
            var suffix = new[] { 0, 3, 2, 7, 7, 9, 12, 15 };

            foreach (var item in Solution(prefix, suffix, 1, 3, sum))
            {
                Console.WriteLine("{0} = [ {1} ] + [ {2} ]", sum, string.Join(" + ", item.Item1.Select(T => prefix[T])), string.Join(" + ", item.Item2.Select(T => suffix[T])));
            }

            Console.WriteLine("Done here. Any key to close.");
            Console.ReadKey();
        }

        public static IEnumerable<Tuple<int[], int[]>> Solution(int[] one, int[] two, int minElementCount, int maxElementCount, int sum)
        {
            if (one.Length < minElementCount || two.Length < minElementCount)
            {
                throw new Exception("Nah.");
            }

            var cacheOne = new Dictionary<int, List<int[]>>();
            var cacheTwo = new Dictionary<int, List<int[]>>();
            var result = new List<Tuple<int[], int[]>>();

            for (int countInOne = minElementCount; countInOne <= Math.Min(one.Length, maxElementCount); countInOne++)
            {
                for (int countInTwo = minElementCount; countInTwo <= Math.Min(two.Length, maxElementCount); countInTwo++)
                {
                    List<int[]> permutationsOne;
                    List<int[]> permutationsTwo;

                    if (!cacheOne.TryGetValue(countInOne, out permutationsOne))
                    {
                        permutationsOne = cacheOne[countInOne] = PermutationsIndices(one, countInOne).ToList();
                    }

                    if (!cacheTwo.TryGetValue(countInTwo, out permutationsTwo))
                    {
                        permutationsTwo = cacheTwo[countInTwo] = PermutationsIndices(two, countInTwo).ToList();
                    }

                    foreach (var permutationOne in permutationsOne)
                    {
                        var sumOne = permutationOne.Select(T => one[T]).Sum();

                        if (sumOne <= sum)
                        {
                            foreach (var permutationTwo in permutationsTwo)
                            {
                                if ((sumOne + permutationTwo.Select(T => two[T]).Sum() == sum))
                                {
                                    yield return Tuple.Create(permutationOne, permutationTwo);
                                }
                            }
                        }
                    }
                }
            }
        }
        public static IEnumerable<int[]> PermutationsIndices<T>(this T[] e, int count)
        {
            if (count > e.Length)
            {
                throw new Exception("Nah.");
            }

            return TraverseArray(e, new Stack<int>(), 0, count - 1);
        }
        public static IEnumerable<int[]> TraverseArray<T>(T[] array, Stack<int> stack, int index, int iterations)
        {
            for (int i = index; i < array.Length - iterations; i++)
            {
                stack.Push(i);

                if (iterations == 0)
                {
                    yield return stack.Reverse().ToArray();
                }
                else
                {
                    foreach (int[] item in TraverseArray(array, stack, i + 1, iterations - 1))
                    {
                        yield return item;
                    }
                }

                stack.Pop();
            }
        }
    }
}

所以,你的任务的输出......

prefix = { 0, 0, 3, 8, 8, 15 }
suffix = { 0, 3, 2, 7, 7, 9, 12, 15 }

会是这样的:

Sum: 42
42 = [ 15 ] + [ 12 + 15 ]
42 = [ 8 ] + [ 7 + 12 + 15 ]
42 = [ 8 ] + [ 7 + 12 + 15 ]
42 = [ 8 ] + [ 7 + 12 + 15 ]
42 = [ 8 ] + [ 7 + 12 + 15 ]
42 = [ 15 ] + [ 0 + 12 + 15 ]
42 = [ 15 ] + [ 3 + 9 + 15 ]
42 = [ 0 + 15 ] + [ 12 + 15 ]
42 = [ 0 + 15 ] + [ 12 + 15 ]
42 = [ 3 + 15 ] + [ 9 + 15 ]
42 = [ 8 + 15 ] + [ 7 + 12 ]
42 = [ 8 + 15 ] + [ 7 + 12 ]
42 = [ 8 + 15 ] + [ 7 + 12 ]
42 = [ 8 + 15 ] + [ 7 + 12 ]
42 = [ 0 + 8 ] + [ 7 + 12 + 15 ]
42 = [ 0 + 8 ] + [ 7 + 12 + 15 ]
42 = [ 0 + 8 ] + [ 7 + 12 + 15 ]
42 = [ 0 + 8 ] + [ 7 + 12 + 15 ]
42 = [ 0 + 15 ] + [ 0 + 12 + 15 ]
42 = [ 0 + 15 ] + [ 3 + 9 + 15 ]
42 = [ 0 + 8 ] + [ 7 + 12 + 15 ]
42 = [ 0 + 8 ] + [ 7 + 12 + 15 ]
42 = [ 0 + 8 ] + [ 7 + 12 + 15 ]
42 = [ 0 + 8 ] + [ 7 + 12 + 15 ]
42 = [ 0 + 15 ] + [ 0 + 12 + 15 ]
42 = [ 0 + 15 ] + [ 3 + 9 + 15 ]
42 = [ 3 + 8 ] + [ 7 + 9 + 15 ]
42 = [ 3 + 8 ] + [ 7 + 9 + 15 ]
42 = [ 3 + 8 ] + [ 7 + 9 + 15 ]
42 = [ 3 + 8 ] + [ 7 + 9 + 15 ]
42 = [ 3 + 15 ] + [ 0 + 9 + 15 ]
42 = [ 3 + 15 ] + [ 3 + 9 + 12 ]
42 = [ 3 + 15 ] + [ 2 + 7 + 15 ]
42 = [ 3 + 15 ] + [ 2 + 7 + 15 ]
42 = [ 8 + 8 ] + [ 2 + 9 + 15 ]
42 = [ 8 + 8 ] + [ 7 + 7 + 12 ]
42 = [ 8 + 15 ] + [ 0 + 7 + 12 ]
42 = [ 8 + 15 ] + [ 0 + 7 + 12 ]
42 = [ 8 + 15 ] + [ 3 + 7 + 9 ]
42 = [ 8 + 15 ] + [ 3 + 7 + 9 ]
42 = [ 8 + 15 ] + [ 0 + 7 + 12 ]
42 = [ 8 + 15 ] + [ 0 + 7 + 12 ]
42 = [ 8 + 15 ] + [ 3 + 7 + 9 ]
42 = [ 8 + 15 ] + [ 3 + 7 + 9 ]
42 = [ 0 + 0 + 15 ] + [ 12 + 15 ]
42 = [ 0 + 3 + 15 ] + [ 9 + 15 ]
42 = [ 0 + 8 + 15 ] + [ 7 + 12 ]
42 = [ 0 + 8 + 15 ] + [ 7 + 12 ]
42 = [ 0 + 8 + 15 ] + [ 7 + 12 ]
42 = [ 0 + 8 + 15 ] + [ 7 + 12 ]
42 = [ 0 + 3 + 15 ] + [ 9 + 15 ]
42 = [ 0 + 8 + 15 ] + [ 7 + 12 ]
42 = [ 0 + 8 + 15 ] + [ 7 + 12 ]
42 = [ 0 + 8 + 15 ] + [ 7 + 12 ]
42 = [ 0 + 8 + 15 ] + [ 7 + 12 ]
42 = [ 3 + 8 + 15 ] + [ 7 + 9 ]
42 = [ 3 + 8 + 15 ] + [ 7 + 9 ]
42 = [ 3 + 8 + 15 ] + [ 7 + 9 ]
42 = [ 3 + 8 + 15 ] + [ 7 + 9 ]
42 = [ 8 + 8 + 15 ] + [ 2 + 9 ]
42 = [ 0 + 0 + 8 ] + [ 7 + 12 + 15 ]
42 = [ 0 + 0 + 8 ] + [ 7 + 12 + 15 ]
42 = [ 0 + 0 + 8 ] + [ 7 + 12 + 15 ]
42 = [ 0 + 0 + 8 ] + [ 7 + 12 + 15 ]
42 = [ 0 + 0 + 15 ] + [ 0 + 12 + 15 ]
42 = [ 0 + 0 + 15 ] + [ 3 + 9 + 15 ]
42 = [ 0 + 3 + 8 ] + [ 7 + 9 + 15 ]
42 = [ 0 + 3 + 8 ] + [ 7 + 9 + 15 ]
42 = [ 0 + 3 + 8 ] + [ 7 + 9 + 15 ]
42 = [ 0 + 3 + 8 ] + [ 7 + 9 + 15 ]
42 = [ 0 + 3 + 15 ] + [ 0 + 9 + 15 ]
42 = [ 0 + 3 + 15 ] + [ 3 + 9 + 12 ]
42 = [ 0 + 3 + 15 ] + [ 2 + 7 + 15 ]
42 = [ 0 + 3 + 15 ] + [ 2 + 7 + 15 ]
42 = [ 0 + 8 + 8 ] + [ 2 + 9 + 15 ]
42 = [ 0 + 8 + 8 ] + [ 7 + 7 + 12 ]
42 = [ 0 + 8 + 15 ] + [ 0 + 7 + 12 ]
42 = [ 0 + 8 + 15 ] + [ 0 + 7 + 12 ]
42 = [ 0 + 8 + 15 ] + [ 3 + 7 + 9 ]
42 = [ 0 + 8 + 15 ] + [ 3 + 7 + 9 ]
42 = [ 0 + 8 + 15 ] + [ 0 + 7 + 12 ]
42 = [ 0 + 8 + 15 ] + [ 0 + 7 + 12 ]
42 = [ 0 + 8 + 15 ] + [ 3 + 7 + 9 ]
42 = [ 0 + 8 + 15 ] + [ 3 + 7 + 9 ]
42 = [ 0 + 3 + 8 ] + [ 7 + 9 + 15 ]
42 = [ 0 + 3 + 8 ] + [ 7 + 9 + 15 ]
42 = [ 0 + 3 + 8 ] + [ 7 + 9 + 15 ]
42 = [ 0 + 3 + 8 ] + [ 7 + 9 + 15 ]
42 = [ 0 + 3 + 15 ] + [ 0 + 9 + 15 ]
42 = [ 0 + 3 + 15 ] + [ 3 + 9 + 12 ]
42 = [ 0 + 3 + 15 ] + [ 2 + 7 + 15 ]
42 = [ 0 + 3 + 15 ] + [ 2 + 7 + 15 ]
42 = [ 0 + 8 + 8 ] + [ 2 + 9 + 15 ]
42 = [ 0 + 8 + 8 ] + [ 7 + 7 + 12 ]
42 = [ 0 + 8 + 15 ] + [ 0 + 7 + 12 ]
42 = [ 0 + 8 + 15 ] + [ 0 + 7 + 12 ]
42 = [ 0 + 8 + 15 ] + [ 3 + 7 + 9 ]
42 = [ 0 + 8 + 15 ] + [ 3 + 7 + 9 ]
42 = [ 0 + 8 + 15 ] + [ 0 + 7 + 12 ]
42 = [ 0 + 8 + 15 ] + [ 0 + 7 + 12 ]
42 = [ 0 + 8 + 15 ] + [ 3 + 7 + 9 ]
42 = [ 0 + 8 + 15 ] + [ 3 + 7 + 9 ]
42 = [ 3 + 8 + 8 ] + [ 2 + 9 + 12 ]
42 = [ 3 + 8 + 8 ] + [ 7 + 7 + 9 ]
42 = [ 3 + 8 + 15 ] + [ 0 + 7 + 9 ]
42 = [ 3 + 8 + 15 ] + [ 0 + 7 + 9 ]
42 = [ 3 + 8 + 15 ] + [ 2 + 7 + 7 ]
42 = [ 3 + 8 + 15 ] + [ 0 + 7 + 9 ]
42 = [ 3 + 8 + 15 ] + [ 0 + 7 + 9 ]
42 = [ 3 + 8 + 15 ] + [ 2 + 7 + 7 ]
42 = [ 8 + 8 + 15 ] + [ 0 + 2 + 9 ]
Done here. Any key to close.

【讨论】:

  • 哇,感谢您回到这里!我将在今晚实施。
  • @Ministry 有什么进展吗?我想在这个主题中看到一个被接受的答案:p。
【解决方案2】:

采用“OR Javascript”选项...

  1. 创建一个关联数组,将前缀总数映射到生成该总数的前缀排列数组;然后填充它。
  2. 为后缀创建第二个相似的关联数组,但仅当 expected_result - total 位于前缀的关联数组中时,才使用后缀排列填充它。
  3. 输出有效的后缀和对应的前缀。

JSFIDDLE

// Inputs
var prefixes = [0, 6, 6, 8, 8, 8, 8, 8, 8, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 16, 15, 15, 18, 18, 18, 18, 18, 18, 23],
    suffixes = [0, 3, 3, 9, 11, 11, 11, 17, 18, 18, 20, 25, 25, 27, 30, 30],
    expected_result = 42;

// Associative Arrays
var prefixTotals = {},
    suffixTotals = {},
// Functions
    addTotal     = function( map, arr, other_map ){
        var t = 0, i = 0;
        for ( ; i < arr.length; ++i )
            t += arr[i].value;
        if (   ( other_map === undefined )
            || ( ( expected_result - t ) in other_map ) )
        {
            if ( !( t in map ) )
                map[t] = [];
            map[t].push( arr );
        }
    },
    calcPermutations     = function( affixes, map, other_map ) {
        var i = 0, j, k, l = affixes.length;
        for ( ; i < l; ++i )
        {
            addTotal( map, [ { index: i, value: affixes[i] } ], other_map );
            for ( j = i+1; j < l; ++j )
            {
                addTotal( map, [ { index: i, value: affixes[i] }, { index: j, value: affixes[j] } ], other_map );
                for ( k = j+1; k < l; ++k )
                {
                    addTotal( map, [ { index: i, value: affixes[i] }, { index: j, value: affixes[j] }, { index: k, value: affixes[k] } ], other_map );
                }
            }
        }
    },
    resultToString = function( affixes ){
        var s = [];
        for ( var i = 0; i < affixes.length; ++i )
            s.push( affixes[i].index + '=>' + affixes[i].value );
        return s.join(',');
    };

calcPermutations( prefixes, prefixTotals, undefined );
calcPermutations( suffixes, suffixTotals, prefixTotals );

var i,j,k,p,s,count = 0,html=[];
for ( i in suffixTotals )
{
    s = suffixTotals[i];
    p = prefixTotals[expected_result - i];
    for ( j = 0; j < p.length; ++j )
        for ( k = 0; k < s.length; ++k )
            html.push( 'Prefixes [' + resultToString( p[j] ) + '], Suffixes [' + resultToString( s[k] ) + ']' );
    count += p.length * s.length;
}
html.unshift( 'There were ' + count + ' valid permutations:' );

document.getElementById( 'out' ).innerHTML = html.join( '<br />' );

【讨论】:

  • 谢谢你-我会在睡一会后看到正确的视图,但看起来很有用。
【解决方案3】:

这是另一种强制解决方案的替代方案。我不得不在没有 LINQ 的情况下在 .NET 3 上编写它,所以我编写了自己的辅助方法来求和和连接这些值 - 因此需要大量代码。 EnumerateIndicesSum42 正在做所有的工作。您可以使用 LINQ 将其缩短很多,但我现在无法访问它,所以在我不小心引入任何错误之前,我会留给您清理它。

public static IEnumerable<int[]> EnumerateIndices(int[] values, int length)
{
    int[] result = new int[length]; 
    int size = (int)(Math.Pow(values.Length, length));
    for(int i = 0; i < size; ++i)
    {
        int tmp = i;
        for(int j = length - 1; j >= 0; --j)
        {
            result[j] = values[tmp % values.Length];
            tmp /= values.Length;               
        }

        yield return result;
    }       
}

public static int Sum(int[] values)
{
    // Just a helper method - if you can use LINQ replace by values.Sum()
    int result = 0, size = values.Length;       
    for(int i = 0; i < size; ++i)
    {
        result += values[i];
    }
    return result;
}

public static string Join(string separator, int[] values)
{
    // Just a helper method, if you can use LINQ replace by sth like string.Join(separator, values.ToArray<string>())
    string[] stringValues = new string[values.Length];  
    int size = values.Length;
    for(int i = 0; i < size; ++i)
    {
        stringValues[i] = values[i].ToString(); 
    }
    return string.Join(separator, stringValues);
}

public static void Sum42()
{
    int[] prefix = { 0, 0, 3, 8, 8, 15};
    int[] suffix = { 0, 3, 2, 7, 7, 9, 12, 15 };

    IEnumerable<int[]> prefixes = EnumerateIndices(prefix, 3);
    IEnumerable<int[]> suffixes = EnumerateIndices(suffix, 3);
    foreach(int[] p in prefixes) {
        foreach(int[] s in suffixes) {
            if(Sum(p) + Sum(s) == 42)
            {
                System.Console.WriteLine("{0} + {1} = 42", Join(" + ", p), Join(" + ", s)); 
            }
        }
    }
}

【讨论】:

  • 这看起来很完美,因为我希望能够以尽可能少的麻烦将其转换为 jQuery。我让它用我更大的阵列运行 42 分钟,几分钟后我回来时它仍在运行(30k+ 结果等于 42)。有没有办法阻止它以不同的顺序使用相同的值?可以不同地使用单独的,但如果它只是以不同的顺序执行:0(a) + 8(a) + 8(b) + 3(a) + (3) (b) 与 8 相同(a) + 0(a) + 8(b) + 3(a) + 3(b)。问候
  • 我也想不出使 EnumerateIndices 能够为 2 + 1、1 + 2、2 + 2、3 + 2、2 + 3 或 3 + 3 的解决方案。
  • 不知道重复问题。 EnumerateIndices 的第二个参数决定了它将从数组中获取多少值。
  • @Ministry:如果您确保每个数组中有两个零,它将自动包含您提到的那些情况,因为它也会尝试例如[0 + 0 +(其他前缀)] + [0 + 0 +(其他后缀)]等
  • 我决定只从数组中删除 0 值,我可以不用它们处理,这使它变得更加整洁。 EnumerateIndices(Suffix.Distinct().ToArray(), 2); Distinct 阻止它以不同的顺序重用相同的方法,但是我仍然不知道如何让它运行数组中所有接受的值(2 + 1 / 1 + 2 等)而不做一堆不同的foreach循环然后组合结果
【解决方案4】:

正如建议的那样,您当然可以嵌套循环,直到 Pascal 抱怨他的三角形,但如果您愿意,您也可以采用完全概率的方法 :)

毕竟,当执行蛮力解决方案时,a rogue alpha particle can flip an entire bit in the memory cells 无论如何都不会给出正确的答案。 (这是个玩笑。请不要对我投反对票,让宇宙射线击中 SO 服务器来处理。)

42 ==  
  prefix.OrderBy(x => random.Next(0,prefix.Length)).Take(random.Next(1,4)).Sum() 
  + 
  suffix.OrderBy(x => random.Next(0,suffix.Length)).Take(random.Next(1,4)).Sum();

这是一个演示,

using System;
using System.Linq;

namespace WhatWasTheQuestion {
    class Program {
        static readonly int[] prefix = { 0, 0, 3, 8, 8, 15 };
        static readonly int[] suffix = { 0, 3, 2, 7, 7, 9, 12, 15 };
        static readonly Random random = new Random();

        static bool generateAndCheckCandidate(int X) {
            var prefixCandidates = prefix.OrderBy(x => random.Next(0, prefix.Length)).Take(random.Next(1, 4)).ToList();
            var suffixCandidates = suffix.OrderBy(x => random.Next(0, suffix.Length)).Take(random.Next(1, 4)).ToList();
            if (prefixCandidates.Sum() + suffixCandidates.Sum() == X) {
                Console.WriteLine(X + " = "  + String.Join("+", prefixCandidates) + "+" + String.Join("+", suffixCandidates));
                return true;
            }
            return false;
        }

        static void Main(string[] args) {
            int maxAttempts = 10000;
            while (maxAttempts > 0 && !generateAndCheckCandidate(42))
            {
                --maxAttempts;
            }
        }
    }
}
// Output:
// 42 = 8+15+0+0+7+12+0

【讨论】:

  • 这行得通,但是满足 [2 + 1/ 1 + 2] 到 [ 3 + 3 ] 因为试图用这个数组等于 24 并不能解决 pre = {0, 6, 6 , 8} 和 suf = {0, 3, 3, 9} 其中 {6 + 6}+{3 + 9} 是可接受的结果。
  • 啊,但我说这是概率性的 :) 只是清除不合适长度的组合。例如,您可以在求和之前检查 suffixCandidates.Length 和 prefixCandidates.Length,或者您可以为其中一个生成一个长度并限制另一个的随机长度。
【解决方案5】:

这是一个使用 LINQ 的直观(尽管速度很慢)的解决方案:

int[] prefixes = { 0, 0, 3, 8, 8, 15 };
int[] suffixes = { 0, 3, 2, 7, 7, 9, 12, 15 };
int target = 42;

var results =
    from prefixLength in Enumerable.Range(1, 3)
    from suffixLength in Enumerable.Range(1, 3)
    where prefixLength + suffixLength >= 3
    from prefixPermutation in prefixes.GetPermutations(prefixLength)
    from suffixPermutation in suffixes.GetPermutations(suffixLength)
    let affixPermutation = prefixPermutation.Concat(suffixPermutation)
    where affixPermutation.Sum() == target
    select string.Join(" + ", affixPermutation);

var final = results.Distinct().ToArray();

我使用了一些基本的可枚举扩展:

public static partial class EnumerableExtensions
{
    public static IEnumerable<IEnumerable<T>> GetPermutations<T>(this IEnumerable<T> source, int length)
    {
        if (length == 0)
        {
            yield return Enumerable.Empty<T>();
            yield break;
        }

        int index = 0;
        foreach (T item in source)
        {
            IEnumerable<T> remainder = source.ExceptAt(index);
            IEnumerable<IEnumerable<T>> tails = GetPermutations(remainder, length - 1);
            foreach (IEnumerable<T> tail in tails)
                yield return tail.Prepend(item);
            index++;
        }
    }

    public static IEnumerable<T> ExceptAt<T>(this IEnumerable<T> source, int index)
    {
        return source.Take(index).Concat(source.Skip(index + 1));
    }

    public static IEnumerable<T> Prepend<T>(this IEnumerable<T> source, T first)
    {
        yield return first;
        foreach (T item in source)
            yield return item;
    }
}

【讨论】:

  • 我认为在确定排列时没有有效的解决方案——幸好 OP 没有在寻找组合!
  • @MichaelPerrenoud:从算法上讲,我同意。我的意思是我假设可以使用记忆化等技术改进实现。
  • 我明白你的意思了!
【解决方案6】:

这不是一个很好的解决方案,但它是一个有效的解决方案。 请注意我如何确保前缀和后缀在开头都有两个零,以便还包括您只使用该数组中的一个或两个值的情况。

    int[] prefix = { 0, 0, 3, 8, 8, 15};
    int[] suffix = { 0, 0, 3, 2, 7, 7, 9, 12, 15 };
    for(int p1 = 0; p1 < prefix.Length; p1++) {
        for(int p2 = 0; p2 < prefix.Length; p2++) {
            for(int p3 = 0; p3 < prefix.Length; p3++) {
                for(int s1 = 0; s1 < suffix.Length; s1++) {
                    for(int s2 = 0; s2 < suffix.Length; s2++) {
                        for(int s3 = 0; s3 < suffix.Length; s3++) {
                            if(prefix[p1] + prefix[p2] + prefix[p3] + suffix[s1] + suffix[s2] + suffix[s3] == 42)
                            {
                                System.Console.WriteLine(string.Format("{0} + {1} + {2} + {3} + {4} + {5} = 42", prefix[p1], prefix[p2], prefix[p3], suffix[s1], suffix[s2], suffix[s3] ));
                            }
                        }
                    }
                }
            }
        }

【讨论】:

  • Indian-Coderules!
  • 无限循环/过多。
  • @Ministry 可能不会无休止,但可能很长一段时间,因为您有 6 个嵌套的 for 循环!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-17
相关资源
最近更新 更多