我用了兩個棧
一個用來存數字 一個用來存運算符
這里引入優先度的概念便於理解
不同的運算符有不同的優先度
當優先度高的符號進入棧中 所有比它優先度低的符號都要彈出
對 就是這么霸道
(
沒有優先度 沒有運算符能讓它彈出 它也不能讓別的運算符彈出 就是說運算過程中會被一直壓在棧底
*
和/
是 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 ;
}