我用了两个栈
一个用来存数字 一个用来存运算符
这里引入优先度的概念便于理解
不同的运算符有不同的优先度
当优先度高的符号进入栈中 所有比它优先度低的符号都要弹出
对 就是这么霸道
(
没有优先度 没有运算符能让它弹出 它也不能让别的运算符弹出 就是说运算过程中会被一直压在栈底
*
和/
是 1
+
和-
的优先度都是 2
最厉害的是)
优先度为3 读到它的时候 栈的头指针要一直向下走 不断弹出运算符 直到碰到第一个(
为止
因为右括号要赶去左括号身边保护它呀
开始我也很懵的
后来自己手动画了两个栈试了几组数据就搞明白了^^
这里就举一个例子吧
还有啊 我这个版本是非高精度的
不过原理都一样
不懂高精度处理的话 可以看我另一篇文章^^
https://blog.csdn.net/qq_42887568/article/details/81435771
include <bits/stdc++.h>
using namespace std;
char a[100] ;
char fz[100] ; // 符号栈
int sz[100] ; // 数字栈
int fhead = 0 ; // 符号栈指针
int shead = 0 ; // 数字栈指针
void math(char f) // 从数字栈中取出栈顶的两个数字 进行 f 运算 结果继续放在栈中
{
switch(f)
{
case '+' : sz[-- shead] += sz[shead + 1] ; break ;
case '-' : sz[-- shead] -= sz[shead + 1] ; break ;
case '*' : sz[-- shead] *= sz[shead + 1] ; break ;
case '/' : sz[-- shead] /= sz[shead + 1] ; break ;
}
-- fhead ;
sz[shead + 1] = 0 ;
}
int main()
{
gets(a);
int len = strlen(a)-1;
for(int i = 0 ; i <= len ; ++ i )
{
// 如果读到 "(" 则直接放入栈中
if(a[i] == '(' ) {
fz[++ fhead] = a[i] ;
continue ;
}
// 如果读到 ")" 则将 "(" 之前的运算符全部出栈
if(a[i]==')') {
while(fz[fhead] != '(')
math(fz[fhead]) ;
-- fhead ;
continue ;
}
// 读到数字直接放在数字栈顶就ok啦
if(a[i] >= '0' && a[i] <= '9'){
++ shead ;
while(a[i] >= '0' && a[i] <= '9')
sz[shead] = sz[shead] *10 + a[i] - '0' ,i++;
i--;
continue;
}
else {
if(a[i] == '/' || a[i] == '*'){
// 如果读到 "/" 或 "*" 直接放在符号栈栈顶
fz[++fhead] = a[i];
continue;
}
else
while(fz[fhead] == '*' || fz[fhead] == '/' || fz[fhead] == a[i]){
// 如果读到 "+" 或 "-"
// 则将栈顶跟自己一样的符号和 "/" "*" 全部弹出
// 这个可以手动列几个式子体会一下 (^-^)
math(fz[fhead]);
}
fz[++ fhead] = a[i] ;
}
}
while(fhead != 0) {
math(fz[fhead]) ;
}
// 当栈中仅有一个数字的时候 运算式的答案就是它啦
cout << sz[shead] ;
return 0 ;
}