逆波兰表示法是一种将运算符(operator)写在操作数(operand)后面的描述程序(算式)的方法。举个例子,我们平常用中缀表示法描述的算式(1 + 2)*(5 + 4),改为逆波兰表示法之后则是1 2 + 5 4 + *。相较于中缀表示法,逆波兰表示法的优势在于不需要括号。
请输出以逆波兰表示法输入的算式的计算结果。
输入格式:
在一行中输入1个算式。相邻的符号(操作数或运算符)用1个空格隔开。
输出格式:
在一行中输出计算结果。
限制:
2≤算式中操作数的总数≤100
1≤算式中运算符的总数≤99
运算符仅包括“+”、“-”、“*”,操作数、计算过程中的值以及最终的计算结果均在int范围内。
输入样例1:
4 3 + 2 -
输出样例1:
5
输入样例2:
1 2 + 3 4 - *
输出样例2:
-3
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
一、问题分析及算法设计思路
本题的要求就是通过一个逆波兰表达式,计算出应得的值,根据题意应采取栈的存储方式来进行逆波兰数的计算。首先先将输入的逆波兰表达式存入一个字符串中,循环到’\0’对字符串进行判断。如果当前字符是数字,就将其压入栈中。如果当前字符是运算符,就取出栈顶两个数字进行运算后再压会栈中。如果当前字符是空格,就跳过。最后栈中最后元素便是运算结果。
二、代码实现
#include <stdio.h>
#include <stdlib.h>
#define bool char
#define true 1
#define false 0
#define MaxSize 1000
typedef int ElemType;
//定义栈的结构
typedef struct SqStack
{
ElemType data[MaxSize];
int top;
} SqStack;
//栈的初始化
bool InitStack(SqStack* S)
{
S->top = -1;
return true;
}
//栈判空
bool Empty(SqStack S)
{
if(S.top == -1)
return true;
else
return false;
}
//压栈
bool Push(SqStack* S, ElemType e)
{
//判断栈满的情况
if(S->top == MaxSize-1)
return false;
S->data[++S->top] = e;
return true;
}
//出栈
bool Pop(SqStack* S, ElemType* e)
{
if(S->top == -1)
return false;
*e = S->data[S->top--];
return true;
}
//便利测试用
bool Print(SqStack S)
{
for(int i = 0; i < S.top+1; i++)
{
printf("%d ",S.data[i]);
}
return true;
}
int main()
{
//定义和初始化栈
SqStack S1, S2;
InitStack(&S1);
InitStack(&S2);
int answer;
//输入字符串
char str[1000];
gets(str);
char c = str[0];
int i = 0;
for(i = 0; str[i] != '\0'; i++)
{
c = str[i];
int x, t;
//printf("%d ",c);
//如果是数字,压入栈中
if(str[i] <= '9' && str[i] >= '0')
{
t = 0;
while(str[i] <= '9' && str[i] >= '0')
{
x = str[i]-48;
t = t*10 + x;
i++;
}
Push(&S1, t);
i--;
}
//如果是空格,跳过
else if(c == ' ')
continue;
//如果是运算符,进行计算操作
else if(c == '+' || c == '-' || c == '*')
{
int m, p;
Pop(&S1, &m);
Pop(&S1, &p);
if(c == '+')
{
answer = p+m;
}
else if(c == '-')
{
answer = p-m;
}
else if(c == '*')
{
answer = p*m;
}
Push(&S1, answer);
}
}
printf("%d", answer);
return 0;
}
三、程序执行结果