SDIBT2666——逆波兰表达式求值

逆波兰表达式求值(栈和队列)

Description

从键盘上输入一个逆波兰表达式,用伪码写出其求值程序。规定:逆波兰表达式的长度不超过一行,以@符作为输入结束,操作数之间用空格分隔,操作符只可能有+、-、*、/四种运算。例如:

请输入一个以'@'字符结束的中缀算术表达式: 
12+(3*(20/4)-8)*6@ 
对应的后缀算术表达式为: 
12 3 20 4 /*8 -6 *+@ 
求值结果为:54

Input

12+(3*(20/4)-8)*6@ 

Output

54

中序表达式转换为逆波兰表达式:

从中缀式的左端开始取字符,逐序进行如下步骤(需要一个栈S1和一个数组)
  (1)若取出的字符是操作数,则分析出完整的运算数,该操作数直接送入数组
  (2)若取出的字符是运算符,则将该运算符与S1栈栈顶元素比较,如果该运算符优先级大于S1栈栈顶运算符优先级,则将该运算符进S1栈,否则,将S1栈的栈顶运算符弹出,送入数组中,直至S1栈栈顶运算符低于(不包括等于)该运算符优先级,则将该运算符送入S1栈。
  (3)若取出的字符是“(”,则直接送入S1栈栈顶。
  (4)若取出的字符是“)”,则将距离S1栈栈顶最近的“(”之间的运算符,逐个出栈,依次送入数组,此时抛弃“(”。
  (5)重复上面的1~4步,直至处理完所有的输入字符
  (6)若取出的字符是“#”,则将S1栈内所有运算符(不包括“@”),逐个出栈,依次送入数组。
逆波兰表达式计算:
  新建一个表达式,如果当前字符为变量或者为数字,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。
PS:
  注意最后一个数字的处理!!
Code:
  1 #include<stdio.h>
  2 #define MAXN 10000
  3 typedef struct Stack
  4 {
  5     int date[MAXN];
  6     int top;
  7 } Stack;
  8 struct BL
  9 {
 10     int date;
 11     int ischar; //计算时 判断是运算符还是数值
 12 } a[1000];
 13 Stack s1;
 14 void Stack_Init(Stack *S)
 15 {
 16     S->top=-1;
 17 }
 18 int IsEmpty(Stack *S)
 19 {
 20     if (S->top==-1) return 1;
 21     return 0;
 22 }
 23 void push(Stack *S,int tmp)
 24 {
 25     S->top++;
 26     S->date[S->top]=tmp;
 27 }
 28 int pop(Stack *S)
 29 {
 30     int tmp;
 31     tmp=S->date[S->top];
 32     S->top--;
 33     return tmp;
 34 }
 35 int top(Stack *S)
 36 {
 37     return S->date[S->top];
 38 }
 39 int main()
 40 {
 41     char tmp;
 42     int i=0,j,num=0,t,t1,t2;
 43     Stack_Init(&s1);
 44     while (scanf("%c",&tmp)!=EOF)
 45     {
 46         if (tmp=='@')
 47         {
 48             if (num)
 49             {a[i].date=num;
 50             a[i++].ischar=0;}
 51             break;
 52         }
 53         if (tmp>='0'&&tmp<='9') num=num*10+tmp-48;
 54         else
 55         {
 56             if (num)
 57             {
 58                 a[i].date=num;
 59                 num=0;
 60                 a[i++].ischar=0;
 61             }
 62             if (tmp=='(') push(&s1,tmp);
 63             else if (tmp==')')
 64             {
 65                 while (top(&s1)!='(')
 66                 {
 67                     t=pop(&s1);
 68                     a[i].date=t;
 69                     a[i++].ischar=1;
 70                 }
 71                 pop(&s1);
 72             }
 73             else if (tmp=='+'||tmp=='-')
 74             {
 75                 while (IsEmpty(&s1)!=1&&top(&s1)!='(')
 76                 {
 77                     t=pop(&s1);
 78                     a[i].date=t;
 79                     a[i++].ischar=1;
 80                 }
 81                 push(&s1,tmp);
 82             }
 83             else if (tmp=='*'||tmp=='/')
 84             {
 85                 while (IsEmpty(&s1)!=1&&(top(&s1)!='+'&&top(&s1)!='-')&&top(&s1)!='(')
 86                 {
 87                     t=pop(&s1);
 88                     a[i].date=t;
 89                     a[i++].ischar=1;
 90                 }
 91                 push(&s1,tmp);
 92             }
 93         }
 94     }
 95     while (IsEmpty(&s1)!=1)
 96     {
 97         t=pop(&s1);
 98         a[i].date=t;
 99         a[i++].ischar=1;
100     }
101     for (j=0; j<i; j++)
102         if (a[j].ischar)
103         {
104             t1=pop(&s1);t2=pop(&s1);
105             if (a[j].date=='*'){t1=t2*t1;push(&s1,t1);}
106             if (a[j].date=='/'){t1=t2/t1;push(&s1,t1);}
107             if (a[j].date=='+'){t1=t2+t1;push(&s1,t1);}
108             if (a[j].date=='-'){t1=t2-t1;push(&s1,t1);}
109         }
110         else push(&s1,a[j].date);
111     printf("%d",top(&s1));
112     return 0;
113 }
原文地址:https://www.cnblogs.com/Enumz/p/3760650.html