1

以下のコードはうまく機能しますが、arraylist 内の整数の頻度を計算するメソッドを追加したいと考えています。例: 90-99 周波数: 3.... 80-89 周波数 6

最善の方法は何ですか?各変数をカウントする if ステートメントを作成する必要がありますか?

import java.io.*;
import java.lang.Math;
import java.util.*;
import java.text.DecimalFormat;

public class gradeSorter{

public static void main(String[] args) throws IOException {
{
DecimalFormat fmt = new DecimalFormat("0.000");
Scanner scanner = new Scanner(new File("grades.dat"));
double average;
double deviation;
double sum = 0;
int number = 0;
int newnumber = 0;
ArrayList<Integer> element = new ArrayList<Integer>();



while (scanner.hasNextInt())
{
element.add(scanner.nextInt());


}
for (int item : element){
        sum += item;
        System.out.println(item);
}

average = sum / element.size();

for (int i = 0; i < element.size(); i++)
{ 
newnumber += Math.pow((element.get(i) - average),2);

}


deviation = Math.sqrt(newnumber / (element.size()));




System.out.println("The average of these grades is : " + fmt.format(average));

System.out.println("The standard deviation of these grades is: " + fmt.format(deviation));  


}
}
}

----jGRASP exec: java gradeSorter

51
52
55
57
58
61
62
63
66
66
66
70
72
73
74
75
75
77
77
78
79
81
82
84
86
87
88
91
94
97
The average of these grades is : 73.233
The standard deviation of these grades is: 12.288

 ----jGRASP: operation complete.
4

4 に答える 4

4

期待する最大値と同じ大きさの整数配列を使用することから始めます。これは成績のように見えるので、取得する最大値は 100 であると想定できますか? もしそうなら、このようなコードはうまくいくでしょう。

int[] freqMap = new int[100];
for(int i=0;i<list.size();i++){
    int indexValue = list.get(i);
    freqMap[indexValue]++;
}

これを見て考える。したがって、グレード 3 になると、3 番目のインデックスで値を取得し、それをインクリメントします。これが 10 回発生すると、頻度配列の最初の4 つの値は次のようになります。

0 0 0 10

これは、配列のインデックスが 0 であるためです。ここで、インデックス 3 の頻度は 10 です。

編集:

構造を反復処理して、特定の範囲の周波数を取得します。これは些細なことです。ここでデモンストレーションします:

//the frequency aggregate for the range 80-90
int freqFor80To90 = 0;
for(int i=80; i<90; i++){
    freqFor80To90+=freqMap[i];
}
System.out.println("The frequency for 80-90 is "+freqFor80To90);

すべての数値の度数を格納すると、ヒープの点で若干コストがかかりますが、元のデータ セットを使用して範囲全体の度数を計算するよりも速く、多くの異なる範囲をクエリできます。

私が提供するソリューションはfreqMap、周波数範囲を照会するための構造 を提供します。それが、上記のコード サンプルで行っていることです。特定の範囲の頻度について構造体を照会します。

他のソリューションでは、範囲全体の周波数を保持する配列が提供されますが、これは完全に有効です。ただし、私のソリューションは、メモリを少し多く消費しますが、元のデータ セットをより細かく表示できるため、柔軟性が高くなります。

于 2013-08-07T20:45:58.253 に答える
1

これには整数の配列を使用できます。

int[] counters = new int[NUMBER_OF_BUCKETS];

while (scanner.hasNextInt()) {
  int n = scanner.nextInt();

  // Determine which bucket this int should be in:
  int bucket = determineBucket(n);

  //Count the integer in the appropriate bucket:
  counters[bucket]++;
}

このdetermineBucket()メソッドは数値を取り、それをカウントするバケットを決定します (バケットは単なる数値のセットです。この場合、バケットはたとえば 80 ~ 89 の範囲になります)。バケットをコーディングする最も簡単な方法は次のとおりです。

private static int determineBucket(int n) {
  if(80 <= n && n < 90) {
    return 0;
  } else if(90 <= n && n < 100) {
    return 1;
  } else if(...) {
    ...
  }
}

実際に数値を長さ 10 の範囲でグループ化する場合は、前のコードよりもうまく処理できますが、何をしようとしているのかわかりません。

于 2013-08-07T20:58:55.243 に答える
0

こちらをご覧ください

java.util.Collections has the method:
public static int frequency(Collection<?> c, Object o)

「指定されたオブジェクトに等しい、指定されたコレクション内の要素の数を返します。」

于 2013-08-07T21:15:51.117 に答える