0

文の平均語長を計算したい。

たとえば、入力が与えられabc def ghiた場合、平均語長は になります3.0

プログラムは動作しますが、単語間の余分なスペースを無視したいです。したがって、次の文が与えられます。

abc  def

(単語間に 2 つのスペース)、平均単語長は ではなく と計算され2.0ます3.0

単語間の余分なスペースを考慮するにはどうすればよいですか? 3.0これらは無視されます。これにより、誤って計算された ではなく、上記の例の平均語長がになります2.0

#include <stdio.h>
#include <conio.h>

int main()
{
char ch,temp;
float avg;
int space = 1,alphbt = 0,k = 0;

printf("Enter a sentence: ");

while((ch = getchar()) != '\n')
{
    temp = ch;

    if( ch != ' ')
    {
       alphbt++;
       k++;         // To ignore spaces before first word!!!
    }  
    else if(ch == ' ' && k != 0)
       space++;

}

if (temp == ' ')    //To ignore spaces after last word!!!
   printf("Average word lenth: %.1f",avg = (float) alphbt/(space-1));
else
   printf("Average word lenth: %.1f",avg = (float) alphbt/space);

getch();
}               
4

3 に答える 3

4

カウントのロジックが間違っています。このコードは、先頭と末尾の両方の空白、および単語間の複数の空白などで正しく機能するint ch;ようです。コードが EOF を正確にチェックできるように、 を使用することに注意してください ( をgetchar()返しますint)。

#include <stdio.h>
#include <stdbool.h>

int main(void)
{
    int ch;
    int numWords = 0;
    int numLetters = 0;
    bool prevWasASpace = true; //spaces at beginning are ignored

    printf("Enter a sentence: ");
    while ((ch = getchar()) != EOF && ch != '\n')
    {
        if (ch == ' ')
            prevWasASpace = true;
        else
        {
            if (prevWasASpace)
                numWords++;
            prevWasASpace = false;
            numLetters++;
        }
    }

    if (numWords > 0)
    {
        double avg = numLetters / (float)(numWords);
        printf("Average word length: %.1f (C = %d, N = %d)\n", avg, numLetters, numWords);
    }
    else
        printf("You didn't enter any words\n");
    return 0;
}

ヒットした#場所を示すために使用するさまざまな実行例。Return

Enter a sentence: A human in Algiers#
Average word length: 3.8 (C = 15, N = 4)

Enter a sentence: A human in Algiers  #
Average word length: 3.8 (C = 15, N = 4)

Enter a sentence:   A human  in   Algiers  #
Average word length: 3.8 (C = 15, N = 4)

Enter a sentence: #
You didn't enter any words

Enter a sentence: A human in AlgiersAverage word length: 3.8 (C = 15, N = 4)

Enter a sentence: You didn't enter any words

最後から 2 番目の例では、2 回入力Control-Dしました (1 回目は「A human in Algiers」をプログラムにフラッシュし、2 回目は EOF を与えるため)、最後の例では 1 回入力しました。このコードはタブを「スペースではなく」としてカウントすることに注意してください。タブをより適切に処理するには、の代わりに#include <ctype.h>and if (isspace(ch))(or )が必要です。if (isblank(ch))if (ch == ' ')


getchar()を返しますint

なぜあなたがint chEOF!を使ったのか混乱しています。

この答えにはいくつかの部分があります。

  1. を使用する最初の理由int chは、getchar()関数が を返すことintです。任意の有効な文字と個別の値 EOF を返すことができます。したがって、その戻り値は、chara に収まるよりも多くの値を返す必要があるため、任意の種類の a にすることはできませんchar。実際には を返しますint

  2. なぜそれが重要なのですか?からの値getchar()が に割り当てられているとしchar chます。現在、ほとんどのキャラクターで、ほとんどの場合、問題なく動作します。ただし、次の 2 つのいずれかが発生します。プレーンcharが符号付きタイプの場合、有効な文字 (多くの場合、ÿ、y ウムラウト、0xFF、正式には Unicode U+00FF、分音符付きのラテン小文字 Y) が EOF として誤認識されます。あるいは、plaincharが unsigned 型の場合、EOF は検出されません。

  3. EOF の検出が重要なのはなぜですか? 入力コードは、予期しないときに EOF を取得する可能性があるためです。ループが次の場合:

    int ch;
    
    while ((ch = getchar()) != '\n')
        ...
    

    入力がEOFに達すると、プログラムは何の役にも立たないことに長い時間を費やします。関数はgetchar()EOF を繰り返し返しますが、EOF はそうではない'\n'ため、ループは再試行されます。getchar()関数が、scanf()fread()read()またはそれらの無数の関連関数のいずれであるかに関係なく、入力関数のエラー条件を常にチェックします。

于 2013-06-16T06:27:20.920 に答える
2

次の入力を検討してください: (ハイフンはスペースを表します)

--Hello---World--

現在、最初のスペースと最後のスペースは無視されていますが、中間のスペースが隣り合っていても、それぞれカウントされます。プログラム、特に 'k' を少し変更するだけで、このケースに対処できます。

#include <stdio.h>
#include <conio.h>
#include <stdbool.h>
int main()
{
  char ch;
  float avg;
  int numWords = 0;
  int numLetters = 0;
  bool prevWasASpace = true; //spaces at beginning are ignored

  printf("Enter a sentence: ");

  while((ch = getchar()) != '\n')
  {
      if( ch != ' ')
      {
         prevWasASpace = false;
         numLetters++;
      }  
      else if(ch == ' ' && !prevWasASpace)
      {
         numWords++;
         prevWasASpace = true; //EDITED this line until after the if.
      }
  } 

  avg = numLetters / (float)(numWords);

  printf("Average word lenth: %.1f",avg);

  getch();
}          

上記を少し変更する必要があるかもしれません (まだテストしていません)。

ただし、単語間のスペースのみに基づいて文内の単語を数えることは、必要なすべてではない場合があります。次の文を考えてみましょう。

ジョンは、「電話を取りなさい...今すぐ!」と言った。

テレビのアナウンサーは、24 時間年中無休で営業していると言いながら、1 回購入すると 1 回無料で取引できると提案しました。

月額 100.99 ドル (3.25 ユーロ) 以上の費用はかかりません。

すぐに彼/彼女の電話で (555) 555-5555 に電話します。

A(n) = A(n-1) + A(n-2) -- つまり、シーケンス: 0,1,1,2,3,5, . . .

単語を構成するものを決定する必要がありますが、それは簡単な質問ではありません (ところで、すべての種類の英語を含む例はありません)。スペースを数えることは、英語ではかなり適切な見積もりですが、すべてを把握することはできません.

Text Segmentationに関するウィキペディアのページを見てください。この記事では、「非自明」というフレーズが 4 回使用されています。

于 2013-06-16T02:10:22.830 に答える
2

明らかに、スペース以外の文字を数えるのは簡単です。問題は単語を数えることです。なぜ単語をスペースとしてカウントするのですか? またはもっと重要なことに、単語を定義するものは何ですか?

IMO 単語は、スペース文字から非スペース文字への移行として定義されます。したがって、それを検出できれば、単語数を知ることができ、問題は解決されます。

私は実装を持っています。それを実装する方法はたくさんあります。後で編集として実装を投稿する場合があります。

*編集:私の実装

#include <stdio.h>

int main()
{
    char ch;
    float avg;
    int words = 0;
    int letters = 0;
    int in_word = 0;

    printf("Enter a sentence: ");

    while((ch = getchar()) != '\n')
    {
        if(ch != ' ') {
            if (!in_word) {
                words++;
                in_word = 1;
            }
            letters++;
        }
        else {
            in_word = 0;
        }
    }

    printf("Average word lenth: %.1f",avg = (float) letters/words);
}
于 2013-06-15T23:39:16.970 に答える