英文中に現れる異なる単語の数を表示するプログラムがわかりません。
例えば 「the a the」と入力されたら
the=2
a=1
と表示されるプログラムです。
なんとかカウントはされるのですが出力がうまくいきません。同じ単語も表示されてしまいます。
どなたかご教授お願いします。
WindowsXP、コンパイラはBCCを使っています。
#include <stdio.h>
#include <string.h>
#define MAX 256
int main()
{
struct {
char word[MAX];
int counter;
}list[50];
int i,j,total=0;
i=0;
while(scanf("%s",list[i].word)!=EOF){ /*キーボードから文字列をすべて読み込む*/
total++;
i++;
}
list[0].counter=1;
for(i=0;i<=total;i++,list[i].counter=0){ /*比較*/
for(j=1;j<=total;j++){
if(strcmp(list[i].word,list[j].word)==0){
list[i].counter++;
}
}
}
for(i=0;i<=total;i++){
printf("%s %d\n",list[i].word,list[i].counter); /*出力 the=2 a=1 the=1となってしまう*/
}
return(0);
}
No.3ベストアンサー
- 回答日時:
#2補足を手直ししてみました。
------------------------------
#include <stdio.h>
#include <string.h>
#define MAX 256
int main(){
struct {
char word[MAX];
int counter;
}list[50];
int i,j,total,find;
char text[MAX];
total=0;
while(scanf("%s",text)!=EOF){
find=-1;
for(i=0;i<total;i++){
if(strcmp(list[i].word,text)==0){
find=i;
}
}
if(find<0){ /* 見つからない */
strcpy(list[total].word,text);
list[total++].counter=1;
} else {
list[find].counter++;
}
}
for(i=0;i<total;i++){
printf("%s %d\n",list[i].word,list[i].counter);
}
return(0);
}
回答ありがとうございます。
無事 完成させることができました。
>if(find<0){
strcpy(list[total].word,text);
list[total++].counter=1;
の部分が少々わからなかったのですが、一つ一つ追っていくことで理解できました。
本当にありがとうございます。
あとよろしければ教えていただきたいのですが、
totalはtotal=0としておかないと実行時にエラーが出るのに
list[i].counterは初期化しておかなくても正常にカウントされていくのは何故でしょうか。
おかしな値が出てしまうような気がするのですが。
No.5
- 回答日時:
#3補足>list[i].counterは初期化しておかなくても正常にカウントされていくのは何故でしょうか。
始めて見つかった単語が出てきた時に
>list[total++].counter=1;
として、1回として数えています。
つまり、ここで初期化していることになります。
すみません、説明不足でした。
このプログラムではなく、全く初期化していないプログラムでも正常にカウントされていくので
不思議だなと思ったのです。
何度もありがとうございます。
No.4
- 回答日時:
この辺の構文解析きっちりやるなら、是非ともトークン関数を調べてみることをお勧めします。
strtok()でお調べ下さい。
非常に参考になる筈です。
参考URL:http://www1.cts.ne.jp/~clab/hsample/Func/Func08. …
No.2
- 回答日時:
while(scanf(…
で読み込むループで
input_word[MAX]に読み込んで
すでに登録されている部分に同じワードが見つからない時
追加してカウント(=1する)
既に登録してある時
見つかったlistをカウント
したらどうでしょうか
回答ありがとうございます。
そういうタイプのもかいてみたのですが、やはりうまくいきません。
#include <stdio.h>
#include <string.h>
#define MAX 256
int main()
{
struct {
char word[MAX];
int counter;
}list[50];
int i,j,total=1;
char text[MAX];
scanf("%s",list[0].word);
list[0].counter++;
while(scanf("%s",text)!=EOF){
for(i=0;i<=total;i++){ /*ここの繰り返し条件がおかしいと思うのですが よくわかりません*/
if(strcmp(list[i].word,text)==0){
list[i].counter++;
}
else{
strcpy(list[i+1].word,text); /*i+1も おそらくおかしいです*/
list[i+1].counter++;
}
}
total++;
}
for(i=0;i<=total;i++){
printf("%s %d\n",list[i].word,list[i].counter);
}
return(0);
}
解決策が思い浮かびません。
どうすればいいでしょうか。
No.1
- 回答日時:
> list[0].counter=1;
ここで1で初期化しているから、最初のthe=2になっています。初期化するなら0で初期化しましょう。
> for(j=1;j<=total;j++){
jのスタートがなぜに1で固定なのでしょうか?
同じ比較を何回もしないようにするのであればここはiからスタートすべきです。
for( j = i ; <= total; j++ ) {
まとめると比較部分はこんな感じ
--------------------------
list[0].counter=0; /*<<<0で初期化*/
for(i=0; i <= total ; i++, list[i].counter=0 ){ /*比較*/
for(j=i ; j <= total ; j++){ /*<<< iから*/
if( strcmp( list[i].word, list[j].word ) == 0){
list[i].counter++;
}
}
}
-----------------------------------
しかしこのアルゴリズムではどうしても同じ単語の重複はでてきます。(3つめのtheのところに1が立つ)
それを回避するにはlistのメンバーにすでにチェックされたかどうかを示すフラグを追加するなどするとよいとおもいます。
回答ありがとうございます。
> list[0].counter=1;
としたのは
> for(j=1;j<=total;j++){
との兼ね合いからか、2文字目からのカウントがうまくできなかったからです(実際の文字数ー1になってしまう)
直したら出来ました、ありがとうございます。
チェックは色々試しましたがうまくできませんでした。
もう一度やってみたいと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- PHP 配列の値の更新方法について 1 2022/08/05 09:49
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
どちのほうがすきですか?
-
【python】辞書作成(ネスト)を...
-
Application.ScreenUpdating = ...
-
formで特定のinputを送信しない...
-
文字の横にプルダウンを表示さ...
-
JSONで文字列が長い時
-
int(input("○○"))の使い方
-
実行時エラー 3020の対策
-
プルダウンで別項目に値を代入...
-
C言語のflagの使い方が分かりま...
-
16進の10進変換について
-
ACCESS テキストボックスを隙...
-
[html]ラジオボタンを使った診...
-
コンボボックスのtag情報の取得...
-
I2C接続のLCDディスプレイを使う
-
日齢計算プログラム
-
c言語 16進数の2進数への変換
-
Perlで複数の値を返す良い方法...
-
[python] 文字列を変数名として...
-
pythonで演算子を変数に代入す...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
どちのほうがすきですか?
-
C# GetFilesで複数のファイルの...
-
Python - Excel で Webからデー...
-
STLのlistで重複するものだけを...
-
可変引数をconstで参照渡し
-
Pythonでのアニメーション
-
PerlでXMLを解析して出力する。
-
複数のIP取得
-
【python】辞書作成(ネスト)を...
-
カーニハンの”C言語”の参照マニ...
-
C言語:単語カウント
-
Application.ScreenUpdating = ...
-
JSONで文字列が長い時
-
formで特定のinputを送信しない...
-
Pythonでターミナルに文字を出...
-
16進の10進変換について
-
セレクトメニューで2つの項目...
-
実行時エラー 3020の対策
-
文字の横にプルダウンを表示さ...
-
FindFirst を複数条件で検索
おすすめ情報