You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java数字可能的求和计算中去除重复值?

嘿,这个问题我之前也碰到过!因为你的输入列表里有重复的数值(比如两个0.05),递归遍历的时候会产生完全一样的求和路径,自然就会出现重复的结果。下面给你几个实用的解决思路:

方案1:用Set替代List存储结果(最直接)

最省心的办法就是把存储结果的容器从ArrayList换成HashSet——Set的核心特性就是自动去重,完全不需要自己写额外的判断逻辑。

修改你的代码非常简单:

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

public class Testing {
    public static void main(String[] args) {
        ArrayList<Double> valid = new ArrayList<Double>();
        Set<Double> result = new HashSet<Double>(); // 替换成Set
        valid.add(0.05);
        valid.add(0.05);
        valid.add(0.1);
        getSum(valid, result, 0, 0);
        System.out.println(result); // 输出就是去重后的结果
        
        // 如果后续需要转回ArrayList:
        // ArrayList<Double> uniqueResult = new ArrayList<>(result);
    }

    public static void getSum(ArrayList<Double> valid, Set<Double> result, int start, double sum) {
        if (valid.size() == start) {
            result.add(sum);
            return;
        }
        // 选择当前元素加入求和
        getSum(valid, result, start + 1, sum + valid.get(start));
        // 不选择当前元素加入求和
        getSum(valid, result, start + 1, sum);
    }
}

⚠️ 小提醒:因为你用的是Double类型,浮点数的精度问题可能会导致一些你认为相同的数值被误判为不同(比如0.1+0.05和0.05+0.1理论上相等,但浮点数计算可能产生微小差异)。如果你的场景对精度要求高,建议用BigDecimal代替Double。

方案2:递归过程中跳过重复元素(从源头避免重复)

如果你的输入数据量比较大,用Set去重可能会有性能开销,那可以在递归阶段就跳过重复元素,从根源上不生成重复的求和结果。具体步骤是:

  1. 先对输入的valid列表排序;
  2. 在递归时,判断当前元素是否和前一个元素相同,如果相同且前一个元素没有被选中,就跳过当前分支,避免重复计算。

修改后的代码示例:

import java.util.ArrayList;
import java.util.Collections;

public class Testing {
    public static void main(String[] args) {
        ArrayList<Double> valid = new ArrayList<Double>();
        ArrayList<Double> result = new ArrayList<Double>();
        valid.add(0.05);
        valid.add(0.05);
        valid.add(0.1);
        Collections.sort(valid); // 先排序,让重复元素相邻
        getSum(valid, result, 0, 0, false);
        System.out.println(result);
    }

    // 新增prevSelected参数:标记前一个元素是否被选中,用来判断是否跳过重复分支
    public static void getSum(ArrayList<Double> valid, ArrayList<Double> result, int start, double sum, boolean prevSelected) {
        if (valid.size() == start) {
            result.add(sum);
            return;
        }

        // 情况1:不选择当前元素
        // 如果当前元素和前一个相同,且前一个元素没被选中,说明这个分支已经被前一个重复元素处理过了,直接跳过
        if (!(start > 0 && valid.get(start).equals(valid.get(start-1)) && !prevSelected)) {
            getSum(valid, result, start + 1, sum, false);
        }

        // 情况2:选择当前元素
        getSum(valid, result, start + 1, sum + valid.get(start), true);
    }
}

这个方案的优势是不会生成冗余的重复结果,节省了后续去重的开销,适合数据量较大的场景。

内容的提问来源于stack exchange,提问作者Raymo111

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:50:42