给定多个范围,请选择数字组合以达到给定的总和

夜间观察

给定范围,即(1-6),(3-6),(2-5)且要达到的总和为13。我应该能够从每个范围中选取数字,以使它们的总和为13。

示例输出:(3,5,5),(4,4,5)等

我正在尝试使用Java代码,但无法找出确切的实现。我需要生成此范围内的随机数,并检查这些数字的总和。这里存在无限循环的危险。你能帮我这个忙吗?

public static void main(String[] args) {
    int rangeStart1 = 1;
    int rangeEnd1 = 6;

    int rangeStart2 = 3;
    int rangeEnd2 = 6;

    int rangeStart3 = 2;
    int rangeEnd3 = 5;

    int sum = 13;
    int obtainedSum = 0;
    int randomNum1 = 0;
    int randomNum2 = 0;
    int randomNum3 = 0;
    while (obtainedSum != sum) {
        randomNum1 = (int)((Math.random() * (rangeEnd1 - rangeStart1)) + rangeStart1);
        randomNum2 = (int)((Math.random() * (rangeEnd2 - rangeStart2)) + rangeStart2);
        randomNum3 = (int)((Math.random() * (rangeEnd3 - rangeStart3)) + rangeStart3);
        obtainedSum = obtainedSum + randomNum1 + randomNum2 + randomNum3;
    }

    System.out.println(obtainedSum);
    System.out.println(randomNum1);
    System.out.println(randomNum2);
    System.out.println(randomNum3);
}
Glains

要从匹配给定总和的数字数组中找到数字的给定排列,可以使用蛮力算法找到可能的组合。为此,您可以在构建中使用深度优先搜索,方法是一次从每个数组中选择一个数字来构建路径。

对于示例输入{ [1-6], [3-6], [2-5] }(包括结尾),有效路径可能是1 > 3 > 2(每个数组的第一个数字)。使用递归,您可以评估所有可能的路径并找到与给定总和匹配的路径。

首先,一些定义使用Java记录语法以避免不必要的样板代码。如果需要,可以将类反向移植到较低的Java版本。

// input range to pick numbers from
public record Range(int startInclusive, int endInclusive) {

    @Override
    public String toString() {
        return "[" + startInclusive + "," + endInclusive + "]";
    }
}

// a node in the graph contains the picked number and the range
// that this number has been picked from
public record Node(Range range, int number) {
    
    @Override
    public String toString() {
        return number + " from " + range.toString();
    }
}

// connection of multiple nodes in a graph
public record Path(Collection<Node> nodes) {

    public static Path EMPTY = new Path(Collections.emptyList());

    // sum of all current nodes
    public int sum() {
        int sum = 0;
        for (Node s : nodes()) {
            sum += s.number;
        }
        return sum;
    }

    // copy of this path with the node added
    public Path with(Node node) {
        List<Node> nodes = new ArrayList<>(nodes());
        nodes.add(node);
        return new Path(nodes);
    }
}

现在,PathContext它存储递归期间使用的必要信息。

public class PathContext {

    private final Range[] ranges;
    private final int sum;

    // resulting paths that match the sum
    private final Collection<Path> paths = new ArrayList<>();
    // find all matches or just one (latter is faster)
    private final boolean skipAfterMatch = false;

    public PathContext(Collection<Range> ranges, int sum) {
        this.ranges = ranges.toArray(new Range[0]);
        this.sum = sum;
    }

    // if the path a valid solution, add it the the results
    public void validatePath(Path path) {
        if (path.sum() == sum) {
            paths.add(path);
        }
    }

    public Range[] getRanges() {
        return ranges;
    }

    public Collection<Path> getPaths() {
        return Collections.unmodifiableCollection(paths);
    }

    public int getSum() {
        return sum;
    }
    
    public boolean abortSearch() {
        return skipAfterMatch && !paths.isEmpty();
    }
}

现在最后,dfs(深度优先搜索):

public static void dfs(PathContext ctx, int rangeIdx, Path path) {
    // if we have no more ranges to pick from, validate if the sum matches
    if (rangeIdx >= ctx.getRanges().length) {
        ctx.validatePath(path);
    } else {
        // get the next range
        Range next = ctx.getRanges()[rangeIdx];

        // traverse trough all numbers in the range, end inclusive
        for (int i = next.startInclusive; i <= next.endInclusive; i++) {
            // generate a new node and path
            Node node = new Node(next, i);
            Path newPath = path.with(node);

            // recurse with the next range
            dfs(ctx, rangeIdx + 1, newPath);

            // check if the search can be aborted (if only one match is needed)
            if (ctx.abortSearch()) {
                break;
            }
        }
    }
}

然后,您可以dfs使用示例数据进行呼叫

public static void main(String[] args) {
    Range range1 = new Range(1, 6);
    Range range2 = new Range(3, 6);
    Range range3 = new Range(2, 5);
    List<Range> ranges = List.of(range1, range2, range3);

    PathContext ctx = new PathContext(ranges, 13);
    // start from index 0 (the first range)
    dfs(ctx, 0, Path.EMPTY);

    // output logging
    System.out.println("total sum: " + ctx.getSum());
    for (Path path : ctx.getPaths()) {

        for (Node node : path.nodes()) {
            System.out.println(node);
        }
        System.out.println();
    }
}

结果输出为:

total sum: 13
2 from [1,6]
6 from [3,6]
5 from [2,5]

3 from [1,6]
5 from [3,6]
5 from [2,5]

3 from [1,6]
6 from [3,6]
4 from [2,5]

4 from [1,6]
4 from [3,6]
5 from [2,5]

4 from [1,6]
5 from [3,6]
4 from [2,5]

4 from [1,6]
6 from [3,6]
3 from [2,5]

5 from [1,6]
3 from [3,6]
5 from [2,5]

5 from [1,6]
4 from [3,6]
4 from [2,5]

5 from [1,6]
5 from [3,6]
3 from [2,5]

5 from [1,6]
6 from [3,6]
2 from [2,5]

6 from [1,6]
3 from [3,6]
4 from [2,5]

6 from [1,6]
4 from [3,6]
3 from [2,5]

6 from [1,6]
5 from [3,6]
2 from [2,5]

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

获取给定数字的所有可能组合以达到给定总和

来自分类Dev

从mysql表的单列中找到等于给定总和的数字组合

来自分类Dev

数字组合的总和

来自分类Dev

多个数字组合

来自分类Dev

Python:给定前十个数字的范围,请从起始数字到结束数字进行迭代,并打印当前数字和先前数字的总和

来自分类Dev

查找具有给定总和的数字列表的所有组合

来自分类Dev

查找总和为给定数字的值组合的函数

来自分类Dev

给定范围内的最大数字因子总和

来自分类Dev

无法将给定对象格式化为数字组合框

来自分类Dev

用于检查给定数字的算法是给定数组中组合的总和

来自分类Dev

如何找出总和最接近给定数字的给定向量的最佳组合

来自分类Dev

给定总和的数字数组

来自分类Dev

查找给定数字的总和

来自分类Dev

使用给定的整数数组来达到目标总和的算法,从而避免了某些数字?

来自分类Dev

查找固定大小的所有唯一组合以达到给定的平均范围

来自分类Dev

PHP给定此数字递增的顺序,请计算所有可能的组合

来自分类Dev

按给定范围缩放数字

来自分类Dev

给定多个相同对象的列表,请根据字段值对它们进行分组和组合

来自分类Dev

如何计算总和等于给定值的所有数字数组元素组合?

来自分类Dev

对于给定的4个数字作为该函数的参数,我是否要找到所有数字组合的最大频率数字?

来自分类Dev

给定范围[a,b]中的奇数总和?

来自分类Dev

给定范围内所有数字的总和除以3和5,并以列表形式显示数字范围

来自分类Dev

查找月份的总和大于给定的数字

来自分类Dev

没有代表的可能总和达到给定数量

来自分类Dev

从给定范围中排除多个范围

来自分类Dev

生成一个numpy数组,其中所有数字的组合的总和小于给定的数字

来自分类Dev

从给定列表中选择最小数字以给出总和 N(允许重复)

来自分类Dev

给定数字的置换和组合

来自分类Dev

C 编程:给定范围的素数总和打印素数和总和

Related 相关文章

  1. 1

    获取给定数字的所有可能组合以达到给定总和

  2. 2

    从mysql表的单列中找到等于给定总和的数字组合

  3. 3

    数字组合的总和

  4. 4

    多个数字组合

  5. 5

    Python:给定前十个数字的范围,请从起始数字到结束数字进行迭代,并打印当前数字和先前数字的总和

  6. 6

    查找具有给定总和的数字列表的所有组合

  7. 7

    查找总和为给定数字的值组合的函数

  8. 8

    给定范围内的最大数字因子总和

  9. 9

    无法将给定对象格式化为数字组合框

  10. 10

    用于检查给定数字的算法是给定数组中组合的总和

  11. 11

    如何找出总和最接近给定数字的给定向量的最佳组合

  12. 12

    给定总和的数字数组

  13. 13

    查找给定数字的总和

  14. 14

    使用给定的整数数组来达到目标总和的算法,从而避免了某些数字?

  15. 15

    查找固定大小的所有唯一组合以达到给定的平均范围

  16. 16

    PHP给定此数字递增的顺序,请计算所有可能的组合

  17. 17

    按给定范围缩放数字

  18. 18

    给定多个相同对象的列表,请根据字段值对它们进行分组和组合

  19. 19

    如何计算总和等于给定值的所有数字数组元素组合?

  20. 20

    对于给定的4个数字作为该函数的参数,我是否要找到所有数字组合的最大频率数字?

  21. 21

    给定范围[a,b]中的奇数总和?

  22. 22

    给定范围内所有数字的总和除以3和5,并以列表形式显示数字范围

  23. 23

    查找月份的总和大于给定的数字

  24. 24

    没有代表的可能总和达到给定数量

  25. 25

    从给定范围中排除多个范围

  26. 26

    生成一个numpy数组,其中所有数字的组合的总和小于给定的数字

  27. 27

    从给定列表中选择最小数字以给出总和 N(允许重复)

  28. 28

    给定数字的置换和组合

  29. 29

    C 编程:给定范围的素数总和打印素数和总和

热门标签

归档