算法笔记 codeup 1918
题目描述
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。(以下的代码添加了括号()和乘方^的情况)
输入
测试输入包含一个测试用例,一个测试用例占一行,一行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当遇到#
时输入结束。
输出
输出精确到小数点后2位。
代码如下:
#include<bits/stdc++.h>
using namespace std;
struct node{
double num;
char op;
int flag;//0 数字 1 操作符
};
string str;
stack<node> s;//操作符栈
queue<node> q;//后缀表达式序列
map<char,int> op;
void change()
{
double num;
node tmp;
for(int i=0;i<str.length();)
{
if(str[i]>='0' && str[i]<='9')
{
tmp.flag=0;
tmp.num=str[i]-'0';//记录操作数的第一个数位
i++;
while(i<str.length() && str[i]>='0' && str[i]<='9')
{
tmp.num=tmp.num*10+(str[i]-'0');
i++;
}
q.push(tmp);
}
else
{
tmp.flag=1;
if(str[i]=='(')
{
tmp.op=str[i];
s.push(tmp);
}
else if(str[i]==')')
{
while(s.top().op!='(')
{
q.push(s.top());
s.pop();
}
s.pop();
}
else
{
while(!s.empty() && op[str[i]]<=op[s.top().op])
{
q.push(s.top());
s.pop();
}
tmp.op=str[i];
s.push(tmp);
}
i++;
}
}
while(!s.empty())
{
q.push(s.top());
s.pop();
}
}
double cal()
{
double tmp1,tmp2;
node cur,tmp;
while(!q.empty())
{
cur=q.front();
q.pop();
if(cur.flag==0)
{
s.push(cur);
}
else
{
tmp2=s.top().num;
s.pop();
tmp1=s.top().num;
s.pop();
tmp.flag=0;
if(cur.op=='+')
tmp.num=tmp1+tmp2;
else if(cur.op=='-')
tmp.num=tmp1-tmp2;
else if(cur.op=='*')
tmp.num=tmp1*tmp2;
else if(cur.op=='/')
tmp.num=tmp1/tmp2;
else if(cur.op=='^')
tmp.num=pow(tmp1,tmp2);
s.push(tmp);
}
}
return s.top().num;
}
int main()
{
std::ios::sync_with_stdio(false);
//设置操作符优先级
op['+']=op['-']=1;
op['*']=op['/']=2;
op['^']=3;
getline(cin,str,'#');
for(string::iterator it=str.end(); it!=str.begin();it--)
{
if(*it==' ')
str.erase(it);//去除表达式中的空格
}
for(string::iterator it=str.begin(); it!=str.end();it++)
{
cout<<*it;
}
cout<<endl;
while(!s.empty())
{
s.pop();//初始化栈
}
change();//中缀变后缀
cout<<setiosflags(ios::fixed)<<setprecision(2)<<cal();
return 0;
}
样例:
文章参考:getline()的使用详解