标准偏差计算器(Java)

时间:2016-10-18 20:18:47

标签: java

我目前必须编写一个程序来计算十个数组的平均值和标准偏差。平均的calculateMean方法似乎工作正常,但我的calculateStandardDeviation方法中的逻辑存在缺陷。不知道到底在哪里。任何建议/指示将不胜感激!

public static void main(String[] args) {

    Scanner input = new Scanner (System.in); 
    System.out.println("Please enter ten numbers: "); 

    double [] set = new double [10]; 

    for (int i = 0; i < 10; i++){
        set[i] = input.nextDouble(); 
    }

    /*for (double j: set){
        System.out.println(j);
    }*/

    System.out.println(calculateMean(set)); 
    System.out.println(calculateStandardDeviation(set));

}

public static double calculateMean(double[] m){
    double sum = 0;
    for (int i = 0; i<m.length; i++){
        sum = sum + m[i];
    }
    double mean = (sum) / (m.length); 
    return mean; 
}

public static double calculateStandardDeviation(double[] sd){

    double sum = 0;
    double newSum = 0; 
    double [] newArray = new double [10]; 

    for (int i = 0; i<sd.length; i++){
        sum = sum + sd[i];
    }
    double mean = (sum) / (sd.length); 

    for (int j = 0; j<sd.length; j++){
        newArray[j] = ((sd[j] - mean) * (sd[j] - mean)); 
        newSum = newSum + newArray[j]; 
    }
    double squaredDiffMean = (newSum) / (sd.length); 
    double standardDev = (Math.sqrt(squaredDiffMean)); 

    return standardDev; 
}

1 个答案:

答案 0 :(得分:0)

首先,为什么要将newArray的大小设置为静态数字?它当然不应该(作为一般规则)。而且,无论如何都不需要第二个阵列。所以把它拿出来。 我发现newArray[j]存在问题,其中j是索引&lt; sd.length,因此它可能超出newArray 的范围。如果您真的想保留它,可以将new double [10]更改为new double [sd.length]。但无论哪种方式,它都不会导致错误,因为您的输入将数组长度限制为10.这只是不好的做法。

因此,请将以下功能更改为:

public static double calculateStandardDeviation(double[] sd){

    double sum = 0;
    double newSum = 0; 

    for (int i = 0; i<sd.length; i++){
        sum = sum + sd[i];
    }
    double mean = (sum) / (sd.length); 

    for (int j = 0; j<sd.length; j++){
        // put the calculation right in there
        newSum = newSum + ((sd[j] - mean) * (sd[j] - mean)); 
    }
    double squaredDiffMean = (newSum) / (sd.length); 
    double standardDev = (Math.sqrt(squaredDiffMean)); 

    return standardDev; 
}

更多要点:

  • 在第二个循环中,您无需使用j代替i。它们位于不同的范围内,因此您可以重用i。唯一不可能的是,如果它是另一个循环中的循环。
  • 您可以使用Math#pow静态函数代替((sd[j] - mean) * (sd[j] - mean))进行计算,例如Math.pow((sd[j] - mean), 2)
  • 根本不需要第一个循环。你已经有了计算均值的函数,为什么还要在你的其他函数中再做一次呢?只需使用此中的第一个功能。
  • 您应该在平均值和SD函数的顶部检查以查看数组的长度是否为0.否则,您可以除以0.现在,这不会对您的代码造成问题,因为您强制来自用户的10个输入,但总的来说,这是一个很好的做法。

那么“更好”的代码如下:

public static double calculateMean(double[] m){
    if (m.length == 0) return 0; // don't divide by zero!

    // ... the rest of your stuff
}

public static double calculateStandardDeviation(double[] sd){

    if (sd.length == 0) return 0; // don't divide by zero!

    double sum = 0;

    double mean = calculateMean(sd);

    for (int i = 0; i<sd.length; i++){
        sum = sum + (sd[i] - mean) * (sd[i] - mean);
    }
    double squaredDiffMean = (sum) / (sd.length); 
    double standardDev = (Math.sqrt(squaredDiffMean)); 

    return standardDev; 
}