表達式的前中後綴表示和表達式運算

 一、將自然表達式轉換爲前/中/後綴表達式,首先按照自然表達式中操作數和操作符的優先級順序構造出表達式對應的二叉樹,然後對二叉樹進行前序/中序/後序遍歷,即得到前/中/後綴表     達式
 
 二、一些其他的遍歷原則:
 
    1、深度優先遍歷:
 
    首先訪問出發點V,並將其標記爲已訪問過;然後依次從V出發搜索V的每個鄰接點W。若W未曾訪問過,則以W爲新的出發點繼續進行深度優先遍歷,直至圖中所有和源點V有路徑相通的頂點(亦稱爲從源點可達的頂點)均已被訪問爲止。若此時圖中仍有未訪問的頂點,則另選一個尚未訪問的頂點作爲新的源點重複上述過程,直至圖中所有頂點均被訪問爲止。
 
    2、廣度優先遍歷:
    首先訪問出發頂點V,然後訪問與頂點V鄰接的全部未被訪問過的頂點W0,W1,...WK-1;接着再依次訪問與頂點W0,W1,...WK-1鄰接的全部未被訪問過的頂點,以此類推,直至圖的所有頂點都被訪問到,或出發頂點V所在的連通分量的全部頂點都被訪問到爲止。
 
    注:對於樹來說,深度優先就是從左到右,從上到下;廣度優先就是從上到下,從左到右。
三、中綴表達式轉後綴表達式(棧的應用)  
 中綴表達式“9+(3-1)*3+10/2”轉化爲後綴表達式爲“9 3 1- 3 * + 10 2 / +”.
   規則:從左到右遍歷中綴表達式的每一數字和符號,若是數字就輸出,即成爲後綴表達式的一部分;若是符號,則判斷其與棧  頂符號的優先級,是右括號或優先級低於棧頂符號(乘除優先加減)則棧頂元素依次出棧並輸出,並將當前符號進棧,一直到最終輸出後綴表達式爲止。
    a.初始化一空棧,用來對符號進出棧使用。
    b.第一個字符是數字9,輸出9,後面是符號“+”,進棧。
    c.第三個字符是“(”,依然是符號,因其只是左括號,還沒有配對,故進棧。
    d.第四個字符是數字3,輸出,總表達式爲9 3,接着是“-”,進棧。
    e.接下來是數字1,輸出,總表達式爲9 3 1,後面是符號“)”,此時,我們需要去匹配此前的“(”,所以棧頂依次出棧,並輸出,直到“(”出棧爲止。此時左括號上方只有“-”,因此輸出“-”。總的表達式爲9 3 1 -。
    f.接着是數字3,輸出,總的表達式爲9 3 1 - 3.緊接着是符號“*”,因爲此時的棧頂符號爲“+”號,優先級低於“*”,因此不輸出,“*”進棧。
    g.之後是符號“+”,此時當前棧頂元素“*”比這個“+”的優先級高,因此棧中元素出棧並輸出(沒有比“+”更低的優先級,所以全部出棧),總輸出表達式爲9 3 1 - 3 * +。然後將當前這個符號“+”進棧。
    h.緊接着數字10,輸出,總表達式爲9 3 1 - 3 * + 10。後是符號“/”,所以“/”進棧。
    i.最後一個數字2,輸出,總的表達式爲9 3 1 - 3 * + 10 2。
    j.因已經到最後,所以將棧中符號全部出棧並輸出。最終輸出的後綴表達式結果爲9 3 1 - 3 * + 10 2 / +。
四、後綴表達式計算結果(棧的應用)
   後綴表達式爲:9 3 1 - 3 * + 10 2 / +
   規則爲:從左到右遍歷表達式的每個數字和符號,遇到是數字就進棧,遇到是符號,就將處於棧頂兩個數字出棧,進行運算,運算結果進棧,一直到最終獲得結果。
   a.初始化一個空棧。此棧用來對要運算的數字進行進出使用。
   b.後綴表達式中前三個是、都是數字,所以9 3 1 進棧。
   c.接下來是“-”,所以將棧中的1出棧作爲減數,3出棧作爲被減數,並運算3-1得到2,再講2進棧。
   d.接着是數字3進棧。
   e.後面是“*”,也就意味着棧中3和2出棧,2與3相乘,得到6,並將6進棧。
   f.下面是“+”,所以棧中6和9出棧,9和6相加,得到15,將15進棧。
   g.接着是10和2兩數字進棧。
   h.接下來是符號“/”,因此,棧頂的2與10出棧,10與2相除,得到5,將5進棧。
   i.最後一個是符號“+”,所以15與5出棧並相加,得到20,講20進棧。
   j.結果是20出棧,棧變爲空。
簡單的實現代碼:
#include<iostream> 
#include<string>  
#include<stack>  
using namespace std;
stack<char> st1;
stack<int> st2;
int main()
{
	int len1, len2, len, i, j;
	string str1, str2;//str1爲中綴表達式,str2爲後綴表達式 
	//利用棧將中綴表達式轉換爲後綴表達式
	while (1){  
		getline(cin, str1);
		len1 = str1.length();
		str2.clear();
		for (i = 0; i < len1; i++){
			if (str1[i] >= '0' && str1[i] <= '9')
				str2.push_back(str1[i]);
			else{
				if (st1.size() == 0 || str1[i] == '(')
					st2.push(str1[i]);
				else{
					char tmp1 = st1.top();
					if (str1[i] == ')'){
						len = st1.size();
						while (len){
							char tmp = st1.top();
							st1.pop();
							if (tmp == '(')
								break;
							else
								str2.push_back(tmp);
							len--;
						}
					}
					else{
						if (tmp1 == '*' || tmp1 == '/'){
							if (str1[i] == '*' || str1[i] == '/')
								st1.push(str1[i]);
							else{
								len = st1.size();
								while (len){
									char tmp = st1.top();
									str2.push_back(tmp);
									st1.pop();
									len--;
								}
								st1.push(str1[i]);
							}
						}
						else{
							st1.push(str1[i]);
						}
					}
				}
			}
		}
		if (st1.size() != 0){
			len = st1.size();
			while (len){
				char tmp = st1.top();
				str2.push_back(tmp);
				st1.pop();
				len--;
			}
		}
		cout << str2 << endl;
		//由後綴表達式計算結果   
		int temp1, temp2, temp3;
		len2 = str2.length();
		for (i = 0; i < len2; i++){
			if (str2[i] >= '0' && str2[i] <= '9'){
				int t = str2[i] - 48;
				st2.push(t);
			}
			else{
				temp1 = st2.top();
				st2.pop();
				temp2 = st2.top();
				st2.pop();
				if (str2[i] == '+'){
					temp3 = temp2 + temp1;
				}
				else if (str2[i] == '-'){
					temp3 = temp2 - temp1;
				}
				else if (str2[i] == '*'){
					temp3 = temp2 * temp1;
				}
				else if (str2[i] == '/'){
					temp3 = temp2 / temp1;
				}
				st2.push(temp3);
			}
		}
		cout << st2.top() << endl;
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章