我创建了一个计算平均值,中位数和方差的程序。该程序最多可接受500个输入。当有500个输入(我的数组的最大大小)时,我的所有方法都能正常工作。当输入较少时,只有“均值”计算器才有效。这是整个计划:
public class StatsPackage{
static int i = 0, arrayLength;
static double sum = 0, mean, median, sumOfSquares, variance, stdDev;
static double calcMean (int inputs[], int count) throws IOException{
for (i = 0; i < count; i++){
sum += inputs[i];
}
mean = (sum/count);
return mean;
}
static double calcMedian (int inputs[], int count){
Arrays.sort(inputs);
if (count % 2 == 0){
median = ((inputs[(count/2)] + inputs[(count/2)- 1])/2) ;
}
if (count % 2 != 0){
median = inputs[(count-1)/2];
}
return median;
}
static double calcVariance (int inputs[], int count){
sum = 0;
for (i = 0; i < count; i++){
sumOfSquares += (inputs[i]*inputs[i]);
}
for (i = 0; i < count; i++){
sum = sum + inputs[i];
}
variance = ((sumOfSquares/count) - (sum * sum)/(count * count));
return variance;
}
static double calcStdDev (double varianceInput){
stdDev = Math.sqrt(variance);
return stdDev;
}
public static void main(String[] args) throws IOException {
NumberFormat nf = new DecimalFormat("0.##");
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
BufferedReader stdin = new BufferedReader (new InputStreamReader (System.in));
String str = "test";
int inputs[] = new int [500];
int counter = 0;
int i = 0;
while ((str = stdin.readLine()) != null && i < 500) {
inputs[i] = Integer.parseInt(str);
i++;
counter++;
}
System.out.println("Mean: " + nf.format(StatsPackage.calcMean(inputs, counter)));
System.out.println("Median: " + nf.format(StatsPackage.calcMedian(inputs, counter)));
System.out.println("Variance: " + nf.format(StatsPackage.calcVariance(inputs, counter)));
System.out.println("Standard Deviation: " + nf.format(StatsPackage.calcStdDev(variance)));
}
}
以下是输入10个随机数时的示例输出:
平均值:47.90 中位数:0.00 差异:0.00 标准偏差:0.00
输入500个数字时,这是相同的代码(我的数组的最大大小):
平均值:47.27 中位数:47.00 差异:856.71 标准差:29.27
这些输出是一致的。我输入了10个数字,我只能得到平均值。我输入了500个数字,我得到了所有这些数字。我正在针对另一个测试程序运行这个程序,而不是在eclipse中输入我自己的数字。测试程序是我的导师,我相信他的程序工作正常。
有人可以帮忙吗?我要把头发撕掉了。
答案 0 :(得分:3)
问题是您正在初始化大小为500的数组,但之后不使用所有500个索引。这意味着你有一个像:
这样的数组[2,5,3,7,8,2,......,0,0,0,0,0,0,0,0,0,0,0,0]
因此,您的代码将使用所有0
来计算中位数和标准偏差。你应该使用的是ArrayList
。
如果你不能使用ArrayList
,那么你必须做更多的工作。
ArrayList
您的while ((str = stdin.readLine()) != null && i < 500) {
inputs[i] = Integer.parseInt(str);
i++;
counter++;
}
变量已包含您需要的信息。现在,在将此数组传递给mean / median / stddev方法之前,需要减小数组的大小。最简单的方法是使用提供给所有数组的现有方法,称为counter
:CopyOf() method for Arrays
CopyOf()
现在在方法调用中用新的int[] newArray = Arrays.copyOf(inputs, counter);
替换旧的input
数组:
newArray
答案 1 :(得分:2)
我假设您使用随机正整数对其进行了测试,因为这些结果似乎就是这种情况。
当您输入n
(其中n
小于500)正整数时,您的数组大多数为0。
当Array.sort
对数组进行就地排序时,calcMedian
修改传递的实际数组,将所有这些0放在前面,中位数自然为0,就像它们的所有n
一样在后面。
然后calcVariance
计算第一个n
0的方差,因为数组先前已排序。
最后,calcStdDev
指的是calcVariance
的结果。
要解决此问题,您应该考虑:
答案 2 :(得分:0)
您计算方差的方法是错误的。看一下方差的定义(例如在wikipedia上)。
import java.util.Arrays;
public class StatisticalCalculations {
public static void main(String[] args) {
double[] array = { 49, 66, 73, 56, 3, 39, 33, 77, 54, 29 };
double mean = getMean(array);
double var = getVariance(array);
double med = getMedian(array);
System.out.println(Arrays.toString(array));
System.out.println("mean : " + mean);
System.out.println("variance : " + var);
System.out.println("median : " + med);
}
private static double getMean(double[] array) {
int l = array.length;
double sum = 0;
for (int i = 0; i < l; i++)
sum += array[i];
return sum / l;
}
private static double getVariance(double[] array) {
double mean = getMean(array);
int l = array.length;
double sum = 0;
for (int i = 0; i < l; i++)
sum += (array[i] - mean) * (array[i] - mean);
return sum / l;
}
private static double getMedian(double[] array) {
int l = array.length;
// copy array to leave original one untouched by sorting
double[] a = new double[l];
for (int i = 0; i < l; i++)
a[i] = array[i];
Arrays.sort(a);
if (l % 2 == 0)
return (a[l / 2 - 1] + a[l / 2]) / 2;
else
return a[(l - 1) / 2];
}
}
此外,您的阵列存在问题,因为它是固定大小而不是可变大小的用户输入。考虑使用ArrayList<Double>
或类似容器作为值来避免此问题。