手直しをお願いします

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

手直しをお願いします

#1

投稿記事 by kwzi » 2年前

#include<stdio.h>
char stack[10];
int sp=0;

/*文字列を左から右に1つずつプッシュし、
成功ならば1、失敗ならば0を返す関数*/
//引数は文字列shibauraであり戻り値は0と1である

int push(char c)
{
if(sp==10){ //スタック内がいっぱいになっている時
return 0; //0を返す
}
stack[sp]=c; //文字列を格納していく
sp++;
return 1; //格納が成功している時は1を返す
}

/*格納されている文字を最後に入れたものから順に
取り出していく関数*/
//引数は無し、戻り値は0と文字列である
char pop()
{
if(sp<0){ //もうスタック内に値がないとき
return 0; //0を返す
}
sp--;
return stack[sp]; //文字列を返す
}

int main()
{
int a,i;
char str[100];
printf("鍵かっこのを含むものを入力してください:");
scanf("%s",str);
for(i=0;i<100;i++)//判別を繰り返し状況に応じてpush popをする
{
if(str=='(')
{
push(str);
}
else if(str=='{')
{
push(str);
}
else if(str==')')//(があるか判別
{
a = pop();
if(a !='(')
{
printf("ERROR");
return 0;
}
}
else if(str=='}')//{があるか判別
{
a = pop();
if(a !='{')
{
printf("ERROR");
return 0;
}
}
else if(str=='\0')//配列の中に何もなくなった時
{
break;
}
else continue;
}
printf("OK");
return 0;//プログラム終了
}

もっと簡単にできる気がするのですが、どこか短縮できたりしませんか?

アバター
あたっしゅ
記事: 663
登録日時: 13年前
住所: 東京23区
連絡を取る:

Re: 手直しをお願いします

#2

投稿記事 by あたっしゅ » 2年前

東上☆海美☆「例によって

コード:

[i]
が抜けてるみみ。

コード:

//
// https://dixq.net/forum/viewtopic.php?f=3&t=21147&sid=01524759808da6a78ead8450a081d8e8
// 手直しをお願いします - ミクプラ(ja)
//
#include<stdio.h>

const int STACKMAX = 10;
char stack[STACKMAX];
int sp = 0;

/*文字列を左から右に1つずつプッシュし、
成功ならば1、失敗ならば0を返す関数*/
//引数は文字列shibauraであり戻り値は0と1である

int push(char c)
{
	if (sp == STACKMAX) { //スタック内がいっぱいになっている時
		return 0; //0を返す
	}
	stack[sp] = c; //文字列を格納していく
	sp++;

	return 1; //格納が成功している時は1を返す
}

/*格納されている文字を最後に入れたものから順に
取り出していく関数*/
//引数は無し、戻り値は0と文字列である
char pop()
{
	if (sp < 0) { //もうスタック内に値がないとき
		return 0; //0を返す
	}
	sp--;

	return stack[sp]; //文字列を返す
}

#define str(x) #x
int main()
{
	int a, i;
	const int BUFMAX = 100;
	char str[ BUFMAX ];

	printf("{}かっこのを含むものを入力してください:");
	//int max = scanf_s("%" str(BUFMAX - 1)  "s", str, BUFMAX);
	scanf_s("%99s", str, BUFMAX);

	for (i = 0; str[ i ]!=0; i++)//判別を繰り返し状況に応じてpush popをする
	{
		int s = str[i];

		printf( "[%d]%c\n", i, (char)s );
		if (s == '(')
		{
			push(s);
		}
		else if (s == '{')
		{
			push(s);
		}
		else if (s == ')')//(があるか判別
		{
			a = pop();
			if (a != '(')
			{
				printf("ERROR");
				return 0;
			}
		}
		else if (s == '}')//{があるか判別
		{
			a = pop();
			if (a != '{')
			{
				printf("ERROR");

				return 0;
			}
		}
		else if (s == '\0')//配列の中に何もなくなった時
		{
			break;
		}
		else push(s);
	}

	printf("\nSTACK\n");
	while (1) {
		int a = pop();

		if (a == 0) {
			break;
		}

		printf( "%c", a ); 
	}
	printf("\nOK\n" );

	return 0;//プログラム終了
}


// end.
こんな感じでどうみみ。
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。

中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 手直しをお願いします

#3

投稿記事 by みけCAT » 2年前

あたっしゅ さんが書きました:
2年前
東上☆海美☆「例によって

コード:

[i]
が抜けてるみみ。
抜けてるのは[​i]ではなくcodeタグです。
誠に遺憾ながらソースコードがcodeタグで囲まれずに投稿され、表示がおかしい場合、
引用画面からコピペするのがいいでしょう。


kwziさんへ

ソースコードを提示する際は、BBCodeが有効な(無効にしない)状態で、
BBCodeのcodeタグの開始タグと終了タグの組(開始タグが先)で囲んでいただけると、
見やすくてありがたいです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 手直しをお願いします

#4

投稿記事 by みけCAT » 2年前

あたっしゅ さんが書きました:
2年前
こんな感じでどうみみ。
例えば

コード:

{a}
という入力において、もとのコードではOKになるのに、あたっしゅさんのコードではERRORになります。
どちらが正しい仕様かはわかりませんが。 (もしかしたら両方正しいといえるかも)

さらに、ループの条件として str[ i ]!=0 を指定しているので、
そのループ内で s == '\0' となることは無いはずであり、この判定は無駄でしょう。

また、もとのコードや投稿にはそれを使うべき証拠が見当たらないのに、
環境依存のscanf_s()を使用しているというのはどうなんですかね…?

また、例えば

コード:

{

コード:

{{{{{{{{{{(}}}}}}}}}}
という入力については、カッコの対応はとれていませんが、どちらのコードでもOKになります。
別にこの仕様が間違っているとは限りませんが。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 手直しをお願いします

#5

投稿記事 by みけCAT » 2年前

自分も修正してみました。
入力の最大文字数指定とエラーチェックを加えた以外、仕様は変えていないと思います。

コード:

#include<stdio.h>
#include<limits.h>

#define STACK_MAX 10
#define INPUT_MAX 99

char stack[STACK_MAX];
int sp=0;

/*文字を左から右に1つずつプッシュし、
成功ならば1、失敗ならば0を返す関数*/
//引数は文字であり戻り値は0か1である

int push(char c)
{
	if(sp == STACK_MAX){		//スタック内がいっぱいになっている時
		return 0;		//0を返す
	}
	stack[sp++]=c;		//文字を格納していく
	return 1;			//格納が成功している時は1を返す
}

/*格納されている文字を最後に入れたものから順に
取り出していく関数*/
//引数は無し、戻り値は0か文字である
char pop(void)
{
	if(sp < 0){			//もうスタック内に値がないとき
		return 0;		//0を返す
	}
	return stack[--sp];		//文字を返す
}

int main(void)
{
	// 正の数はその文字をpushするべきことを、負の数はその文字がpopされるべきことを表す
	static const int push_info[UCHAR_MAX + 1] = {
		['('] = '(', [')'] = -'(',
		['{'] = '{', ['}'] = -'{'
	};

	int i;
	char str[INPUT_MAX + 1];
	printf("鍵かっこのを含むものを入力してください:");
#define TO_STR_I(x) #x
#define TO_STR(x) TO_STR_I(x)
	if(scanf("%" TO_STR(INPUT_MAX) "s", str)!=1){
		fputs("scanf() failed\n", stderr);
		return 1;
	}
#undef TO_STR
#undef TO_STR_I
	for(i = 0; str[i] != '\0'; i++)//判別を繰り返し状況に応じてpush popをする
	{
		int info = push_info[(unsigned char)str[i]];
		if(info > 0){
			push(info);
		} else if(info < 0){
			if(pop() != -info){
				printf("ERROR");
				return 0;
			}
		}
	}
	printf("OK");
	return 0;//プログラム終了
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

返信

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