计算一组数字的所有一次性组合

时间:2019-05-18 05:58:15

标签: java combinations

北卡罗莱纳州彩票提供几种抽奖游戏,其中两个是Pick 3和Pick4。您分别选择3或4位数字(介于0和9(含)之间),并且数字可以重复(例如9-9) -9是有效的组合)。在本示例中,我将使用Pick 3,因为它更易于使用,但我正在尝试使它成为通用的解决方案,以处理任意数量的数字。

选择3和选择4的功能之一是“ 1-OFF”,这意味着如果所抽取的号码中的至少一个比您的彩票号码高1或低1,您将赢得奖品。 / p>

例如,假设您玩了选择3,而您选择的数字是5-5-5。至少有一个数字必须是1-off才能赢(如果这样玩游戏,则5-5-5不会赢任何奖金)。获胜组合为:

1 Number    2 Numbers    3 Numbers
--------    ---------    ---------
4-5-5       4-4-5        4-4-4
5-4-5       5-4-4        6-6-6
5-5-4       4-5-4        4-4-6
6-5-5       6-6-5        4-6-6
5-6-5       5-6-6        4-6-4
5-5-6       6-5-6        6-4-4
            4-5-6        6-6-4
            6-5-4        6-4-6
            6-4-5
            5-6-4
            5-4-6
            4-6-5

(我想是所有的组合,但您知道了)。

我能想到的最“有效”的解决方案是拥有定义哪些数字以及如何更改的数组:

int[][] alterations = {
    // 1 digit
    {-1, 0, 0}, {0, -1, 0}, {0, 0, -1}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1},
    // 2 digits
    {-1, -1, 0}, ...
};

然后根据每个变更数组修改数字:

int[] numbers = {5, 5, 5};
for(int i = 0; i < alterations.length; i++) {
    int[] copy = Arrays.copyOf(numbers, numbers.length);
    for(int j = 0; j < alterations[i].length; j++) {
        // note: this logic does not account for the numbers 0 and 9:
        // 1 down from 0 translates to 9, and 1 up from 9 translates
        // to 0, but you get the gist of how this is supposed to work
        copy[j] += alterations[i][j];
    }
    printArray(copy);
}

...

private static void printArray(int[] a) {
    String x = "";
    for(int i : a)
        x += i + " ";

    System.out.println(x.trim());
}

但是我想知道是否有更好的方法可以做到这一点。有没有人遇到这样的事情并且有更好的主意?

1 个答案:

答案 0 :(得分:0)

听起来像您正在寻找回溯,因为构造alterations数组非常繁琐。在回溯算法中,您将构建候选项,应用更改,并检查结果组合是否有效,如果有效,则进行打印。我建议您阅读Steven Skiena的算法设计手册第7章,以获取有关回溯以及如何解决组合问题的一些背景信息。