实验四 堆栈的应用
一、 实验目的
掌握堆栈的使用。
二、 实验内容
1、输入一个数学表达式(假定表达式输入格式合法),计算表达式结果 并输出。
2、数学表达式由单个数字和运算符“+”、“-”、“*”、“/”、“(、) ”构成, 例如 2 + 3 * ( 4 + 5 ) - 6 / 4。
3、变量、输出采用整数,只舍不入。
三、 注意事项
本题测试一定要多找几个测试用例,特别是复杂用例、边界用例。否 则,很容易造成死机或者没有返回结果。
假设输入的表达式正确,即每个左括号都对应一个右括号;
假设不存在括号嵌套的情况;
用栈LIFO的思想,借助数组完成中缀表达式的直接计算。
代码如下:
#include<iostream>
#include<cstdio>
#include<stdlib.h>
#include<string.h>
using namespace std;
string expression;
int num[25],temp[10],i,t;
bool flag=true;//true时对num数组操作,false时对temp数组操作(对括号内进行运算)
int numi=-1,tempi=-1;
void calculate(const char exp,int next){
if(exp=='+'){//'+':存入后一位的数
if(flag) num[++numi]=next;
else temp[++tempi]=next;
}
else if(exp=='-'){//'-':存入后一位的相反数
if(flag) num[++numi]=-next;
else temp[++tempi]=-next;
}
else if(exp=='*'){//'*':存入前一位和后一位的乘积
if(flag){
t=num[numi];
num[numi]=t*next;
}
else{
t=temp[tempi];
temp[tempi]=t*next;
}
}
else if(exp=='/'){//'/':存入前一位和后一位的商
if(flag){
t=num[numi];
num[numi]=t/next;
}
else{
t=temp[tempi];
temp[tempi]=t/next;
}
}
return;
}
int main(){
char pair;//pair记录左括号前的运算符号
cout<<"Input"<<endl;
cin>>expression;
cout<<"Output"<<endl;
for(i=0;i<expression.length();i++){
if(expression[i]>='0'&&expression[i]<='9'){//如果是数字就压栈
if(flag)num[++numi]=expression[i]-'0';
else temp[++tempi]=expression[i]-'0';
continue;
}
else {
if(expression[i]=='('){//遇到左括号时flag设为false
flag=false;
}
else if(expression[i]==')'){//遇到右括号时flag重设为true并计算得到括号内计算的结果
t=0;
for(int j=tempi;j>=0;j--){t+=temp[j];}
flag=true;
if(pair!=0){calculate(pair,t);pair=0;}
else num[++numi]=t;
tempi=-1;
}
else{//遇到运算符,判断下一位是否是左括号
if(expression[i+1]=='('){//是
flag=false;
pair=expression[i];
i++;
}
else{//不是,正常计算
calculate(expression[i],expression[i+1]-'0');
i++;
}
}
}
}
int ans=0;//最终将num数组中所有的值加起来得到表达式的结果
for(int j=numi;j>=0;j--){ans+=num[j];}
cout<<ans<<endl;
cout<<"End"<<endl;
return 0;
}
结论分析与体会:
老师在课上讲了后缀表达式的过程。直接用中缀表达式需要两个栈来实现不带括号嵌套的表达式计算,括号嵌套的可以用三个栈去实现。
以上代码是提交平台的代码,其实可以对运算部分(加减乘除)的方法进行优化,在主函数里判断flag后将数组作为参数传入。