要求是能够进行+-*%以及括号,输入的式子在10000位以内。输入的是中缀表达式,我的思路是转后缀表达式。但是没怎么学会。而且还要提示异常输入。最麻烦的是数字和运算符之间可能有空格!
#include<cstdio>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
using namespace std;
struct node
{
double num;
char op;
bool flag; //true 为数字
};
stack<node> st;
queue<node> q;
map<char,int> mp;
string str;
void Change() //中缀转后缀
{
node temp,tempst; //temp用于存队首元素,tempst存栈顶元素
for(int i = 0;i < str.length();)
{
if(str[i]>='0'&&str[i]<='9') //如果是数字
{
temp.num = str[i] - '0';
temp.flag = true;
i++;
while(i < str.length() && str[i]>='0' && str[i] <= '9') //数字可能不止一位
{
temp.num = temp.num * 10 + str[i] - '0';
i++;
}
q.push(temp);
}
else //是运算符
{
temp.op = str[i];
temp.flag = false;
if(!st.empty())
tempst = st.top();
while(!st.empty() && mp[temp.op] <= mp[tempst.op]) //与栈顶运算符优先级比较
{ // 只有优先级大于栈顶操作符才直接入栈,否则将栈中操作符压入队列
q.push(tempst);
st.pop();
if(!st.empty())
{
tempst=st.top();
}
}
st.push(temp);
i++;
}
}
while(!st.empty())
{
q.push(st.top());
st.pop();
}
}
double Cal () //计算
{
double num1,num2,num;
node temp,tempst;
while(!q.empty())
{
temp = q.front();
if(temp.flag == true) //队首是数字,压入栈zhong
{
st.push(temp);
}
else //是运算符,从栈中弹出两个数字
{
tempst = st.top();
num2 = tempst.num;
st.pop();
tempst = st.top();
num1 = tempst.num;
st.pop();
if(temp.op == '+') num = num1 + num2;
else if(temp.op == '-') num = num1 - num2;
else if(temp.op == '*') num = num1 * num2;
else if(temp.op == '/') num = num1 / num2;
temp.num = num;
temp.flag = true;
st.push(temp);
}
q.pop();
}
temp = st.top();
return temp.num;
}
int main(void)
{
mp['+'] = mp['-'] = 0;
mp['*'] = mp['/'] = 1;
double num;
while(getline(cin,str),str!="0")
{
for(string::iterator it = str.begin();it!=str.end();it++)
{
if(*it == ' ')
str.erase(it);
}
while(!st.empty())
st.pop();
Change();
num = Cal();
printf("%.2f\n",num);
}
return 0;
}