課題が・・・

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
774

課題が・・・

#1

投稿記事 by 774 » 16年前

こんばんわ、また課題でどうすればいいのかがわからなくなったので来ました。
今回の課題は1*2+3と式を文字列入力したらポーランド記法で表示して計算結果を取り出す、というプログラムです。
条件があって、()とマイナスの考慮で入れ方をツリー構造体で入れていくという条件です。

今、計算と()の判断とマイナス考慮はとりあえず置いておいて、表示ができるように使用としています。
プログラムの作り方は式を入力したら関数内に飛び、引地として持ってきた文字列を後ろからfor文とif文で+とーから検索、次に数字を*と/を検索という演算子の検索優先順位にして、それを抜けたら数字を入れていき、再帰プログラムでツリーができるまで続けるというようにます。
ですが、途中まで行くと無限ループになってしまいます。
よく見てみてもわからないのですが、どこをどう直せばいいのでしょう。

これが今のプログラムのソースの状態です。
関数内のスペースもtabスペースもしていないprintfのものは確認用のprintfです。
#include <stdio.h>
#include <string.h>

#define N 50

/*構造体の宣言*/
struct node
{
	char str[N];
	struct node *left;
	struct node *right;
};

void print_tree(struct node *p);
struct node *kansu(char str[/url]);
int main(void)
{
	struct node	*root;
	char d[N];
	int i, j = 0;	
	
	/* ツリー作成 */
	printf("文字列入力 ");
	fgets(d, 100, stdin);
	d[strlen(d) - 1] = '\0';     /* 余分な改行コードを削除 */
	
	do
	{
		root = NULL;	//ルートにNULLを入れる
		root = kansu(d);	//入力した値dをkansu関数の引値として入れてルートに入れる
		print_tree(root);	//rootをprint_tree関数の引地として入れる

		printf("\n");
		printf("文字列入力 ");
		fgets(d, 100, stdin);
		d[strlen(d) - 1] = '\0';     /* 余分な改行コードを削除 */
	}
	while(strcmp(d, "quit") != 0);

	return 0;
}

//ツリー出力 
void print_tree(struct node *p)
{
	if(p!=NULL)
	{
		print_tree(p->left);
		print_tree(p->right);
		printf("%c", p->str[N]);
	}
}
struct node *kansu(char str[/url])
{
	int i;
	char rstr[N], lstr[N];
	struct node *p;

printf("い%s\n", str);
	for(i=strlen(str)-1; str != '+' && str != '-' && i>=0; i--);	//+とーを探索するループ
	
	if(str == '+' || str == '-')	//もしstrが+かーだったら
	{
printf("ろ%c\n", str);
		p->str[0] = str;
		p->str[1] = '\0';
	}
	else	//そうでなかったら
	{
printf("は%s\n", str);
		for(i=strlen(str)-1; str != '*' && str != '/' && i>=0 ; i--);	//*と/を探索するループ
printf("に%c\n", str);
		if(str[i] == '*' || str[i] == '/')
		{
			p = malloc(sizeof(struct node));
			p->right = NULL;
			p->left = NULL;
printf("ほ%c\n", str[i]);
			p->str[0] = str[i];
			p->str[1] = '\0';
		}
	}
	
	if(str[i] != '+' && str[i] != '-' && str[i] != '*' && str[i] != '/')	//もし数字だったら
	{
		p = malloc(sizeof(struct node));
		p->right = NULL;
		p->left = NULL;
printf("へ%c\n", str[i+1]);
		str[i] = str[i+1];
		p->str[0] = str[i];
		p->str[1] = '\0';	
	}
	else	//そうでなかったら
	{
		strcpy(rstr, str+i+1);
printf("と%s\n", rstr);
		strncpy(lstr, str, i);
		lstr[i] = '\0';
printf("ち%s\n", lstr);
	}
	
	/* 再帰部分 */
	p->right = kansu(rstr);
	p->left = kansu(lstr);
	
	return p;
}


以上がソースの内容です。
どうかよろしくお願いしますm( )m

たいちう

Re:課題が・・・

#2

投稿記事 by たいちう » 16年前

間違っている所が4-5箇所あったよ。まだ残っていたらすまん。
void print_tree(struct node *p)
{
	if(p!=NULL)
	{
		print_tree(p->left);
		print_tree(p->right);
		printf("%c", p->str[0]);
	}
}
struct node *kansu(char str[/url])
{
	int i;
	char rstr[N] = { '\0' }, lstr[N] = { '\0' };
	struct node *p;

	for(i=strlen(str)-1; str != '+' && str != '-' && i>=0; i--);	//+とーを探索するループ

	if(str == '+' || str == '-')	//もしstrが+かーだったら
	{
		p = malloc(sizeof(struct node));
		p->right = NULL;
		p->left = NULL;
		p->str[0] = str;
		p->str[1] = '\0';
	}
	else	//そうでなかったら
	{
		for(i=strlen(str)-1; str != '*' && str != '/' && i>0 ; i--);	//*と/を探索するループ
		if(str == '*' || str == '/')
		{
			p = malloc(sizeof(struct node));
			p->right = NULL;
			p->left = NULL;
			p->str[0] = str[i];
			p->str[1] = '\0';
		}
	}
	
	if(str[i] != '+' && str[i] != '-' && str[i] != '*' && str[i] != '/')	//もし数字だったら
	{
		p = malloc(sizeof(struct node));
		p->right = NULL;
		p->left = NULL;
		p->str[0] = str[i];
		p->str[1] = '\0';
	}
	else	//そうでなかったら
	{
		strcpy(rstr, str+i+1);
		strncpy(lstr, str, i);
		lstr[i] = '\0';
	}
	
	/* 再帰部分 */
	if (rstr[0])
		p->right = kansu(rstr);
	if (lstr[0])
		p->left = kansu(lstr);
	
	return p;
}

たいちう

Re:課題が・・・

#3

投稿記事 by たいちう » 16年前

もう少しで自力で完成できたのでは?惜しかったね。
文字列"1*2+3"の入力は当然試したと思うけど、
"3"や"1*2"とかのみの入力は試しましたか?
最も簡単なケースでデバッグを始めると良いでしょう。

774

Re:課題が・・・

#4

投稿記事 by 774 » 16年前

ミスの指摘ありがとうございます!
メモリの確保や判定等が色々忘れていたんですね・・・気をつけます。
3と1*2・・・それは試してませんでした。以後、気をつけます。
ご指摘ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る