前面做了棧的基本操作
總感覺需要做乙個實際的例子來檢驗一下。
這裡我將用棧來做乙個簡單的四則運算。
目標比較簡單:
做乙個帶小括號(「()」)的四則運算,如果要加入到中括號(「」)或者大括號(「{}」),依次類推。
求乙個表示式:
用下面這個算是做例子,程式最後應該可以算出任何帶小括號的運算。
3+(32-6)*9+5*3-(3*(65-15)/5)+12;
方法一:字尾法。
1.了解中綴和字尾表示法
中綴表示法:剛才的那個算是就是中綴表示法,我們通常看到的數學符號就是中綴表示法,即數字在計算符號的兩邊。
字尾表示法:所有的計算符號在數字之後。不包含括號,運算子放在兩個運算物件的後面,所有的計算按運算子出現的順序,嚴格從左向右進行。
原理:從左到右遍歷表示式,如果是數字則輸出,如果是符號:判斷該符號與棧頂的符號優先順序,
如果是右括號或者優先順序低於棧頂符號,則棧中元素依次出棧並輸出,並且將當前符號進棧。
對上面的式子進行處理:
後序表示式用處:
當轉換成後序表示式後更方便計算表示式的值,如將後序表示式的元素依次進棧直到遇到運算子,這時候從棧中彈出兩個元素,再結合運算子計算出這兩個數運算的結果(如6-9=3),將其結果壓棧(此時棧元素為3 23 -3),然後繼續將後序非符號元素壓棧,直到遇到運算子。重複之前的操作。。。
infixexp(中序表示式)轉換postfixexp(後序表示式)演算法:
1)當輸入的是運算元時候,直接輸出到後序表示式postfixexp序列中
2)當輸入開括號時候,把它壓棧
3)當輸入的是閉括號時候,先判斷棧是否為空,若為空,則發生錯誤並進行相關處理。若非空,把棧中元素依次彈出並輸出到postfix中,知道遇到第乙個開括號,若沒有遇到開括號,也發生錯誤,進行相關處理
4)當輸入是運算子op(+、- 、×、/)時候
a)迴圈,當(棧非空and棧頂不是開括號and棧頂運算子的優先順序不低於輸入的運算子的優先順序)時,反覆操作:將棧頂元素彈出並新增到postfix中
b)把輸入的運算子op壓棧
5)當中序表示式infixexp的符號串行全部讀入後,若棧內扔有元素,把他們依次彈出並放到後序表示式postfixexp序列尾部。若彈出的元素遇到空括號,則說明不匹配,發生錯誤,並進行相關處理
編寫了乙個程式如下: 比較爛
1 #include 2 #includeview code3 #include 4 #include 5
6using
namespace
std;78
int get_proi(char
ch)921}
2223
void predo(string &str)
2435
}36 str =ot;37}
3839
bool in_to_pre(string &str,vector &vec)//
中序-->後序
4058 k =i;
59vec.push_back(elem);60}
61else
if (str[i] == '
+' || str[i] == '
-' || str[i] == '
*' || str[i] == '
/' || str[i] == '
(' || str[i] == ')'
)6268}
69//
in to pre
70int deep = 0;71
for (vector::iterator it = vec.begin();it!=vec.end();it++)
7279
else
80
87//
2.2.如果是 「)」,出棧直到「(」
88else
if (tmp[0] == ')'
)8995if
(opstack.empty())
9699
else
100104
}105
//3.不是括號
106//
3.1 迴圈,當(棧非空 and 棧頂不是開括號 and 棧頂運算子的優先順序 不低於 輸入的運算子的優先順序)時,反覆操作:將棧頂元素退出壓入後序棧中
107else
if (!opstack.empty() && opstack.top().at(0) != '
(' && get_proi(opstack.top().at(0)) >= get_proi(tmp[0
]))108
114opstack.push(tmp);
115}
116//
3.2 壓入 操作符 棧中
117else
118121
}122
}123
while(!opstack.empty())
124128
if (deep != 0
)129
132else
133137
}138
139string cacl(string str1,string str2,string op,stack &opt)
140152
153char t[256
];154
string
s;155
156 sprintf(t, "%f"
, sum);
157 s =t;
158return
s;159
}160
161void do_cacl(vector &vec)
162171
else
172180
}181 cout<
182}
183int
main()
184
2.運算的優先順序:
棧的應用 表示式運算
字首表示式 又稱波蘭表示法 polish notation,或波蘭記法 是一種邏輯 算術和代數表示方法,其特點是操作符置於運算元的前面,因此也稱做字首表示法。中綴表示式 通常將運算子寫在運算量之間,例如a b,這種表示法稱為中綴表示法。字尾表示式 字尾表示法又稱逆波蘭表示法,它是波蘭邏輯學家盧卡西維...
鏈棧的應用 表示式運算
鏈棧的應用 表示式運算 include include using namespace std define selemtype int typedef struct linknode linkstack 判空函式 鏈棧為空返回1 不為空返回0 intisempty linkstack top 初始...
演算法學習 算術表示式
題目描述 implement a basic calculator to evaluate a expression string.the expression string may contain open and closing parentheses the plus or minus sig...