Mae向きなブログ

Mae向きな情報発信を続けていきたいと思います。

逆ポーランド記法

H15年春季基本情報技術者試験の午後の問4*1を解いてみました。

#include <stdio.h>

#define TRUE  1
#define FALSE 0

#define MAX 128

double calc(char ex[], int lp);
void push(double t);
double pop(void);

double stack[MAX];
int sp = 0;

int main()
{
  char buf[MAX];
  int len;
  fgets(buf, MAX, stdin);
  len = strlen(buf) - 2;
  printf("%f\n", calc(buf, len));
}

double calc(char ex[], int lp)
{
  int cp;
  double ret, x, y, t;
  int numf, negf;
  
  cp = 0;
  t = 0;
  numf = FALSE;
  negf = FALSE;
  
  while(cp <= lp){
    if (ex[cp] >= '0' && ex[cp] <= '9'){ /* 数字なら */
      t = t * 10 + (ex[cp] - '0');
      numf = TRUE;
    }
    else{
      if (numf == TRUE){ 
	if (negf == TRUE){
	  t = -t;
	  negf = FALSE;
	}
	push(t);
	t = 0;
	numf = FALSE;
      }
      if (ex[cp] == '+'){
	y = pop();
	x = pop();
	t = x + y;
	push(t);
	t = 0;
      }
      if (ex[cp] == '-'){
	if (cp != lp && ex[cp + 1] >= '0' && ex[cp + 1] <= '9')
	  negf = TRUE;
	else{
	  y = pop();
	  x = pop();
	  t = x - y;
	  push(t);
	  t = 0;
	}
      }
      if (ex[cp] == '*'){
	y = pop();
	x = pop();
	t = x * y;
	push(t);
	t = 0;
      }
      if (ex[cp] == '/'){
	y = pop();
	x = pop();
	if (y == 0){
	  printf("error: zero divisor\n");
	  exit(1);
	}
	else
	  t = x / y;
	push(t);
	t = 0;
      }
    }
    cp++;
  }
  ret = pop();
  return ret; 
}

void push(double t)
{
  if (sp < MAX){
    stack[sp] = t;
    sp++;
  }
  else{
    printf("error: stack full, can't push\n");
    exit(1);
  }
}

double pop(void)
{
  double t;
  if (sp > 0){
    sp--;
    t = stack[sp];
  }
  else{
    printf("error: stack empty\n");
    exit(1);
  }
  return t;
}