【问题标题】:Calculating all 1-off combinations of a set of numbers计算一组数字的所有 1-off 组合
【发布时间】:2019-05-18 14:19:59
【问题描述】:

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

Pick 3 和 Pick 4 的其中一项功能是“1-OFF”,这意味着如果至少有一个开出的号码与您彩票上的号码相差 1 或 1,您就中奖了。

例如,假设您选择了 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());
}

但我想知道是否有更好的方法来做到这一点。有没有人遇到过这样的事情并有更好的想法?

【问题讨论】:

  • 这只是排列问题的有界版本。首先,对于每个数字,定义它可以是哪些数字 5 -&gt; {4,6} 用于 1-off;这显然是微不足道的。然后在结果上调用 Guava 的 Lists.cartesianProduct 之类的东西。如果您不想直接使用库,它是开源的... TL;DR 通用解决方案相当容易。

标签: java combinations


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2011-06-06
    • 2016-03-22
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 2013-10-06
    相关资源
    最近更新 更多