实验目的
掌握栈的基本操作算法的实现,包括栈初始化、进栈、出栈、取栈顶元素等
掌握利用栈实现中缀表达式求值的算法
实验内容
输入一个中缀算术表达式,求解表达式的值。运算包括“+”,“-”,“*”,“/”,”(”,”)”,“=”参加运算的数为double类型且为正数。(要求:直接使用中缀算术表达式进行计算,不能转换为后缀或前缀表达式再进行计算,只考虑二元运算即可)
输入要求:
多组数据,每组数据一行,对应一个算术表达式,每个表达式均以“=”结尾,当表达式只要一个“=”时,输入结束。参加运算的数为“double”类型。
输出要求:
对每组数据输出1行,为表达式的运算结果。保留2位小数
输入样例:
2+2=
20*(4.5-3)=
=
输出样例:
4.00
30.00
设计思路
创建两个栈,一个放数字,一个放字符。从左到右读取中缀算术表达式,读到数字则将数字放入数字栈,读到字符则根据优先级判断计算顺序:遇到括号先算括号里面的;两个相邻的字符,先算优先级高的。当读到中缀算术表达式末尾时,输出表达式的计算结果,清空两个栈准备读取下一个中缀算术表达式,并进行计算。当中缀算术表达式为‘=’时,退出程序。
代码及注释
主要参考了这个代码:https://blog.youkuaiyun.com/weixin_44652407/article/details/103963877
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stack>
using namespace std;
int pre (char c)//返回优先级次序
{
if (c=='+'||c=='-' ) return 1; // + - 返回1
else if (c=='*'||c=='/' ) return 2; // * / 返回2
else return 0; // = ( 返回0
}
void calculate (stack<double> &num,stack<char> &cha)//四则运算
{
double a=num.top();//读数字栈头
num.pop(); //出栈
double b=num.top();//读数字栈头
num.pop();//出栈
char c=cha.top();//读字符栈头
cha.pop();//出栈
switch (c)//加减乘除运算
{
case '+' : num.push(b+a); break;//加
case '-' : num.push(b-a); break;//减
case '*' : num.push(b*a); break;//乘
case '/' : num.push(b/a); break;//除
}
}
int main()
{
stack<double> num;//存数字的栈
stack<char> cha;//存字符的栈
while (1)
{
char s[100];
scanf ("%s",s);//读取中缀算术表达式
if (!strcmp(s,"=")) break;//只输入“=”则退出循环
for (int i=0;s[i]!='\0';i++)//遍历中缀算术表达式每一个字符
{
if (isdigit(s[i]))//读取数字
{
double temp=atof(&s[i]);//将字符串转为浮点型
num.push(temp);//将该数字入栈
while (isdigit(s[i])||s[i]=='.') i++;//已遍历完该数字,将i移到该数字最后一位
i--;
}
else //读取字符
{
if (cha.empty()) cha.push(s[i]);//字符栈为空,入栈
else if (s[i]=='(') cha.push(s[i]);//字符为左括号,入栈
else if (s[i]==')') //字符为右括号
{
while (cha.top()!='(') calculate (num,cha);//计算括号内的表达式
cha.pop();//将左括号出栈
}
else if (pre(s[i])>pre(cha.top())) cha.push(s[i]);//字符优先级大于字符栈头的优先级,入栈
else if (pre(s[i])<=pre(cha.top())) //字符优先级小于字符栈头的优先级
{
while (!cha.empty()&&pre(s[i])<=pre(cha.top())) calculate (num,cha);//计算前面的表达式直到字符优先级大于字符栈头的优先级
cha.push(s[i]);//字符入栈
}
}
}
printf ("%.2f\n",num.top());//输出中缀算术表达式的计算结果
num.pop();//清空数字栈
cha.pop();//清空字符栈
}
return 0;
}