逆ポーランド式

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

逆ポーランド式

#1

投稿記事 by YUM » 14年前

2桁以上の自然数の逆ポーランド式の計算プログラムを作成したいのですが、
3桁以上になったり、沢山の数値を計算をしようとするとうまくいきません。
解決法がわかる方がいらっしゃいましたら教えていただければ幸いです。
よろしくお願いします。

また、数値間のみの区切りとして'z'を挿入し、区切り文字までは
ひとつの数値としてます。

コード:

#include <stdio.h>
#include <stdlib.h>

void init_stack();
int push(int);
int pop();

int stack[100];
int sp;

char expr[100];

int main(){
  int i=0,j=0,a,b,c;
  char ch;

//数値の外部入力
  printf("入力:");
  fgets(expr,20,stdin);

  init_stack();
  while(expr[j]!='\n'){
      printf("%c",expr[j]);
      j++;
    }

  printf("\n\n");

  while(expr[i]!='\n'){

    if(expr[i]=='+'){
      b=pop();
      a=pop();
      c=a+b;
      printf("a=%d\n",a);
      printf("b=%d\n",b);
      printf("a+b=%d\n\n",c);
    }else if(expr[i]=='-'){
      b=pop();
      a=pop();
      c=a-b;
      printf("a=%d\n",a);
      printf("b=%d\n",b);
      printf("a-b=%d\n\n",c);
    }else if(expr[i]=='*'){
      b=pop();
      a=pop();
      c=a*b;
      printf("a=%d\n",a);
      printf("b=%d\n",b);
      printf("a*b=%d\n\n",c);
    }else if(expr[i]=='/'){
      b=pop();
      a=pop();
      c=a/b;
      printf("a=%d\n",a);
      printf("b=%d\n",b);
      printf("a/b=%d\n\n",c);
    }else if(expr[i]=='z'){
      b=pop();
      a=pop()*10;
      c=a+b;
    }else {
      ch=expr[i];
      c=atoi(&ch);
    }
    push(c);
    i++;

  }

  printf("A. %d\n",stack[sp-1]);
}
//スタック初期化
void init_stack(){
  sp=-1;
}
//スタックにプッシュ
int push(int n){
  stack[sp]=n;
  sp++;
  return 0;
}
//ポップする
int pop(){
  sp--;
  return (stack[sp]);
}

アバター
ゆーずぃ
記事: 62
登録日時: 14年前
住所: 埼玉県

Re: 逆ポーランド式

#2

投稿記事 by ゆーずぃ » 14年前

YUM さんが書きました:沢山の数値を計算をしようとするとうまくいきません。
一応聞きますが、19バイト以内に収まる入力をして、ですよね?

アバター
bitter_fox
記事: 607
登録日時: 14年前
住所: 大阪府

Re: 逆ポーランド式

#3

投稿記事 by bitter_fox » 14年前

YUM さんが書きました:

コード:

        else if(expr[i]=='z'){
              b=pop();
              a=pop()*10;
              c=a+b;
            }
zが来たら一つ前(一桁目:b)ともう一つ前の値(二桁目:a)を取り出して、
aを十倍してそれにbを足したものをcにいれて、
cをスタックにプッシュしてるためです。
これだと、2桁のものしか扱えません。

zを区切りに使用する必要はあるのでしょうか??
やるとしたら、zをトークンとしてstrtokで分割していくか、
zでない間、数値をバッファに加算してzでなかったら、バッファを10倍して行くか、
数値のプッシュをする際にカウンタを回して、zが来たらそのカウンタ数までバッファを十倍してポップして値をバッファに加算・・・を繰り返すしてループを抜けた時にプッシュするという方法でしょうか・・・

アバター
bitter_fox
記事: 607
登録日時: 14年前
住所: 大阪府

Re: 逆ポーランド式

#4

投稿記事 by bitter_fox » 14年前

bitter_fox さんが書きました: zでない間、数値をバッファに加算してzでなかったら、バッファを10倍して行くか、
類似の各桁の足し算をするプログラムをサンプルとして、書いてみました。

コード:


#include <stdio.h>

void main()
{
	char str[256];
	int buffer = 0, counte;

	scanf("%255s", str); // 文字列を取得

	for (counter = 0; counter < strlen(str); counter++) // 配列外を参照してしまわないように
	{
		if (str[counter] == 'z') // もしzがあればそこが区切り
		{
			printf("%d\n", buffer); // bufferを出力

			return;
		}

		if (str[counter] < '0' || str[counter] > '9') // 入力が0~9で無かったら
		{
			printf("Error: 数値以外のものがありました\n");

			return;
		}

		buffer += str[counter]-'0'; // bufferにその桁の数値を加算
	}

	printf("Error: zがありませんでした\n"); // ここまでにzがなかった
}


YUM

Re: 逆ポーランド式

#5

投稿記事 by YUM » 14年前

なんとかなりました、ご返答ありがとうございました。

閉鎖

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