BUAA_数据结构_4TH_计算器(表达式计算-后缀表达式实现)
题目描述:
从标准输入中读入一个整数算术运算表达式,如24 / ( 1 + 5%3 + 36 / 6 / 2 - 2) * ( 12 / 2 / 2 )= ,计算表达式结果,并输出。
要求:
1、表达式运算符只有+、-、*、/、%,表达式末尾的=字符表示表达式输入结束,表达式中可能会出现空格;
2、表达式中会出现圆括号,括号可能嵌套,不会出现错误的表达式;
3、出现除号/时,以整数相除进行运算,结果仍为整数,例如:5/3结果应为1。
4、要求采用逆波兰表达式来实现表达式计算。
输入形式
从键盘输入一个以=结尾的整数算术运算表达式。操作符和操作数之间可以有空格分隔。
输出形式
在屏幕上输出计算结果(为整数,即在计算过程中除法为整除)。
思路
最朴素的思路应为中缀转后缀 之后进行运算
但这里我们采用在转换的同时进行计算的思路。
具体思路如下:
设立两个栈:数据栈和符号栈
从输入的表达式中获取一个元素:
若此元素为数字则压入数据栈(此处需要考虑如何处理1234,254,这类>=10的数字 处理方法在下面代码中 有需要可以酌情参考)
若此元素不为数字:
- 为等号:跳出循环 并不断弹栈进行运算
- 为空格:continue即可
- 为):不断弹栈并计算直到符号栈中弹出(
(此处注意弹出(之后不进行计算)- 为(,+,*,/,-则从符号栈中弹出优先级高于当前的符号并与数据栈元素进行运算 将计算结果压回数据栈中 知道遇到一个优先级低的符号 然后将当前符号压入栈中
易错点
- 栈空的时候进行弹栈/查看栈顶元素操作
- 未处理空格
- 遇到等号跳出循环之后未对仍在栈中的元素进行运算
- 符号优先级
- 数字处理
参考代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define maxN 200
char middle[maxN+10];
char op_stack[maxN+10];
int pos_op;
int num_stack[maxN+10];
int pos_num;
int is_empty();
int is_full();
void push(char x);
char pop();
char look();
void push_num(int x);
int pop_num();
int is_number(char x);
int cal(char op,int num1,int num2);
int get_pri(char x);
int main()
{
pos_op=-1;
pos_num=-1;
int num1,num2;
int cal_temp;
char op;
gets(middle);
int len=strlen(middle);
for(int i=0;i<len;i++){
if(is_number(middle[i])){
int num=0;
while(is_number(middle[i])){
num=num*10+middle[i]-'0';
i++;
}
push_num(num);
}
if(middle[i]==' ') continue;
if(middle[i]=='=') break;
if(middle[i]==')'){
while(1){
op=pop();
if(op=='(') break;
num2=pop_num();
num1=pop_num();
cal_temp=cal(op,num1,num2);
push_num(cal_temp);
}
}
else{
if(is_empty()){
push(middle[i]);
continue;
}
char stack_top=look();
while(get_pri(stack_top)>=get_pri(middle[i])){
if(stack_top=='(') break;
op=pop();
num2=pop_num();
num1=pop_num();
cal_temp=cal(op,num1,num2);
push_num(cal_temp);
if(is_empty()) break;
stack_top=look();
}
push(middle[i]);
}
}
while(!is_empty()){
op=pop();
num2=pop_num();
num1=pop_num();
cal_temp=cal(op,num1,num2);
push_num(cal_temp);
}
int res=pop_num();
printf("%d\n",res);
return 0;
}
int is_empty()
{
if(pos_op==-1){
return 1;
}
else{
return 0;
}
}
int is_full()
{
if(pos_op==maxN-1){
return 1;
}
else{
return 0;
}
}
void push(char x)
{
op_stack[++pos_op]=x;
}
char pop()
{
char res=op_stack[pos_op];
op_stack[pos_op]='\0';
pos_op--;
return res;
}
char look()
{
return op_stack[pos_op];
}
int is_number(char x)
{
if(x>='0'&&x<='9') return 1;
else return 0;
}
void push_num(int x)
{
num_stack[++pos_num]=x;
}
int pop_num()
{
int res=num_stack[pos_num];
num_stack[pos_num]='\0';
pos_num--;
return res;
}
int cal(char op,int num1,int num2)
{
switch(op){
case '+':
return num1+num2;
case '-':
return num1-num2;
case '*':
return num1*num2;
case '/':
return num1/num2;
case '%':
return num1%num2;
}
}
int get_pri(char x)
{
switch(x){
case '+':
return 0;
case '-':
return 0;
case '*':
return 1;
case '/':
return 1;
case '%':
return 1;
case '(':
return 2;
case ')':
return 2;
}
}
有问题
或bug欢迎私戳/评论