ページ 11

文字列配列について

Posted: 2013年5月17日(金) 17:47
by yuher
ある英文について,標準入力からgetcharで一文字ずつ読み込み,アルファベットのそれぞれの文字が何個あるか集計し,アスタリスクで表示しろ.という問題です.度数はアスタリスクで表示し,大文字、小文字は区別せず,アルファベット以外は無視するとのことです.
ヒントとしては,while,for文を使用するらしいです.
よろしくお願いします.

Re: 文字列配列について

Posted: 2013年5月17日(金) 17:55
by みけCAT
フォーラムルールをお読みください。
課題の丸投げは禁止です。
今書けているコードがありましたら、提示してください。

Re: 文字列配列について

Posted: 2013年5月17日(金) 18:01
by yuher
変数、配列宣言と初期化(文字列を集計する要素数26の配列,ほか)

while(getchar()の戻り値がEOFではない)
if(読み込んだ文字がアルファベット)
その文字に該当する要素を1だけ増やす

頻度の最大値MAXを求める

for (i=0;i<26;i++)
{
i番目の文字の*の個数を計算(maxを使った比例計算)
  行頭の表示(i番目の文字)
  計算した個数だけ*を出力
  行末に頻度を整数で表示

こんな感じにすればいけるのでは?というのはあるのですが,これを言語にすることができません
よろしくお願いします.

Re: 文字列配列について

Posted: 2013年5月17日(金) 18:05
by みけCAT
そのような感じでいいと思います。
どこがわかりませんか?全部ですか?どこがわからないかがわかりませんか?

Re: 文字列配列について

Posted: 2013年5月17日(金) 18:07
by yuhe
C言語を始めたばっかりで、参考書を無理やりこじつけて形にはできたのですが,言語に変換することができません.
全体的に分に変換することができないです。。。

Re: 文字列配列について

Posted: 2013年5月17日(金) 18:24
by みけCAT
うーん…教えるのは難しいですね…

コード:

#include <stdio.h>
#include <ctype.h>

/* *の個数の最大値 */
#define GRAPH_MAX 60

int main(void) {
	/* 変数、配列宣言と初期化(文字列を集計する要素数26の配列,ほか) */
	int input;
	int syuukei[26]={0};
	int i;
	int max=0;

	/* while(getchar()の戻り値がEOFではない) */
	while((input=getchar())!=EOF) {
		/* if(読み込んだ文字がアルファベット) */
		if(isalpha(input)) {
			/* その文字に該当する要素を1だけ増やす */
			if(islower(input))syuukei[input-'a']++;
			else if(isupper(input))syuukei[input-'A']++;
		}
	}

	/* 頻度の最大値MAXを求める */
	for(i=0;i<26;i++) {
		if(syuukei[i]>max)max=syuukei[i];
	}

	if(max==0)max=1; /* ゼロ除算防止 */

	for(i=0;i<26;i++) {
		/* i番目の文字の*の個数を計算(maxを使った比例計算) */
		int kazu=syuukei[i]*GRAPH_MAX/max;
		int j;
		/* 行頭の表示(i番目の文字) */
		printf("%c : ",i+'A');
		/* 計算した個数だけ*を出力 */
		for(j=0;j<kazu;j++)putchar('*');
		/* 行末に頻度を整数で表示 */
		printf(" %d\n",syuukei[i]);
	}

	return 0;
}

Re: 文字列配列について

Posted: 2013年5月17日(金) 18:26
by yuher
ありがとうございます.これを見てじっくり考えてみます!

Re: 文字列配列について

Posted: 2013年5月17日(金) 18:37
by yuher
int kazu=syuukei*GRAPH_MAX/max;

すいません,この行だけちょっとわからないです.
syuukei*GRAPH_MAX/max;とはどういうことですか?

Re: 文字列配列について

Posted: 2013年5月17日(金) 18:42
by みけCAT
その文字の個数から表示すべき*の個数を求めています。
syuukeuをmaxで割ってsyuukeiのmaxに対する割合を求めます。
この割合をGRAPH_MAX(max個あるアルファベットに対する*の表示個数)に掛けて表示すべき*の個数を求めます。
これをそのまま書くとGRAPH_MAX*(syuukei/max)となりますが、C言語では整数の割り算は切り捨てになるため、
最初の表現になっています。

Re: 文字列配列について

Posted: 2013年5月17日(金) 18:52
by yuher
やり方,可能な処理かわかりませんが,kazuというのを浮動小数点で表示することなどはできないのでしょうか。

Re: 文字列配列について

Posted: 2013年5月17日(金) 18:57
by みけCAT
できます。なぜ必要なのですか?それともただの興味ですか?

コード:

double kazu=(double)syuukei[i]*GRAPH_MAX/max;
double型の変数をprintfでひょうじするには%fを使用します。

Re: 文字列配列について

Posted: 2013年5月17日(金) 19:03
by yuher
すいません,浮動小数点を利用すればsyuukei*GRAPH_MAX/max;の形を変換できるものだと思っていました.
計算自体を浮動小数点で計算してもsyuukei*GRAPH_MAX/max;の形は変えられないのでしょうか?

Re: 文字列配列について

Posted: 2013年5月17日(金) 19:07
by みけCAT
浮動小数点なら任意の順番で大丈夫だと思います。(多少の誤差はでるかもしれませんが)

コード:

double kazu=(double)syuukei[i]*GRAPH_MAX/max;
double kazu=(double)GRAPH_MAX*syuukei[i]/max;
double kazu=(double)syuukei[i]/max*GRAPH_MAX;
double kazu=(double)GRAPH_MAX/max*syuukei[i];
double kazu=1.0/max*syuukei[i]*GRAPH_MAX;
double kazu=1.0/max*GRAPH_MAX*syuukei[i];