需要找出并以锯齿状数组

时间:2016-10-06 11:32:37

标签: c# arrays jagged-arrays

使用C#,我需要找出英国国家彩票可能结果的所有组合(不包括奖金编号)。因此,我试图从数字1到59的唯一组合中获得六个数字的所有组合。每个组合由非重复数字组成,顺序无关。

所有有效组合的输出为:
 1 2 3 4 5 6
1 2 3 4 5 7
...依此如1 2 3 4 5 59
1 2 3 4 6 7
。 ..依据如下:54 54 55 56 57 58
53 54 55 56 57 59
54 55 56 57 58 59

由于有超过4500万个组合,我试图用一个锯齿状数组作为结果集来实现它,但是它会抛出内存异常。
所以我将它分成两个结果集,如下面的代码所示,但它仍然抛出相同的异常。

如何在两个结果集或一个结果集中获得所有组合结果集?
在下面的代码中,我使用了Jagged Arrays,但结果集可以是任何对象类型。
我显然需要在时间和空间复杂度方面具有最佳性能的算法。
感谢您的帮助。

 private void GetAllCombinationsForSixNumbers(out int[][] arrayOfAllCombinationsFirstSet, out int[][] arrayOfAllCombinationsSecondSet)
    {
        arrayOfAllCombinationsFirstSet = new int[25000000][];
        arrayOfAllCombinationsSecondSet = new int[25000000][];

        for (int eachArray = 0; eachArray < arrayOfAllCombinationsFirstSet.Length; eachArray++)
        {
            arrayOfAllCombinationsFirstSet[eachArray] = new int[6];
            arrayOfAllCombinationsSecondSet[eachArray] = new int[6];
        }
        int arrayCurrentRowIndex = 0, arrayCurrentRowIndexForSecondArray = 0;

        for (int firstNumber = 1; firstNumber < 59; firstNumber++)
        {
            for (int secondNumber = firstNumber + 1; secondNumber <= 59; secondNumber++)
            {
                for (int thirdNumber = secondNumber + 1; thirdNumber <= 59; thirdNumber++)
                {
                    for (int fourthNumber = thirdNumber + 1; fourthNumber <= 59; fourthNumber++)
                    {
                        for (int fifthNumber = fourthNumber + 1; fifthNumber <= 59; fifthNumber++)
                        {
                            for (int sixthNumber = fifthNumber + 1; sixthNumber <= 59; sixthNumber++)
                            {
                                if (arrayCurrentRowIndex < arrayOfAllCombinationsFirstSet.Length)
                                {
                                    arrayOfAllCombinationsFirstSet[arrayCurrentRowIndex][0] = firstNumber;
                                    arrayOfAllCombinationsFirstSet[arrayCurrentRowIndex][1] = secondNumber;
                                    arrayOfAllCombinationsFirstSet[arrayCurrentRowIndex][2] = thirdNumber;
                                    arrayOfAllCombinationsFirstSet[arrayCurrentRowIndex][3] = fourthNumber;
                                    arrayOfAllCombinationsFirstSet[arrayCurrentRowIndex][4] = fifthNumber;
                                    arrayOfAllCombinationsFirstSet[arrayCurrentRowIndex][5] = sixthNumber;
                                    arrayCurrentRowIndex++;
                                }
                                else
                                {
                                    arrayOfAllCombinationsSecondSet[arrayCurrentRowIndexForSecondArray][0] = firstNumber;
                                    arrayOfAllCombinationsSecondSet[arrayCurrentRowIndexForSecondArray][1] = secondNumber;
                                    arrayOfAllCombinationsSecondSet[arrayCurrentRowIndexForSecondArray][2] = thirdNumber;
                                    arrayOfAllCombinationsSecondSet[arrayCurrentRowIndexForSecondArray][3] = fourthNumber;
                                    arrayOfAllCombinationsSecondSet[arrayCurrentRowIndexForSecondArray][4] = fifthNumber;
                                    arrayOfAllCombinationsSecondSet[arrayCurrentRowIndexForSecondArray][5] = sixthNumber;
                                    arrayCurrentRowIndexForSecondArray++;
                                }
                            }
                        }
                    }
                }
            }
        }         

    }

2 个答案:

答案 0 :(得分:2)

因此,您在数字系统中生成从[1 2 3 4 5 6]到[54 55 56 57 58 59]的值,基数为59,不包括零。 排除的零根本不是问题,你只需要向左移动,所以1变为0,2变为1,依此类推。所以你的边界变成这样:

[0 1 2 3 4 5]
....
[53 54 55 56 57 58]

之后,您可以创建将索引与基数10(十进制)映射到数组中的精确值的函数。

为此,您需要将索引与基数10转换为数字系统中的索引,基数为59.例如,我想从索引123的数组中获取值:

123 => [2 5]

使用起始索引在此数字系统中添加:

[0 1 2 3 4 5] + [2 5] = [0 1 2 3 6 10]

然后你只需向后移动它:

[1 2 3 4 7 11]

至于重复 - 只需过滤它。它的总体影响可能会很小。

答案 1 :(得分:0)

如果您确实需要这么多阵列(我真的不知道您为什么会这样做),那么除了int之外,您可以将所有byte更改为int eachArray,因为{{1}在CLR中需要最少的内存。此外,您可以将数组大小从byte减少到25000000

在我的测试中,如果你在一个空的控制台应用程序中创建它们,那么字节数组(你的其他未改变的代码)几乎不适合32位进程的可用内存。

如果它们仍然不适合您特定应用程序的内存,那么您必须将进程更改为64位(系统中有足够的可用RAM)。

但是,只是在当前情况下,只需要懒得和动态生成组合就好得多。