下面的代码工作正常,但我想添加一个方法来计算arraylist中整数的频率。例如:90-99 freq:3 .... 80-89 freq 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.
答案 0 :(得分: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
,用于查询频率范围。这就是我在上面的代码示例中所做的事情;查询特定范围频率的结构。
其他解决方案为您提供保持整个范围频率的阵列,这是完全有效的。但是,我的解决方案提供了更大的灵活性,因为它以更多的内存为代价提供了原始数据集的更精细视图。
答案 1 :(得分:1)
创建一个大小为10
的数组,其中包含每个范围中数字的频率:
int[] rangeFrequency = new int[10];
现在,对于范围内的所有数字 - [0,9]
,频率将在索引0中。对于范围[10, 19]
,频率将在索引1中,依此类推......
现在重点是如何获得所有这些范围的索引?方法如下:
<强>伪代码:强>
for each element in list
bucket = element / 10 // For range [0-9], this will give index = 0
// For range [10-19], this will give index = 1
rangeFrequence[bucket] += 1;
<强>代码:强>
int[] rangeFrequency = new int[10];
for (int elem: element) {
int bucket = elem / 10;
rangeFrequency[bucket] += 1;
}
// Print frequency from array:
for (int i = 0; i < rangeFrequency.length; ++i) {
System.out.print("Frequency in range : [" + i * 10 + ", " +
(i * 10 + 9) + ") --> ");
System.out.println(rangeFrequency[i]);
}
请注意,当grade < 0 || grade >= 100
,上述程序崩溃时,您需要处理 ArrayIndexOutOfBounds 。
答案 2 :(得分: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的范围内对数字进行分组,那么你可以比以前的代码做得更好,但我不能确定你要做什么。
答案 3 :(得分:0)
请参阅here
java.util.Collections has the method:
public static int frequency(Collection<?> c, Object o)
“返回指定集合中等于指定对象的元素数。”