// Eric LippertのクイズをC#からJavaに移植
// http://b...content-available-to-author-only...n.com/b/ericlippert/archive/2012/02/24/a-simple-puzzle.aspx
// http://d...content-available-to-author-only...e.jp/matarillo/20120226/p1
import java.util.Random;
class Main {
/**
* 指定した範囲内の度数分布表を作成します。
* bucketsには1以上の値が与えられるものとします。
* maxにはminより大きな値が与えられるものとします。
* @param data 度数分布表を作成するデータ。
* @param buckets 作成する度数分布表の階級数(区間の数)。
* @param min 作成する度数分布表の最小値。この値以上のデータを集計し、この値未満のデータは無視します。
* @param max 作成する度数分布表の最大値。この値未満のデータを集計し、この値以上のデータは無視します。
* @return 累積度数の配列。長さはbuckets。
*/
private static int[] createHistogram(double[] data, int buckets, double min, double max) {
// 累積度数の配列を作成。
int[] results = new int[buckets];
// 階級幅の逆数を計算。
double multiplier = buckets / (max - min);
for (double datum : data)
{
// 幅で割って(=幅の逆数を掛けて)整数化。
int index = (int)((datum - min) * multiplier);
// 度数分布表の範囲に収まっていたら度数をカウントアップ。
if (0 <= index && index < buckets)
results[index] += 1;
}
return results;
}
public static void main
(String[] args
) { // 0以上100未満のランダムな数を100000個生成。
double[] data = new double[100000];
for (int i = 0; i < data.length; i++)
data[i] = 100.0 * r.nextDouble();
// 10以上20未満の区間を10個に分割した度数分布表を作成。
int[] hist = createHistogram(data, 10, 10.0, 20.0);
for (int i = 0; i < hist.length; i++)
System.
out.
println(i
+ ": " + hist
[i
]); }
}