- ベストアンサー
分割した単語の頻出頻度表示プログラムの作成とアドバイスの求め方
- 英文テキストファイルを読み込み、分割した単語の頻出頻度を表示するプログラムを作成しています。
- 現時点では、分割した単語の表示しかできていません。
- どなたか良きアドバイスをお願いします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
まず頻度用の表を作っておき、分割した単語を登録するときに、登録済みの単語と比較して同じものがあれば該当の頻度を+1、なければ単語を登録して該当の頻度を1にセットすればいいように思います。 参考まで。(単語切り出しの仕様がいまいち分かってません) #include <stdio.h> #include <stdlib.h> #include <string.h> #define WORD_MAX 1000 /* 単語帳の登録数 */ #define WORD_SIZE 100 /* 単語の最大長 */ char *word[WORD_MAX]; /* 単語帳 */ int freq[WORD_MAX]; /* 頻度表 */ int wordp=0; /* 単語帳の最後 */ /******************************************/ /* 単語登録(すでに登録済みなら頻度+1) */ /******************************************/ void add_word(char *s) { int i; if (strlen(s)==0) return; /* 長さ0は登録しない */ for (i=0; i<wordp; i++) { /* 登録済みかどうか調べる */ if (strcmp(word[i],s)==0) { freq[i]++; break; } } if (i==wordp) { /* 登録されてなければ追加する */ if ((word[wordp]=malloc(strlen(s)))==NULL) exit(1); strcpy(word[wordp],s); freq[wordp]=1; if (wordp<WORD_MAX-1) wordp++; } } /******************************/ /* ファイルから単語を切り出す */ /******************************/ void split_word(FILE *fp) { char buf[WORD_SIZE]; int bufp=0; int key; int sp=0; /* 空白チェック用フラグ */ while((key=fgetc(fp))!=EOF) { if (key==' ' && sp==0) { /* 空白の1個目は単語区切り文字とする */ buf[bufp]='\0'; bufp=0; add_word(buf); sp=1; } else { if( key=='.' || key== '!' || key=='?' || key=='"'){ /* 特定の区切り文字は単語登録する */ if (sp==1) { /* 空白に続く場合は空白含めて登録する */ buf[bufp]=key; if (bufp<WORD_SIZE-1) bufp++; buf[bufp]='\0'; bufp=0; add_word(buf); sp=0; } else { buf[bufp]='\0'; bufp=0; add_word(buf); buf[0]=key; buf[1]='\0'; add_word(buf); } } else { if (key == ',' || key == 0x0a || key == 0x0d ){ /* 普通の区切り文字 */ buf[bufp]='\0'; bufp=0; add_word(buf); sp=0; } else { /* 区切り文字ではない文字(空白の2個目以降は区切り文字としない) */ buf[bufp]=key; if (bufp<WORD_SIZE-1) bufp++; if (key != ' ') sp=0; } } } } if (bufp>0) { /* 単語直後にEOFがきた場合 */ buf[bufp]='\0'; add_word(buf); } } /******************/ /* 単語を表示する */ /******************/ void print_word(void) { int i; for (i=0; i<wordp; i++) { printf("%d [%s] %d\n",i,word[i],freq[i]); } } /************************************/ /* 単語用に確保したメモリを解放する */ /************************************/ void free_word(void) { int i; for (i=0; i<wordp; i++) { free(word[i]); } } /**********/ /* メイン */ /**********/ int main(int argc, char **argv) { FILE *fp; if (argc!=2) return -1; /* コマンドラインでファイル名指定 */ if ((fp=fopen(argv[1],"r"))==NULL) return -1; /* ファイル開けない */ split_word(fp); fclose(fp); /* 単語切り出し */ print_word(); /* 単語表示 */ free_word(); /* メモリ解放 */ return 0; }
その他の回答 (1)
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
とりあえず、いまあるプログラムは捨てて新しく作りましょう♪ 空白文字(スペースやタブ)ピリオドやカンマ、感嘆符、疑問符などで単語を切り出すプログラムを作りましょう。 切り出した文字を登録する「辞書(頻度が記録できる)」を実現するプログラムを作りましょう。 とりあえずの辞書ができたら、検索、更新、登録なんかが素早くできるように、ブラッシュアップしましょう。 プログラムの練習でそういうのを作っているのでないなら、Perlなどを使うのが吉
お礼
うーん。1から作り直すとなると難しいですね
補足
具体例を出していただき有難うございます。 プログラムを実行したところ23行目 if ((word[wordp]=malloc(strlen(s)))==NULL) exit(1);がエラーだったので if ((word[wordp]=(char*)malloc(strlen(s)))==NULL) exit(1);としたところ、エラーは0になりましたが実行すると "Press any key to continue"と表示され、ファイルを読み込むことができません。 自分なりに試行錯誤してみましたがどうも上手くいきません。何か特別な実行方法があるのでしょうか。