- 締切済み
出現文字の種類の数
下記のプログラムのファイルから読み込んだ出現文字の種類の数を取得するにはどうすれば良いでしょうか? また、 ー アルファベットでは大文字を全て小文字に置換 ー スペース、タブ、改行記号はスペースに置換 ー 数字は全て0に置換 ー その他の記号はそのまま使う という条件になっています。 #include<stdio.h> #include<ctype.h> #include<math.h> int cnt[256]; char chs[256]; int n=256; int main(void) { int k; for(k=0;k<n;k++) cnt[k]=0; inputdata(); heapsort(1,n); printdata_reverse(); } void inputdata() { char c; char *fnam="English.txt"; FILE *fp; char bff[80]; char *p; int k; fp = fopen(fnam,"r"); while(fgets(bff,80,fp)!=NULL) { for(p=bff;*p;p++) { c = *p; if(isalpha(*p)) c=tolower(*p); if(isdigit(*p)) c = '0'; if(isspace(*p)) c = ' '; cnt[c]++; chs[c] = c; } } fclose(fp); } void heapsort(int s,int t) { int i; makeheap(s,t); for(i = t; i>= s+1; i--) { swap(s,i); heapify(s,i-1); } } void makeheap(int s,int t) { int i; for(i = t; i >= s; i--) heapify(i,t); } void heapify(int p,int q) { int r; r = 2*p; if(r <= q){ if(r < q && cnt[r] > cnt[r+1]) r = r+1; if(cnt[p] > cnt[r]){ swap(p,r); heapify(r,q); } } } void swap(int i, int j) { int temp1,temp2; temp1=cnt[i]; cnt[i]=cnt[j]; cnt[j]=temp1; temp2=chs[i]; chs[i]=chs[j]; chs[j]=temp2; } void printdata_reverse() { int k; int m=0; double pcnt[100]; for(k=0;k<n;k++) { if(cnt[k]>0) m += cnt[k]; } printf("Characters in UN Charter.\n"); printf(" # C occ. %%\n"); for(k=0;k<n;k++) { if(cnt[k]>0) { pcnt[k] = 1.0*cnt[k]/m; printf("%3d '%c' %5d %f\n", k,chs[k],cnt[k],pcnt[k]); } } } 実行結果 Characters in UN Charter. # C occ. % 1 ' ' 4576 0.190643 2 'e' 2804 0.116819 3 't' 1827 0.076115 4 's' 1464 0.060992 5 'o' 1339 0.055785 6 'a' 1315 0.054785 7 'n' 1313 0.054701 8 'r' 1257 0.052368 9 'i' 1103 0.045953 10 'h' 972 0.040495 11 'c' 755 0.031454 12 'l' 645 0.026872 13 'd' 639 0.026622 14 'u' 593 0.024705 15 'f' 492 0.020497 16 'p' 430 0.017914 17 'm' 400 0.016665 18 'g' 285 0.011874 19 '0' 278 0.011582 20 'b' 253 0.010540 21 '.' 238 0.009915 22 'v' 203 0.008457 23 'y' 199 0.008291 24 ',' 192 0.007999 25 'w' 167 0.006957 26 '-' 54 0.002250 27 'k' 38 0.001583 28 'x' 34 0.001416 29 ''' 30 0.001250 30 'j' 27 0.001125 31 '(' 20 0.000833 32 ')' 20 0.000833 33 'z' 17 0.000708 34 'q' 13 0.000542 35 ':' 11 0.000458
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- yama5140
- ベストアンサー率54% (136/250)
前回と一字一句同じに質問するのではなく、 「下の例では、『35』という数になります。これをプログラム内で取得するにはどうすれば良いでしょうか?」と記載し、 かつ、 >また、 >ー アルファベットでは大文字を全て小文字に置換 >ー スペース、タブ、改行記号はスペースに置換 >ー 数字は全て0に置換 >ー その他の記号はそのまま使う >という条件になっています。 この↑6行を削除していれば、ズバリの回答があったかと思います・・。 この6行は、質問主旨とは全く関係ないもので、反って回答者を混乱させるだけです。 ・というか、本当に上のが質問主旨ですか?。 (= http://okwave.jp/qa4567672.html 「補足」) ・「取得」とは、ファイルに書き出す、ということ?(「リダイレクト」で検索)。 ・ソース内容(再帰呼出し等)と、随分と乖離してますが・・。 ++++++++++++++++++++++++++++++++++++++++++++++ (微積分できる人から、九九を尋ねられるような気持ちの悪さが・・) ☆「出現文字の種類の数」用の変数を用意し代入する(◆)だけ、です。 具体的には、printdata_reverse() を以下のように変更してみてください。 (インデントに全角空白使用)。 または、変数を0で初期化しておいて、インクリメントするとか・・。 int igLast; // ◆「出現文字の種類の数」用(グローバル変数) void printdata_reverse( void ) { int k; int iTotal = 0; // m から変更 double pcnt; // 配列の必要なし for( k = 1; k < 0x7F; k++ ){ // [ 0 ] は初期化時を除き未使用、0x7e まで if( cnt[ k ] ) igLast = k; // ◆降順ソート済み、出現最少 = 種類の数 iTotal += cnt[ k ]; // 0 はいくら加えても・・ } printf( "Characters in UN Charter.\n" ); printf( " # C occ. %%\n" ); for( k = 1; k <= igLast; k++ ){ pcnt = 100.0 * (double)cnt[ k ] / (double)iTotal; printf( "%3d '%c' %5d %6.2lf%\n", k, chs[ k ], cnt[ k ], pcnt ); } } グローバル変数ですので、printdata_reverse() 呼び出し後ならどこでも使えますよ。 参考:http://e-words.jp/p/r-ascii.html ++++++++++++++++++++++++++++++++++++++++++++++ 年寄りの小言 エラー・警告の無いものを投稿するのがマナーと思います。 エラー・警告を無くすことができない場合は、そのことを質問。
- asuncion
- ベストアンサー率33% (2127/6289)
種類の数、ということは、 ・英小文字 ・スペース ・ゼロ の3個が答えではないでしょうか。
- Tacosan
- ベストアンサー率23% (3656/15482)
「出現文字の種類の数」って何? なんで置換なんてするの?
- arain
- ベストアンサー率27% (292/1049)
http://okwave.jp/qa4567672.html で、出力結果として何がどうあれば正しいわけ? せめて、どこで何を行っている(行いたい)のかコメントくらいつけようよ。