如何使用循环找到与平均值最远的值?

时间:2017-05-03 13:32:42

标签: java loops

我正在尝试编写一个java程序,它从文本文件中读取数据,并根据给定的问题计算一些不同的平均值。

我给出的文件包含13个不同的十进制数字(在文件的第一行显示)

我试图找到:

  • 所有值的平均值。 (称此平均值为A1。)
  • 所有值的平均值,不包括距离A1最远的值。 (将此平均值称为A2。)
  • 所有值的平均值,不包括距离A2最远的两个值。 (将此平均值称为A3。)
  • 所有值的平均值,不包括距离A3最远的三个值。
  • 。 。
  • 所有值的平均值,不包括距离A(N-1)最远的N-1。 (这是一个元素的平均值;换句话说,就是该元素本身的值。)

这是我的代码。我设法获得A1,A2,A3和A4,但我不知道接下来该做什么。 (我觉得我应该使用循环,但我不知道如何)

import java.io.File;
import java.io.IOException;
import java.util.Scanner;

public class FurtherTweeking
{ public static void main ( String[] args ) throws IOException {

//Read the given file
Scanner scan = new Scanner(new File("C:\\Users\\IdeaProjects\\src\\ArrayList.txt"));
//The first line of the file gives the number of values that follow
int Num = scan.nextInt();

//Reads the data into an array
Double[] InputData = new Double[Num];
double ArraySum = 0;
int i = 0;
do {
    InputData[i] = scan.nextDouble();
    i = i+1;
}
while(scan.hasNextLine());
scan.close();






//Calculate the sum of all input data
for (int j = 0; j < Num; j++ ) {
    if (InputData[j] != null) {
        ArraySum = ArraySum + InputData[j];
    }
}
//Calculate the average of the original input data
double A1 = ArraySum/(Num);
System.out.println("A1: " + A1);





//Scan through the array to find the value that is farthest (in either direction) from the average
double Farthest = InputData[0];
for (int j = 0; j < Num; j++ ) {
    if (InputData[j] != null) {
        if ( Math.abs ( A1 - InputData[j] ) > Math.abs ( A1 - Farthest ) )
            Farthest = InputData[j];
    }
}
for (int u = 0; u < Num; u++){
    if (InputData[u] == Farthest ){
        InputData[u] = null;
    }
}
System.out.println("Most distant value: " + Farthest);
//compute an average that does not include the most distant value. Print the new average.
double A2 = ( ArraySum - Farthest )/( Num - 1.0 );
System.out.println("A2: " + A2 );






double Farthest2 = InputData[0];
double Farthest3 = InputData[0];
for (int j = 0; j < Num; j++ ) {
    if (InputData[j] != null) {
        if ( Math.abs ( A2 - InputData[j] ) > Math.abs ( A2 - Farthest2 ) ) {
            Farthest3 = Farthest2;
            Farthest2 = InputData[j];
        }
        else if ( Math.abs ( A2 - InputData[j] ) > Math.abs ( A2 - Farthest3 ) ) {
            Farthest3 = InputData[j];
        }
    }
}
System.out.println("Most distant value: " + Farthest2 + ", " + Farthest3);
//compute an average that does not include the most distant value. Print the new average.
double A3 = ( ArraySum - Farthest - Farthest2 - Farthest3 )/( Num - 3.0 );
System.out.println("A3: " + A3 );





double Farthest4 = InputData[0];
double Farthest5 = InputData[0];
double Farthest6 = InputData[0];
for (int j = 0; j < Num; j++ ) {
    if (InputData[j] != null) {
        if ( Math.abs ( A3 - InputData[j] ) > Math.abs ( A3 - Farthest4 ) ) {
            Farthest6 = Farthest5;
            Farthest5 = Farthest4;
            Farthest4 = InputData[j];
        }
        else if ( Math.abs ( A3 - InputData[j] ) > Math.abs ( A3 - Farthest5 ) ) {
            Farthest6 = Farthest5;
            Farthest5 = InputData[j];
        }
        else if ( Math.abs ( A3 - InputData[j] ) > Math.abs ( A3 - Farthest6 ) ) {
            Farthest6 = InputData[j];
        }
    }
}
System.out.println("Most distant value: " + Farthest4 + ", " + Farthest5+ ", " + Farthest6);
//compute an average that does not include the most distant value. Print the new average.
double A4 = ( ArraySum - Farthest - Farthest2 - Farthest3 -Farthest4 - Farthest5 - Farthest6 )/( Num - 6.0 );
System.out.println("A4: " + A4 );
}
}

谢谢你的时间!!!

3 个答案:

答案 0 :(得分:1)

我会创建两个util函数:

/** Returns the average of a collection of double */
private static Double average(Collection<Double> coll) {
  return coll.stream().collect(Collectors.averagingDouble(Double::doubleValue));
}

/** Returns the first, most distant element of a collection from a defined value. */
private static Double furthest(Collection<Double> coll, Double value) {
  return coll.stream()
    .max((d1, d2) -> Double.compare(Math.abs(d1-value), Math.abs(d2-value)))
    .orElse(null);
}

并像这样使用它们:

Double[] array = new Double[]{1d,2d,3d,4d,5d,6d,7d,8d,9d};
List<Double> list = new ArrayList<>(Arrays.asList(array));

for (int i = 0; i < array.length; i++) {

  double average = average(list);
  System.out.printf("Average A%d: %.1f, List: %s\n", (i+1), average, input);

  double furthest = furthest(list, average);
  list.remove(furthest);
}

输出:

Average A1: 5.0, List: [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
Average A2: 5.5, List: [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
Average A3: 6.0, List: [3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
Average A4: 6.5, List: [4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
Average A5: 7.0, List: [5.0, 6.0, 7.0, 8.0, 9.0]
Average A6: 7.5, List: [6.0, 7.0, 8.0, 9.0]
Average A7: 8.0, List: [7.0, 8.0, 9.0]
Average A8: 8.5, List: [8.0, 9.0]
Average A9: 9.0, List: [9.0]

答案 1 :(得分:0)

我认为你写的任务要复杂得多(如果我理解你的任务正确的话)。想象一下,如果你没有13个数字,但即便像一千个,那么呢?我给你写了一些东西,可能不是你需要的东西(但我不确定,它可能是),但是它会向你展示这样的事情是如何完成的,我左边打印代码,这样你就可以看到实际发生了什么,我建议你运行这段代码。

public static void main(String arg[]) {
  List<Double> list = new ArrayList<>(Arrays.asList(3.2, 4.8, 5.2, 1.2, 9.8, 0.5, 6.6, 2.2, 7.1));

  while(list.size() > 0) {
    System.out.println("Next iteration, list: " + list);
    DoubleSummaryStatistics stats = list.stream().collect(DoubleSummaryStatistics::new,
        DoubleSummaryStatistics::accept, DoubleSummaryStatistics::combine);
    double average = stats.getAverage();
    double min = stats.getMin();
    double max = stats.getMax();
    double furthest = Math.abs(average - max) > Math.abs(average - min) ? max : min;
    System.out.println("Average: " + average);
    System.out.println("Minimum: " + min);
    System.out.println("Maximum: " + max);
    System.out.println("Furthest away: " + furthest);
    list.remove(furthest);
  }
}

我们在这里做的是计算列表中的DoubleSummaryStatistics(它计算我们的平均值,最大值,最小值等,查看链接)然后我们只需要我们需要的值。最远的值可能是最大值或最小值,因此我们需要自己找到这个值。然后我们从列表中删除该值并重新执行,直到列表中没有元素。

答案 2 :(得分:0)

对于大型列表,使用集合会很慢,可能是o(n * 2)。 相反,n值的有效实现将是......

1. Put all values in a double[] array
2. Sort array with Arrays.sort(double[n]).  Time is o(n*log(n))
3. Calculate sum of array
4. Setup markers a=0 and b=n-1
5. Now each smaller average requires clipping at start or end of list, which corresponds to incrementing a or decrementing b

使用上述算法,所有平均值都可以在o(n log(n))+ o(n)= o(n log(n))中找到。更快,也使用更少的内存。

以下是快速解决方案的代码:

import java.util.Arrays;

class Main {

    public static void main(String[] args) {
        double[] arD = {3.2, 4.8, 5.2, 1.2, 9.8, 0.5, 6.6, 2.2, 7.1};
        Arrays.sort(arD);

        double sum = 0;
        for (double d : arD)
            sum += d;

        int n = arD.length;
        int a = 0, b = n - 1;
        while (a <= b) {
            int m = b - a + 1;
            double avg = sum / m;
            System.out.println("Average of  range=[" + a + "," + b + "] is " + avg);
            if (Math.abs(arD[a] - avg) > Math.abs(arD[b] - avg))
                sum -= arD[a++];
            else
                sum -= arD[b--];
        }

    }
}