求一个数组的平均数

问题描述 投票:0回答:2

给定任务

返回一个ints数组的 "居中 "平均值,除了忽略数组中最大和最小的值之外,我们说它是数值的平均值。如果最小值有多个副本,则只需忽略一个副本,同样,最大值也是如此。使用int除法来产生最终的平均值。你可以假设数组的长度为3以上。

centeredAverage([1, 2, 3, 4, 100]) → 3
centeredAverage([1, 1, 5, 5, 10, 8, 7]) → 5
centeredAverage([-10, -4, -2, -4, -2, 0]) → -3

我试着这样解决,但我小迷糊了。( catch ArrayIndexOutOfBounds exception):

public class Main {
    public static void main(String[] args) {
        int[] num = {1, 2, 3, 4, 100};
        int[] num1 = {1, 1, 5, 5, 10, 8, 7};
        int[] num2 = {-10, -4, -2, -4, -2, 0};
        System.out.println(centeredAverage(num));
        System.out.println(centeredAverage(num1));
        System.out.println(centeredAverage(num2));
    }

public static int centeredAverage(int[] nums) {
    int count = 0;
    int average = 0;
    //to search for max and min
    Arrays.sort(nums);
    //the last int of an array
    int end = nums[nums.length - 1];

    if (nums.length > 3) {
        //exclude minimum and maximum values
        for (int i = 1; i < end; i++) {
            if (!(nums[i] == nums[i + 1])) {
                count++;
                average = (nums[i] + nums[i + 1]) / count;
            }
        }
    }

    return average;
}

}

java arrays indexoutofboundsexception
2个回答
2
投票

我对你的问题展开一点评论。

你的解决方案是先对数组进行排序,然后跳过第一个和最后一个元素。这是很好的思路,但实现方式是错误的。

  • int end = nums[nums.length - 1]; 应该是... int end = nums.length - 1 看来你的意思是 end 为最后一个元素的索引
  • average = (nums[i] + nums[i + 1]) / count; 在循环中是错误的,因为你除法太频繁了。另外,这一行意味着你只添加了2个元素,然后除以 count. 这不是所有数组元素的平均数,除了最小的和最大的。
  • if(nums.length > 3) 是不必要的,因为 "你可以假设数组的长度是3或更多。" (如果你想使用这个条件,应该是if if(nums.length >= 3))
  • if (!(nums[i] == nums[i + 1])) 似乎是不对的,为什么你要跳过相同值的连续元素?你已经跳过了第一个和最后一个元素。

因此,你的代码应该是这样的。

int sum= 0;
//to search for max and min
Arrays.sort(nums);
//the last int of an array
int end = nums.length - 1;


//exclude minimum and maximum values which are at index 0 and "end"
for (int i = 1; i < end; i++) {               
   sum += nums[i];
}

int average = sum / nums.length - 2;

你的方法的一个缺点是你改变了被传递的数组 因为排序是一个就地操作。因此,如果这种情况不应该发生,你至少要复制一个数组。

你也根本不需要排序,只需要跟踪最小和最高的元素。

int smallest = Integer.MAX_VALUE;
int highest = Integer.MIN_VALUE;
int sum = 0;

for( int value : nums ) {
  sum += value;
  smallest = Math.min(smallest, value); //or use if(smallest > value) smallest = value;
  highest = Math.max(highest , value);  //or use if(highest < value) highest = value;
}

//smallest and highest are part of the sum so subtract them again
//since we ignore 2 elements we divide by length - 2
int average = (sum - smallest - highest) / (nums.length - 2);

1
投票

问题是你没有把长度为2的元素存储在end里 而是把长度为1的元素存储在end里.Declare end为.NET。

int end = nums.length - 2;

还有一点我注意到了。

if (nums. length >= 3)


0
投票

这应该可以。

public static int centeredAverage(int[] nums) {
//array to ArrayList
ArrayList<Integer> list = (ArrayList<Integer>)Arrays.stream(nums)     
                                .boxed()        
                                .collect(Collectors.toList());
//Sorting the ArrayList
Collections.sort(list);
//Removing first and last number
list.remove(0);
list.remove(list.size()-1);
//Returning the average
return (int) list.stream().mapToDouble(val -> val).average().orElse(0.0);
}
© www.soinside.com 2019 - 2024. All rights reserved.