概念不多说,上题目。
codeup 1918 简易计算器
题目描述
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
样例输入:
30 / 90 - 26 + 97 - 5 - 6 - 13 / 88 * 6 + 51 / 29 + 79 * 87 + 57 * 92
0
1
2
3
样例输出:
12178.21
————————————————
主要思路
1.用栈将中缀表达式转化为后缀表达式,进入队列
2.计算后缀表达式
#include<bits/stdc++.h>
using namespace std;
struct node
{
double num;//记录数字
char op;//记录运算符
bool flag;//标记为数字还是计算符
};
string str;
stack<node> s;
queue<node> q;
map<char,int> op;//标记运算符优先级(operator)
void change()
{
node temp;
for(int i=0;i<str.size();)
{
if(str[i]>='0'&&str[i]<='9')//数字进队列
{
temp.flag=true;//标记为数字
temp.num=str[i++]-'0';//记录数字后i自增
while(i<str.size()&&str[i]>='0'&&str[i]<='9')//提前检测下一位,防止为两位数
{
temp.num=temp.num*10+(str[i]-'0');
i++;//自增
}
q.push(temp);//进队
}
else
{
temp.flag=false;//同理
while(!s.empty()&&op[str[i]]<=op[s.top().op])//与栈顶元素比较
{
q.push(s.top());//若该元素不高于栈顶元素,弹出栈顶元素(如,栈中为“/”,比较元素为“+”,显然栈中优先级更高,所以“/”在队列中位置较‘+’更靠前)
s.pop();//为什么是不高于而不是低于,因为当优先级相同时,谁靠前谁先算,越靠前的越先进栈,所以弹出栈进队
}
//这里的思想只需要记住一点,队列的符号排列顺序即为使用顺序,所以越先进队越先计算,用栈留住优先级低的(同级则为留住靠后,靠后的符号)
temp.op=str[i];
s.push(temp);//为优先级更高的符号,则直接进队
i++;//i自增
}
}
while(!s.empty())//防止遗漏元素
{
q.push(s.top());
s.pop();
}
}
double cal()
{
double temp1,temp2;
node cur,temp;
while(!q.empty())//队列不空
{
cur=q.front();//队首元素赋给cur
q.pop();//赋完元素要出队
if(cur.flag) //如果为数字,则直接进栈
{
s.push(cur);
}
else
{
temp2=s.top().num;//注意这里的进栈,因为减法除法使用的两个数顺序不能颠倒,则先进栈的后出栈,所以先出栈的给temp2
s.pop();
temp1=s.top().num;
s.pop();
temp.flag=true;
if(cur.op=='+') temp.num=temp1+temp2;//四则运算
else if(cur.op=='-') temp.num=temp1-temp2;
else if(cur.op=='*') temp.num=temp1*temp2;
else temp.num=temp1/temp2;
s.push(temp);//每次计算完之后再进栈,即为先计算完的部分,可以视为一个数与剩余部分计算
}
}
return s.top().num;
}
int main()
{
op['+']=op['-']=1;
op['*']=op['/']=2;//map标记符号,用数字代表优先级
while(getline(cin,str),str!="0")//未知数据组数
{
for(string::iterator it=str.end();it!=str.begin();it--)
{
if(*it==' ') str.erase(it);//删除多余空格(如果题干有说明会出现无效字符此处一并删除即可)
}
while(!s.empty()) s.pop();//栈初始化
change();
printf("%.2lf\n",cal());
}
return 0;
}
算法小白,一起努力吧