对于输入字符串要单独考虑 对于优先级函数返回值只有几种情况而没有考虑所以情况编译器会报错!
#include<cstdio>
#include<iostream>
#include<stack>
#include<string>
using namespace std;
stack<char> oper;
stack<float> num;
string str;
int getnextnum(unsigned int* i) {//计算某个数后面是否还是一个数 连续读入两个符号间的所以数字 并且把i的值也要变化
int sum = str[i] - '0';
int temp = 0;
while (str[i + 1] >= '0' && str[i + 1] <= '9') {
temp = str[i + 1] - '0';
sum = sum * 10 + temp;
(*i)++;
}
return sum;
}</float></char></string></stack></iostream></cstdio>
int priority(char a) { //给运算符定义优先级
if (a == '#')
return 0;
if (a == '$')
return 1;
if (a == '+' || a == '-')
return 2;
if (a == '*' || a == '/')
return 3;
else return 4; //这一步非常重要 虽然没什么意义但是如果不给其他情况(虽然没有其他情况)给返回值 编译会不通过
}
void calculate() {//把运算数栈栈顶两个元素弹出,把运算符栈顶一个符号弹出作为运算符 计算这两个数的值 然后把结果压入运算数栈中
float m, n, sum=0.0f;
char a;
n = num.top();
num.pop();
m = num.top();
num.pop();
a = oper.top();
oper.pop();
if (a == '+')
sum = m + n;
else if (a == '-')
sum = m - n;
else if (a == '*')
sum = m * n;
else if (a == '/')
sum = m / n;
num.push(sum);
}
void func(int x, int i) { //由于每个判断都有大量重复的代码 所以用个功能函数简化main函数行数
while (1) {//循环知道找到一个比运算符栈顶符号优先级要大的符号
if (priority(oper.top()) < x) {//如果当前符号比运算符栈顶的优先级大 则压入运算符栈
oper.push(str[i]);
break;
}
else {//否则就执行calculate函数
calculate();
}
}
}
int main() {
while (getline(cin, str)) {//获取一行字符串
if (str == "0")//如果为0就执行下一次循环
continue;
while(!oper.empty())//当栈不为空就弹出所以元素 oper.pop(); while (!num.empty())//当栈不为空就弹出所以元素 num.pop(); oper.push('#'); str.push_back('$'); for (unsigned int i = 0; i < str.size(); ++i) {//遍历字符串 注意如果不用unsigned定义会报错 因为str.size()是无符号数 if (str[i] >= '0' && str[i] <= '9') { num.push(getnextnum(&i));//获取之后所以数字并压入运算栈中 } else if (str[i] == '+') { func(2, i); } else if (str[i] == '-') { func(2, i); } else if (str[i] == '*') { func(3, i); } else if (str[i] == '/') { func(3, i); } else if (str[i] == '$') { if (oper.top() == '#') oper.push(str[i]); else { while (oper.top() != '#') calculate(); oper.push('$'); } } } if(!num.empty()) printf("%0.2f\n", num.top());//输出 } return 0;
}