2016-10-18 17 views
1

現在、10個の数値の配列の平均と標準偏差を計算するプログラムを作成する必要があります。平均calculateMeanメソッドはうまくいくようですが、calculateStandardDeviationメソッドのロジックに欠陥があります。正確にそれがどこにあるのかわからない。どんなアドバイス/ポインタでも大変感謝しています!標準偏差計算(Java)

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; 
} 
+0

は、なぜあなたは10に' newArray'のサイズを設定するのですか? 'newArray'のサイズを' sd'配列のサイズに合わせて設定します。 (また、 'calculateMean(double [])'というメソッドを素敵に作成しているのを見て、 'calculateStandardDevation(double [])'メソッドで平均を計算するときに呼び出すべきです) – Bobulous

+0

2つの提案:(1)平均を計算する際に配列がnullでも空でもないことを確認する、(2)標準偏差の計算が最適ではないと思う。より簡単な方法があります。少ないコードです。 – duffymo

+1

「私のcalculateStandardDeviationメソッドのロジックに欠陥があります」というのはどういう意味ですか?結果は間違っていますか?私はあなたのプログラムを2,4,4,4,5,5,7,9,9,10の入力で走らせ、平均値と標準偏差としてそれぞれ5.35 2.5475478405713994を与えました。それは正しいようですか? – MojoJojo

答えて

0

まず、newArrayのサイズを静的な数値に設定するのはなぜですか?それは最も一般的なものではないはずです。さらに、その第2のアレイは、関係なく必要である。だからそれを取り出してください。 newArray[j]との問題があります。 jのインデックスは< 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; 
} 

よりポイント:2つ目のループでは

  • を、あなたはjの代わりiを使用する必要はありません。それらは異なるスコープにあるので、の再利用iです。あなたが他のループの中のループである場合、あなたができない唯一の時間です。
  • 代わりの((sd[j] - mean) * (sd[j] - mean))
  • は、あなたがすべてで最初のループを必要としない Math.pow((sd[j] - mean), 2)
  • のように、計算のためにMath#pow静的関数を使用することができます。あなたはすでに平均を計算する関数を持っているので、なぜあなたの他の関数で再びそれを行うのですか?この関数の最初の関数も使用してください。
  • 配列の長さが0かどうかを確認するには、mean関数とSD関数の先頭にチェックが必要です。それ以外の場合は、0で割ることができます。これで、コードに問題はありませんユーザーからの10の入力がありますが、一般的にはこれが良い方法です。

それでは、「より良い」コードは、次のようになります。sd` `の大きさが、それ以外の何かであるかもしれないとき

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; 
} 
+0

ありがとうございます。私が静的配列を持っている唯一の理由は、配列を10個呼び出すためにこれを完了しているためです。 – scoopfaze

+1

私はまた、forループが異なるスコープにあることを理解していますが、自分の分かりやすさのために、私はちょうど異なる変数を使うことを好みます。 – scoopfaze

+0

@ user5499487はい、この特定のコードでは、10にすることができます。しかし、一般的な考え方として、配列の長さを制限する理由はありません。任意の配列サイズで動作するはずです。しかし、あなたのコードには何が間違っていると思いますか? –

関連する問題