2017-10-24 9 views
1

私は、配列から平均、中央値、およびモードを計算するこのプログラムを作った。私はいくつかの例でテストしましたが、テストした入力の多くは忘れてしまったかもしれないが、先生が使っているテストプログラムでは、私はその入力を提示されていませんでした。たぶん、誰かが見ていると私は、コードのモードポイントでミスを作っていますかどうかを確認することができます可能なモードエラー

#include <stdio.h> 
#include <stdlib.h> 
#include <limits.h> 

void *safeMalloc(int n) { 
    void *p = malloc(n); 
    if (p == NULL) { 
     printf("Error: malloc(%d) failed. Out of memory?\n", n); 
     exit(EXIT_FAILURE); 
    } 
    return p; 
} 

int main(int argc, char *argv[]) { 
    int n, i; 
    scanf("%d", &n); 
    int *array = safeMalloc(n * sizeof(int)); 
    for (i = 0; i < n; i++) { 
     int value; 
     scanf("%d", &value); 
     array[i] = value; 
    } 

    //mean 
    double mean; 
    double sum = 0; 
    for (i = 0; i < n; i++) { 
     sum = sum + (double)array[i]; 
    } 
    mean = sum/n; 
    printf("mean: %.2f\n", mean); 

    //median 

    float temp; 
    int j; 
    for (i = 0; i < n; i++) 
     for (j = i + 1; j < n; j++) { 
      if (array[i] > array[j]) { 
       temp = array[j]; 
       array[j] = array[i]; 
       array[i] = temp; 
      } 
     } 
    printf("median: %d\n", array[n/2]); 

    //mode 

    int val = array[0], noOfRepetitions = 1, valMax = array[0], maxRepetitions = 1, possibleMax = 1; 

    for (i = 1; i < n; i++) { 
     if (array[i] == val) { 
      noOfRepetitions++; 
     } 

     if (array[i] != val) { 
      val = array[i]; 
      noOfRepetitions = 1; 
     } 

     if (noOfRepetitions == possibleMax) { 
      maxRepetitions = 1; 
      continue; 
     } 

     if (noOfRepetitions > maxRepetitions) { 
      valMax = val; 
      maxRepetitions = noOfRepetitions; 
      possibleMax = maxRepetitions; 
     } 
    } 

    if (maxRepetitions > 1) { 
     printf("mode: %d\n", valMax); 
    } else { 
     printf("mode: NONE\n"); 
    } 

    return 0; 
} 

ちょうどそれを横断するときの番号がソートされているので、モードのための私の考えでした。次の要素が前の要素と同じ場合は、noOfRepetitionsを増やします。今までnoOfRepetitionmaxRepetitionsより大きい場合は、これに置き換えてください。例えば、同じ回数の繰り返しを持つ2つ以上の数値がある場合に必要な最後の最大値も格納します。

EDIT:配列のモードは、配列内で最大の出現数を持つ数値を返さなければなりません。同じ数の最大出現数を持つ2つ以上の数字がある場合、その配列にモードはありません。

+0

とき、統計的観点から、以下のことを注意してください2つ以上の数字は、あなたがマルチモードの分布を持っているのと同じ最大出現数を持ちます。 –

+0

_unsorted_入力はどうですか?あなたの配列が '1 2 1 5 1 4 1 3 3 1'ならば、あなたのプログラムはモードとして' 1'または '3'を返しますか?中央値を見つけることができますか? – CiaPan

+0

また、中央値の場合、偶数の要素の場合は、2つの中心値の平均値を取る必要があります。 –

答えて

0

変数possibleMaxの目的がないようです。

if(noOfRepetitions==possibleMax){ 
     maxRepetitions=1; 
     continue; 
    } 

これにより、maxRepetitionsが誤ってリセットされることがあります。

分布は、すべてのモード値マルチモーダルと印刷されている場合は、検出することができた:

#include <stdio.h> 
#include <stdlib.h> 
#include <limits.h> 

void *safeMalloc(int n) { 
    void *p = malloc(n); 
    if (p == NULL) { 
     printf("Error: malloc(%d) failed. Out of memory?\n", n); 
     exit(EXIT_FAILURE); 
    } 
    return p; 
} 

int main(int argc, char *argv[]) { 
    int n, i; 
    if (scanf("%d", &n) != 1 || n <= 0) 
     return 1; 
    int *array = safeMalloc(n * sizeof(int)); 
    for (i = 0; i < n; i++) { 
     if (scanf("%d", &array[i]) != 1) 
      return 1; 
    } 

    //mean 
    double sum = 0; 
    for (i = 0; i < n; i++) { 
     sum = sum + (double)array[i]; 
    } 
    printf("mean: %.2f\n", sum/n); 

    //median 

    int j; 
    for (i = 0; i < n; i++) { 
     for (j = i + 1; j < n; j++) { 
      if (array[i] > array[j]) { 
       int temp = array[j]; 
       array[j] = array[i]; 
       array[i] = temp; 
      } 
     } 
    } 
    printf("median: %d\n", array[n/2]); 

    //mode 

    int val = array[0], noOfRepetitions = 1, valMax = array[0], maxRepetitions = 1; 

    for (i = 1; i < n; i++) { 
     if (array[i] == val) { 
      noOfRepetitions++; 
      if (noOfRepetitions > maxRepetitions) { 
       valMax = val; 
       maxRepetitions = noOfRepetitions; 
      } 
     } else { 
      val = array[i]; 
      noOfRepetitions = 1; 
     } 
    } 

    if (maxRepetitions == 1) { 
     printf("mode: NONE\n"); 
    } else { 
     printf("mode: %d", valMax); 
     val = array[0]; 
     noOfRepetitions = 1; 
     for (i = 1; i < n; i++) { 
      if (array[i] == val) { 
       noOfRepetitions++; 
      } else { 
       if (noOfRepetition == maxRepetitions && val != valMax) { 
        printf(", %d", val); 
       } 
       val = array[i]; 
       noOfRepetitions = 1; 
      } 
     } 
     if (noOfRepetition == maxRepetitions && val != valMax) { 
      printf(", %d", val); 
     } 
     printf("\n"); 
    } 
    return 0; 
} 
+0

私の心の中にはありません。possibleMaxのアイデアは、同じ最大頻度の複数の数値がある場合の事実です。例えば、私がその行を削除すると、1と2の両方に周波数2があるので、ケース1 1 2 2 3は私にモード2を与えません。私は後でmaxRepetition変更されず、1のままで印刷されません。 –

+0

質問を編集して、* mode *の意味を明確にすることはできますか? – chqrlie

+1

@chqrlie https://en.wikipedia.org/wiki/Mode_(statistics) – CiaPan

0

私は私のミスを発見しました。私は、同じ最大周波数を持つ数があり、その後に周波数が低いが、他の周波数よりはるかに大きい数を持つ場合を考えなかった。例:1 1 2 1 2 2 3 3 4 5 6.私のコードでは、結果は3になります。 noOfRepetitionsとoldMaxRepetitionの比較を変更するだけでした。

+0

'oldMaxRepetition'が定義されていません。コードを修正するためにどのような変更を加えたのかは不明です。 – chqrlie

0

モードを検索するコードが複雑すぎるようです。この比較:

//mode 

    int val = array[0], noOfRepetitions = 1, 
     valMax = array[0], maxRepetitions = 1; 

    for (i = 1; i < n; i++) { 
     if (array[i] == val) { 
      if (++noOfRepetitions > maxRepetitions) { 
       valMax = val; 
       maxRepetitions = noOfRepetitions; 
      } 
     } 
     else 
     { 
      val = array[i]; 
      noOfRepetitions = 1; 
     } 
    } 

これはおそらく、あなたが必要なものを行うための最も簡単なコードですが、それはあまりにも頻繁にmaxValmaxRepetitionsを上書きします。

次のバージョンは一度しか発見された各新しい最大ごとに2つの「最大」の変数を上書きする - コードの一部を複製するコストで:

//mode 

    int val = array[0], noOfRepetitions = 1, 
     valMax = array[0], maxRepetitions = 1; 

    for (i = 1; i < n; i++) { 
     if (array[i] == val) { 
      ++noOfRepetitions; 
     } 
     else 
     { 
      if (noOfRepetitions > maxRepetitions) { 
       valMax = val; 
       maxRepetitions = noOfRepetitions; 
      } 

      val = array[i]; 
      noOfRepetitions = 1; 
     } 
    } 

    if (noOfRepetitions > maxRepetitions) { 
     valMax = val; 
     maxRepetitions = noOfRepetitions; 
    } 
関連する問題