均值,中位数,方差计算器

时间:2015-10-27 21:18:24

标签: java methods mean median

我创建了一个计算平均值,中位数和方差的程序。该程序最多可接受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中输入我自己的数字。测试程序是我的导师,我相信他的程序工作正常。

有人可以帮忙吗?我要把头发撕掉了。

3 个答案:

答案 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方法之前,需要减小数组的大小。最简单的方法是使用提供给所有数组的现有方法,称为counterCopyOf() 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的结果。

要解决此问题,您应该考虑:

  • 使用this method taking a starting and ending indices对数组进行排序。
  • 在排序之前复制数组。
  • 保持班级无国籍 - 所有这些方法都可以采取任何必要的参数作为参数(虽然这不是绝对必要的,但它将为你节省大量的时间)。

答案 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>或类似容器作为值来避免此问题。