- ベストアンサー
アルファベットの出現回数を数えるプログラム
- ポインタを用いてアルファベットを順に進めながら、指定の数列内に出現するアルファベットの回数を数えるプログラムです。
- プログラムはランダムに生成された数列内のアルファベットを順にチェックし、出現したアルファベットごとにカウントを増やします。
- 最終的に、アルファベットの出現回数をアルファベットの順に表示します。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。itohhといいます。 まずは、""と''の違いですが、文字列を指定したい場合""にします、''のときは、文字の値 そのものを扱う場合です。 配列(a)の中には、半角英小文字のみ設定されているという条件でサンプルを載せます。 void main(void) { static char a[100]="adhfdfhhlljyerhcvcjhljeyruqqruqruietyiucvnasqasdjh"; // (1) static int count[26]; // (2) int idx; char *alpha; int suu; memset( count, 0x00, sizeof(int)*26 ); // (3) // 文字列の最後まで出現頻度をカウントします。 for( alpha=a; *alpha!='\0'; alpha++ ) // (4) { // 'a'を配列の0番目に'z'を25番目としてカウントします。 idx = *alpha - 'a'; // (5) count[idx]++; } // 'a'から'z'までの件数を出力します。 for(suu='a',idx=0; suu<='z' ; idx++,suu++) printf("%cの出で来た回数は%d\n",suu,count[idx]); } 注意:各行の先頭に全角スペースを入れていますのでカット&コピーするときは気を付けてください。 説明: (1)配列に初期設定する場合、""で囲みます。 (2)アルファベットは26文字なので... (3)件数のカウンタをまとめてzeroクリアします。 (4)alphaの指すアドレスが0x00になるまでループします。 (5)上記でも書きましたが「''」で囲む場合は、文字の値となります、この場合、「'a'」 ですから、0x61という値と同じです。 配列「a」のはじめの文字は「'a'」ですから引き算すると「0」になり、idxに設定されます。 配列「a」の2番目の文字は「'd'」ですから引き算すると「3」になり、idxに設定されます。 これを最後まで繰り返すと「a」から「z」までの配列「count」に出現頻度がカウントされます。 如何でしょうか? もし、判らないところがあれば、補足してください。
その他の回答 (3)
- itohh
- ベストアンサー率45% (210/459)
こんにちは。itohhといいます。 >>memset( count, 0x00, sizeof(int)*26 ); >これはmemsetという関数」なのでしょうか(無知ですいません。)? そのとおりです。 文字列を操作するのに良く使用する関数は。 memset関数:指定の文字で埋める memcpy関数:文字列をコピーする memcmp関数:文字列を比較する strcpy関数:文字列をコピーする(自動的に文字列の最後に「¥0」を代入する) などです。一度、関数マニュアルを見てください。 >>idx = *alpha - 'a'; // (5) >*alphaはchar型ではないのでしょうか?値をもつのですか? alphaは、char型のポインタです。 しかし、*alphaは、char型です。ですから、1バイトを参照することになります。 char型とは、ASCIIコードが設定されていると言うことです。 'a'なら0x61が'b'なら0x62が'z'なら0x7Aが設定されています。ASCIIコード一覧を確認してみてください。 例えば。 *alphaに入っている1バイト目のASCIIコードは、'a'=0x61で、2バイト目は、'd'=0x64です。 (5)では、ASCIIコード同士で引き算をしているということです。 c言語の場合、足し算したからといって文字列が連結されるというわけでもないし、引き算した からといって文字列が分割されるわけではないのです。
- itohh
- ベストアンサー率45% (210/459)
こんにちは。itohhといいます。 すみません、chikako-imagawaさんが考えたソースのアドバイスを忘れていました。 >#include<stdio.h> >main(void) >{ > static char a[100]=’adhfdfhhlljyerhcvcjhljeyruqqruqruietyiucvnasqasdjh’; 「""」と「''」の間違いですね。 > static int count[100]; > int I; > char *alpha,*suu; > alpha=a; > I=0; > while(*alpha!=’\0’) > { > for(*suu=’a’;*suu<=’z’;*suu+=’b’-‘a’) suuは、charポインタです、実態がないところには、「'a'」は設定できません。 suuは、int型にするべきでしょう。 > { > if(*alpha==*suu) ++count[I]; > ++I; > } このループは、「'a'」から「'z'」まで行いますが、「I」カウンタがalphaの2文字目以降も どんどんカウントアップされ続けてしまいます。 「*suu+=’b’-‘a’」で1づつカウントアップするということが、お判りなのですから forループを使わない方法(わたしが示したサンプルのように)を考えられるのではないですか? もし、forループを使うのでしたら、「for(suu='a' ,I=0;」のように行うべきでしょう。 > } このwhileループでは、「alpha」をカウントアップしていません。 > for(*suu=’a’,I=0;*suu<=’z’;++I,*suu+=’b’-‘a’;) printf(“%c の出で来た回数は %d\n”,*suu,count[I]); これも、suuは、charポインタです、実態がないところには、「'a'」は設定できません。 >}
- bin-chan
- ベストアンサー率33% (1403/4213)
C&C++は門外漢なんですが、考え方の参考になりましたら。 配列aの要素を先頭から終端まで見ていく際、出現するのはa-zですよね。 最後に出現回数をa-zの順で表示することでもあるし、 判定対象の文字毎にa-zのループを回すのではなく、 「文字コードからカウント用の配列の添え字を求める」のが簡単では? (カウント用の配列countは26あれば良い)
補足
アドバイスありがとうございます。 >memset( count, 0x00, sizeof(int)*26 ); これはmemsetという関数」なのでしょうか(無知ですいません。)? >idx = *alpha - 'a'; // (5) *alphaはchar型ではないのでしょうか?値をもつのですか? すいませんが教えてください。