2017-05-03 8 views
0

私は、テキストファイルからデータを読み込み、与えられた質問に従っていくつかの異なる平均を計算するJavaプログラムを作成しようとしています。ループを使用して平均値から最も離れた値を見つけるにはどうすればよいですか?

  • すべての値の平均:

    私は与えられていたファイルは、私が見つけるためにしようとしている(ファイルの1行目に示されている)13の異なる進数

    が含まれています。

  • A1から最も遠いものを除く、すべての値の平均値。
  • A2から最も離れた2つを除く、すべての値の平均値。
  • A3から最も遠い3つを除くすべての値の平均値。
  • 。 。 。
  • A(N-1)から最も離れたN-1を除く、すべての値の平均。 (これはただ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); 
} 
} 

感謝を!

+0

注:ここでは

は高速なソリューションのためのコードです。どの段階でも、最小値と最大値が平均値から等距離にある場合は、どれを削除しますか?あなたの選択は、その後のすべての平均に影響します。 –

答えて

1

私は2つの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] 
+0

Double.compare()の絶対的な違いは? – DAle

+0

あなたは正しいです、ありがとう。今では最初の一番遠いものが 'furthest()'によって返されます – Oneiros

+0

そして、それほど奇妙な出力を得るためにいくつかの他の数値を選ぶほうがいいでしょうか? – DAle

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を数える(それは私たちのために、平均、最大、最小などをカウントし、リンクを見て)、その後、私達はちょうど私たちに必要な値をとるれます。一番遠い値は最大値か最小値のどちらかになりますので、この値を自分で見つける必要があります。次に、リストからその値を削除し、リストに要素がなくなるまで、それをすべてやり直します。

+0

ありがとうございます!しかし、配列をリストに変更する目的が何であるか分かりません。 (これは愚かな質問であれば申し訳ありません) –

+0

私はこの例のリストを扱う方が好きです。 'ArrayList'は名前が示すように内部的に配列を使いますが、多くの便利なメソッドが詰まっています。他の多くのもの、Googleの 'Javaのリスト対配列 'またはそれのような何か、あなたはたくさん見つける:)この例では、私たちはそれから一番の項目を削除する必要があるので、リストを使用して、そう簡単ではない配列を使用すると、他の変更が必要になります。 – Shadov

0

o(n * 2)。 代わりに、n値のための効率的な実装が...全平均は、N、O(N ログ(N))+ O(N)= O(に見出すことができる上記のアルゴリズムにより

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 

あろう 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--]; 
     } 

    } 
} 
関連する問題