后缀转换和评估的中缀,包括空格和双引号

时间:2019-06-08 21:26:52

标签: c

我有下面的代码,但是我需要代码来说明空格和两位数,例如,如果我输入(7-3)/(2 + 2),它应该显示为73-22 + /结果: 1.如果我输入(7-3)/(2 + 2),它应该出来7 3-2 2 + /结果1.如果我输入(22-10)/(2 + 2),它应该出来22 10 -2 2 + /结果:3

这是我的代码:

#include<stdio.h>
char stack[100];
int top = 0;
int eval_top = -1;
int eval_stack[100];

void push(char x) // Push char into stack
{
  stack[top++] = x;
}
char pop() // Pop char to top of stack
{
  if (top == -1)
    return -1;
  else
    return stack[top--];
}

/* functions for evaluation of postfix expression */
// push function
void eval_push(int x) { // Find push result
  eval_stack[++eval_top] = x;
}
// pop function
int eval_pop() { // Find pop result
  if (eval_top == -1) {
    return -1;
  } else {
    return eval_stack[eval_top--];
  }
}

int priority(char x) // check priority order
{
  if (x == '(')
    return 0;
  if (x == '+' || x == '-')
    return 1;
  if (x == '*' || x == '/')
    return 2;
}
// function to evaluate the postfix expression
void EvalPostfix(char postfix[]) {

  int A, B;
  int val;
  char ch;
  int i;

  //find postfix
  for (i = 0; postfix[i] != ')'; i++) {
    ch = postfix[i];
    if (isdigit(ch)) {
      eval_push(ch - '0');
    } else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {

      A = eval_pop();
      B = eval_pop();

      switch (ch) {
      case '*':
        val = B * A;
        break;

      case '/':
        val = B / A;
        break;

      case '+':
        val = B + A;
        break;

      case '-':
        val = B - A;
        break;
      }

      eval_push(val); //send value on top of stack
    }
  }
  printf("\n Result: %d \n", eval_pop());
}

main() {
  int i = 0;
  char * e, x;
  char postfix[100]; // store postfix for later evaluation
  char exp[100];
  printf("Infix expression : ");
  scanf("%s", exp); // asking the user to enter the infix expression
  printf("Postfix expression: ");
  e = exp;
  while ( * e != '\0') {
    if (isalnum( * e)) { // if character is alphabet or number , it is printed
      printf("%c", * e);
      postfix[i++] = * e;
    } else if ( * e == '(') // if it is open parenthesis, it is pushed into the stack without any priority
      push( * e);
    else if ( * e == ')') // if it is closed parenthesis , pop the elements in the stack and print them until the we see ( symbol
    {
      while ((x = pop()) != '(') {
        printf("%c", x);
        postfix[i++] = x;
      }
    } else // if character is symbol like +, -, *, / then based on their priority character is pushed if it high priority otherwise high priority symbols are popped and it is pushed
    {
      while (priority(stack[top]) >= priority( * e)) {
        x = pop();
        printf("%c", x);
        postfix[i++] = x;
      }
      push( * e);
    }
    e++;
  }
  while (top != -1) // printing remaining elements in the stack
  {
    x = pop();
    printf("%c", x);
    postfix[i++] = x;
  }
  postfix[i] = ')'; // this is to add at the end for detecting end by the evaluation function
  EvalPostfix(postfix);
}

1 个答案:

答案 0 :(得分:1)

您的代码中存在一些问题

您的 pop 与您的 push 不对称, push 会增加索引,因此 pop 必须预先减少索引,因此第一个无效索引不是-1而是0:

char pop() // Pop char to top of stack
{
  if (top == 0)
    return -1;
  else
    return stack[--top];
}
如果所有测试都为假,

priority 不会返回值,但是最后一个测试可能没用

while (priority(stack[top]) >= priority( * e))

您错过检查堆栈是否为空,必须为:

while ((top != 0) && (priority(stack[top]) >= priority( * e))) {

因为 stack 的第一个无效索引为0而不是-1

  

while(top!= -1)//打印堆栈中的剩余元素

必须

while (top != 0) // printing remaining elements in the stack

在制作后缀表达式时,数字之间没有分隔,例如,“ 12 + 3”变成“ 123+”,例如“ 1 + 23”,在 EvalPostfix 中,您考虑一个数字只能有一位数字(eval_push(ch - '0');),因此您不能管理多于一位数字的数字。要管理几个数字,请在所有数字后添加一个分隔符,例如,空格为“ 12 3 +”或“ 1 23 +”,并使用 scanf

读取数字

在所有情况下,您都不能正确编写后缀表达式,例如对于1 + 2 * 3,您将生成12 + 3 *,但它必须为123 * +

您没有检测到无效的中缀表达式


while (priority(stack[top]) >= priority( * e))

我错过了说顶部元素不是stack[top]而是stack[top - 1],所以必须将其替换为

while ((top != 0) && (priority(stack[top - 1]) >= priority( * e))) {

加上校正1 + 2 * 3会生成正确的后缀表达式123 * +

请注意,引入函数 empty() tops()更为清晰,如果对堆栈的访问无效,则会显示一条消息并退出,而不是返回-1作为 char

int empty()
{
   return (top == 0);
}

char tops()
{
   if (top == 0) {
     fputs("top() on the empty stack, abort", stderr);
     exit(-1);
   }
   return stack[top - 1];
}

char pop() // Pop char to top of stack
{
  if (top == 0) {
     fputs("pop() on the empty stack, abort", stderr);
     exit(-1);
  }
  return stack[--top];
}

还检测堆栈的可能溢出:

void push(char x) // Push char into stack
{
  if (top == sizeof(stack)) {
    fputs("stack overflow", stderr);
    exit(-1);
  }
  stack[top++] = x;
}

所以现在您可以做

    while (!empty() && (priority(tops()) >= priority( * e))) {

当然,其他堆栈也是一样

  

我需要代码来说明空格和两位数

两位数的限制性太强,只需管理任何整数即可,因为您可以使用 strtol 提取数字。您也不能使用scanf("%s", exp);来读取完整的表达式,因为它在第一个空格处停了,请使用 fgets