質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

844閲覧

頻度の高い順に文字と個数を表示したい

teruterubose

総合スコア1

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2023/11/07 10:54

実現したいこと

頻度の高い順に文字と個数を表示したい

前提

c言語で作っています。
テキストファイルから読み込んで、a-zと空白の出現回数を数えたいです。
そして、下記の理想のように出力したいです。

該当のソースコード

c

1#include <stdio.h> 2 3int main(void){ 4 FILE *fp; //ファイルポインタ 5 6 int moji[27] = {0}; 7 int i, j, tmp; 8 float num = 0; //全文字数num 9 char c; 10 11 if((fp = fopen("/home/NumCom1/report/book1", "r")) != NULL) 12 { 13 while ((c = fgetc(fp)) != EOF) 14 { 15 16 if (c >= 97 && c <= 122) //小文字の場合 17 { 18 moji[(int)c-97]++; 19 num++; 20 } 21 if (c >= 65 && c <= 90) //大文字の場合 22 { 23 moji[(int)c - 65]++; 24 num++; 25 } 26 if(c = 32); 27 moji[26]++; 28 num++; 29 30 31 } 32 33 for(i=0; i<26; i++) 34 { 35 printf("%c : %d \t%.3f%% \n", i+97, moji[i], moji[i]*100/num); 36 } 37 printf("%c : %d \t%.3f%%\n",32, moji[26], moji[26]*100/num); 38 39 40 } 41 42 else // エラーメッセージを出力 43 { 44 printf("File open error!\n"); 45 return (-1); 46 } 47 48 return 0; 49}

出力結果

c

1a : 49997 3.594% 2b : 9570 0.688% 3c : 16719 1.202% 4d : 26713 1.920% 5e : 78174 5.619% 6f : 15180 1.091% 7g : 11532 0.829% 8h : 39562 2.844% 9i : 41124 2.956% 10j : 896 0.064% 11k : 3872 0.278% 12l : 24624 1.770% 13m : 14583 1.048% 14n : 41205 2.962% 15o : 46708 3.357% 16p : 11524 0.828% 17q : 794 0.057% 18r : 37849 2.721% 19s : 40137 2.885% 20t : 55584 3.995% 21u : 16377 1.177% 22v : 5926 0.426% 23w : 13784 0.991% 24x : 1155 0.083% 25y : 10744 0.772% 26z : 449 0.032% 27 : 776435 55.810%

理想

c

1 : 776435 55.810% 2e : 78174 5.619% 3t : 55584 3.995% 4a : 49997 3.594% 5o : 46708 3.357% 6n : 41205 2.962% 7以下略

発生している問題

バブルソートを使ってやってみましたが個数だけ昇順になり、文字のほうはどうやって多い順に出力するのかわかりませんでした。
どうすれば理想のように出力されるでしょうか?
また、提示したソースコードを変えるべきところがありましたらそちらもお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2023/11/07 13:34

26 行目は変ではありませんか?
teruterubose

2023/11/08 04:28

具体的にはどういったことでしょうか?
jimbe

2023/11/08 05:21 編集

>if(c = 32); これは c に 32 を入れているだけです。 '=' 1つは代入です。 同じかという判断をするなら '=' 2つです。従って何の判断もしていません。 さらに ';' で終わっているため if の効果はこの行だけです。後の(複数)処理を成立時にのみ行わせるなら ';' を消して '{' '}' 対で囲わなければなりません。従って後続の >moji[26]++; >num++; は(インデントはそれっぽくなっていますが) if に関係無く常に実行しています。 結果は正しいですか? /home/NumCom1/report/book1 ファイルは本当に半分以上スペースだったのでしょうか?
teruterubose

2023/11/08 06:03

勘違いしていました^^; 20%程でした。ありがとうございます。
guest

回答3

0

ベストアンサー

バブルソートを使ってやってみましたが個数だけ昇順になり、文字のほうはどうやって多い順に出力するのかわかりませんでした。

個数がソートできたのなら、ソートのロジックは出来ているので、
char hyoji_moji[27]={'a','b',~~'z',' '};というのを作って、
ソートの中でmoji[i]moji[j]を交換する時に一緒にhyoji_moji[i]hyoji_moji[j]を交換すれば良いです。
で、表示の時はi+97じゃなくてhyoji_moji[i]を表示する。

投稿2023/11/07 11:03

otn

総合スコア86295

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

teruterubose

2023/11/08 04:38

回答ありがとうございました。非常に助かりました。
otn

2023/11/08 04:55

変数名を hyoji_moji にしましたが、中身は文字なので mojiにしたかったが、すでにmojiは使われていた。 お書きのコードの moji は、中身が文字じゃなくて個数なので、kosu とか count とかにした方が良いですね。
guest

0

例えば,「配列 moji[] の有効な index 値(0~26)を全部持っている配列」とかいうのを導入すると,表示部分のコードは以下のような感じになります.

C

1// 配列 moji[] の index に使う値を全部持っている配列 2int Index[27] = { 0,1,2,3, ... 25,26 }; 3 4//何もソートしない場合の出力処理はこんな感じ 5for( int i=0; i<27; ++i ) //配列 Index の全要素についてのループ 6{ 7 int iMoji = Index[i]; //moji[] の要素を示すためのindex値 8 printf( "%c %d\n", ( iMoji<26 ? iMoji+97 : 32 ), moji[ iMoji ] ); 9}

この場合,表示よりも前に,配列 Index[] の中身を適切に並び替えてやれば表示順がかわることになりますよね.
(すなわち Index[] を,moji[] に基づいてソートすればよい)


それはそれとして,
表示だけできればよくて(=実際にデータをソートする必要はなくて),且つ,O(N^2) な処理(バブルソート)を使うことを考えても問題無い状況なのであれば,
至極素朴に「値が大きいやつから順に表示」をすればよいだけな気もします.

すなわち,「まだ表示していないやつの中で最大のやつを表示する」を,全ての要素を表示するまで繰り返せばそれで済む気がします.
(選択ソート的な処理で,選択(:ここでは表示)だけするけどデータのソートはしない,みたいな話)

投稿2023/11/07 11:35

編集2023/11/08 02:38
fana

総合スコア12151

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

teruterubose

2023/11/08 04:38

回答ありがとうございました。非常に助かりました。
guest

0

構造体を習っていれば、文字とカウントを一つの構造体にして各文字分の構造体の配列を対象にカウントしたりソートしたりというテもあります。

投稿2023/11/07 13:28

編集2023/11/07 13:29
jimbe

総合スコア13318

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

teruterubose

2023/11/08 04:39

勉強して構造体でもやってみようと思います!ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問