【问题标题】:finding the sum of an arraylist but excluding the largest element [closed]查找数组列表的总和但不包括最大元素
【发布时间】:2021-01-06 14:46:38
【问题描述】:

我目前没有任何代码,但我需要返回一个数组列表的总和,但不包括最大元素,例如 3,4,5,10,我必须找到 3+ 的总和4+5 = 12。 我不知道如何编写代码以使其忽略最大的元素。 我目前有:

int sum = 0;
for(int i = 0; i < array.length; i++)
   sum = sum + array[i];
return sum;

【问题讨论】:

  • 遍历所有元素,对它们求和,同时检查最大值。迭代后从总和中减去最大值。
  • 首先需要找到最大的元素。有多种方式,一种是List升序排序。只是总和直到最后一个(最后一个是最大的)......

标签: java arrays arraylist sum


【解决方案1】:

我把这个问题看作是两个问题的简单组合:

  1. 对集合的所有元素求和
  2. 查找集合中最大的元素

您可能可以在一次迭代中对您的集合进行这两项操作:

  • 一个一个地求和元素,跟踪迄今为止最高的
  • 完成后,从总和中减去最高值

但是如cmets或answers中所述,还有许多其他方法;只要找到你认为最符合你逻辑的那个。

【讨论】:

    【解决方案2】:

    方法

    计算全和,然后计算最大元素并从全和中减去:

    List<Integer> values = List.of(3, 4, 5, 10);
    
    int sum = 0;
    for (int value : values) {
        sum += value;
    }
    
    int max = Collections.max(values);
    
    sum -= max;
    

    单次迭代

    您当然也可以一次性计算两者:

    List<Integer> values = List.of(3, 4, 5, 10);
    
    int sum = 0;
    int max = values.get(0);
    for (int value : values) {
        sum += value;
        if (value > max) {
            max = value;
        }
    }
    
    sum -= max;
    

    您还可以使用Stream API 来完成这项工作。 IntStream::summaryStatistics 一次性高效计算所需的一切:

    List<Integer> values = List.of(3, 4, 5, 10);
    
    IntSummaryStatistics stats = values.stream()
        .mapToInt(Integer::intValue)
        .summaryStatistics();
    
    int sum = stats.getSum() - stats.getMax();
    

    如果您有一个非常大的数据列表(> 10k)也非常有用,因为它提供了开箱即用的多线程。

    【讨论】:

    • 在流的情况下,显然“高效”更多的是代码简洁,而不是高效的代码。
    • @trilogy 在“一次迭代中的一切”的意义上高效
    【解决方案3】:
    import java.util.Arrays;
    public class Sum {
    
        public static void main(String[] args) 
        {
            // TODO Auto-generated method stub
            //arr size>1
            int arr[] = {3,5,4};
            int res[] = getSumAndMax(arr);
            
            int sum=0;
            Arrays.sort(arr);
            for(int i=0;i<arr.length-1;i++)
            {
                sum+=arr[i];
            }
            System.out.println("sum="+sum+" :max="+arr[arr.length-1]);
            System.out.println("sum="+res[0]+" :max="+res[1]);
        }
        public static int[] getSumAndMax(int[] arr)
        {
            int sum=0;
            int max=arr[0];
            for(int i=0;i<arr.length;i++)
            {
                sum+=arr[i];
                max = Math.max(max, arr[i]);
            }
            int out[] = {sum-max, max};
            return out;
        }
    }
    

    输出:

    sum=7 :max=5
    

    【讨论】:

    • 谢谢你的帮助,但是当我说 Arrays.sort(array); ,它说找不到任何名为“数组”的东西?
    • 必须先导入类,在java.lang中默认不是... import java.util.Arrays;
    • 非常感谢你的帮助,显然我不需要对数组进行排序,我只需要像你说的那样做 length-1。我喜欢这个网站
    • :) ,如果它没有排序,如果你有幸在最后一个位置有max,你会得到正确的答案......(排序在最后一个位置强制执行最大值)
    • 还要注意排序是耗时的,所以即使你得到了正确的答案,也许在最后计算总和和扣除的计算最大值会更快......
    【解决方案4】:

    试试这个。

    • 将总和和最大值设置为第一个值。
    • 然后迭代并计算总和并找到最大值。
    • 然后返回总和减去最大值。
    public static int findSum(int[] array) {
        if (array == null || array.length <2){
                return 0;
        }
        int max = array[0];
        int sum = max;
        for (int i = 1; i < array.length; i++) {
            int v = array[i];
            sum = sum + v;
            if (v > max) {
                max = v;
            }
        }
        return sum - max;
    }
    

    这是一种使用流的方法。

    • 流式传输整数
    • 反转位(补运算符~)
    • 对它们进行排序
    • 跳过第一个
    • 再次反转它们
    • 总和。

    位的反转是一个古老的技巧,因为IntStream sorted 方法不采用Comparator,所以它允许以等效的反向顺序对它们进行排序。然后跳过第一个最大的元素,将它们再次反转为原始值,然后将余数相加。

    public static int findSumStream(int[] array) {
        return array == null || array.length < 2 ? 0 : Arrays
                .stream(array)
                .map(i -> ~i)
                .sorted()
                .map(i->~i)
                .skip(1)
                .sum();
        
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-08
      • 1970-01-01
      • 2011-04-13
      • 1970-01-01
      • 2015-03-03
      • 1970-01-01
      • 2011-02-15
      相关资源
      最近更新 更多