ページ 11

アルファベットの検定

Posted: 2007年6月13日(水) 15:30
by minami
前回「乱数の検定」のトピックを立てさせてもらったminamiです
乱数の検定については無事終了しましたが、今度の課題は
テキストファイル内のデータ(a~Zまでの52文字の羅列)について検定するものです

基本的な質問かもしれませんが、アルファベットを取り扱うプログラムはASCIIコード
に変換して処理したほうがいいのでしょうか?

Re:アルファベットの検定

Posted: 2007年6月13日(水) 16:05
by 管理人
アスキーコードに変換して・・という意味がよくわからないのですが、
minamiさんは具体的にどうやって変換しようとしているのですか?

char c='1';
printf("%c\n",c);
printf("%d\n",c);

printf("%c\n",1);
printf("%d\n",1);

printf("%c\n",'1');
printf("%d\n",'1');

アスキーコード表を見ながら上記の説明が出来れば、文字列処理はかなりスムーズに進むと思います。

Re:アルファベットの検定

Posted: 2007年6月13日(水) 17:01
by keichan
isalpha 関数を使っちゃダメなんですか?

Re:アルファベットの検定

Posted: 2007年6月13日(水) 17:23
by minami
管理人さん、返信ありがとうございます。

説明不足ですみません。

今の状態は、test.txtにアルファベットの羅列が入っています。
プログラム上でファイルを読み込むと同時に
①アルファベットの出現頻度を検定する
②その羅列の連検定を実施する

①については下のようなプログラムになったのですが
②については2次元配列を利用して作成しようと思ってます。
/* ファイル中の英文字の出現頻度を調べる */
void Count(FILE *fp)
{
    int c;
      /* ファイルの終わりに達するまで1文字読み込む */
    while ((c = getc(fp)) != EOF)
          /* c がアルファベットの小文字か大文字なら */
        if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') 
            C[c]++;        /* カウントする */
}
②では2次元配列を使って
アルファベットの羅列が「BcfnihxichaqyffchFUjlcmihJ・・・・」だったら
[Bc][cf][fn][ni][ih][hx][xi]とファイルから読み込むと同時に
2次元配列でカウントしていく感じで作成しようと考えてます。
a b c ・・・・・y z A B C・・・・・Y Z
------------------------------------------
a| 1 3・・・・・・・・・ 6・・・・・・・2 
b| 0 4 5 ・・・・・6 7 4 0 4 ・・・・ 4 6
c| 2・・・・・・・ 9 2 7 3 0 ・・・・ 5 2
・|
・|
・|
y|
z|
A|
B|
・|
・|
・|
Y|
Z|
 
 

こういうイメージで
横の座標が、連の文字「●▲」における一文字目(●)で、縦の座標が二文字目(▲)
をあらわしていて、"「●▲」が出た時点で縦と横の交点に1カウントする"
という感じにするとプログラムが書きやすいのかな?を思ってます。
長々と書いてしまいました。
自分のわからないことを人に説明するのって意外と難しいですね・・・ m(__)m

Re:アルファベットの検定

Posted: 2007年6月13日(水) 17:27
by minami
投稿して自分のレスをみたら、表のところがずれていました。
すみません
横の「a b c・・・Y Z」がもう少し右よりです。

Re:アルファベットの検定

Posted: 2007年6月13日(水) 19:09
by フリオ
 
 急ごしらえですが、とりあえずできました。
表示は、適当なので、ご自身で工夫してください。
#include <stdio.h>
#include <ctype.h>

#define CHMAX 256

void ChTest(int chtest[/url][CHMAX], int freq[/url], FILE *fp)
{
	int ch0, ch1, i, j;
	
	ch0 = fgetc(fp);
	freq[ch0] ++;
	if(ch0 != EOF){
		while((ch1 = fgetc(fp)) != EOF){
			chtest[ch0][ch1] ++;
			ch0 = ch1;
			freq[ch0] ++;
		}
	}
	return;
}

void PrintResult(int chtest[/url][CHMAX], int freq[/url])
{
	int i, j;
	
	printf("  ");
	for(i = 0; i < CHMAX; i ++) if(isalpha(i))printf("%c", i);
	puts("  freq");
	for(i = 0; i < CHMAX; i ++){
		if(!isalpha(i)) continue;
		printf("%c ", i);
		for(j = 0; j < CHMAX; j ++){
			if(isalpha(j)){
				printf("%d", chtest[j]);
			}
		}
		printf("    %d\n", freq);
	}
	return;
}
int main(void)
{
	FILE *fp;
	int chtest[CHMAX][CHMAX] = {0,};
	int freq[CHMAX] = {0,};
	
	if((fp = fopen("test.txt", "r")) == NULL) return 1;
	ChTest(chtest, freq, fp);
	fclose(fp);
	PrintResult(chtest, freq);
	return 0;
}

 

Re:アルファベットの検定

Posted: 2007年6月13日(水) 19:14
by フリオ
 
> freq[ch0] ++;
> if(ch0 != EOF){

ここは、

if(ch0 != EOF){
freq[ch0] ++;

です。
 

Re:アルファベットの検定

Posted: 2007年6月13日(水) 20:17
by minami
フリオさん、ありがとうございます。

今までmain関数の中での処理ばかりしてたので、こうやって関数をいくつか使って
プログラムするとすごく見やすくなるのですね。

しかも、アルファベットの出現頻度と連なりの検定をひとつのプログラムで
できるとは思ってもいませんでした。

文字処理マクロ等、勉強不足のところも多々ありますがフリオさんのプログラム
を参考に自分なりのプログラム作成に励みます。

またわからないときはよろしくお願いします。

Re:アルファベットの検定

Posted: 2007年6月14日(木) 08:22
by minami
おはようございます
昨日、アルファベットの検定について質問したminamiです。

フリオさんのプログラムを見ながら勉強したのですが、ChTest関数のところが
よくわからなくてこまってます。
6行目ではテキストファイル中のアルファベット、1文字1文字についての
出現頻度を求めていると思うんですが、
9行目の[ch0]と[ch1]については、連なりの検定をしているところでいいんですか?

5行目でch0にテキストファイルの文字を読み込んで、8行目でch1に同じテキストファイルから
読み込んでいますよね
だから、9行目の[ch0][ch1]は同じ文字(テキストファイルの1文字目)になるのではないでしょうか?
私の勉強不足で、初歩的な疑問かもしれませんが、ここのところがちょっと判らなかったので
また質問させてもらいました。
1: void ChTest(int chtest[/url][CHMAX], int freq[/url], FILE *fp)
2: {
3: 	int ch0, ch1, i, j;
4: 	
5:	ch0 = fgetc(fp);
6:	freq[ch0] ++;
7:	if(ch0 != EOF){
8:		while((ch1 = fgetc(fp)) != EOF){
9:			chtest[ch0][ch1] ++;
10:			ch0 = ch1;
11:			freq[ch0] ++;
12:		}
13:	}
14:	return;
15: }