#include#includechar sfex[1000]; //儲存後序表示式,雖然沒用到棧的性質,但下面的注釋還是用字尾棧來描述
void transform()else if(ch=='+'||ch=='-')else if(ch=='*'||ch=='/')
else
i--; //為了統一,因為判斷跳出後有i++移至下一字元
sfex[t++] = '$'; //字尾棧中每個數字後加分隔符}}
while(top!=0)sfex[t++]=stack[top--];//符號棧仍有元素就把符號棧剩下的元素壓進數字棧
sfex[t] = '#'; //後序表示式的最後加乙個#作為結束符方便計算
for(int x=1;x='0'&&ch<='9')
stack[++top]=d; //數字壓入棧
}ch=sfex[t++]; //讀出當前字元,而且剛好跳過了數字的#
}printf("\n%g\n",stack[top]); //輸出(數字)棧頂值就是結果
}int main()
/***
in 2*3+4*(11+22)/3+1
out 2$3$*4$11$22$+*3$/+1$+
51***/
證明:
從操作角度看
解字尾時,開臨時數字棧,每讀到乙個字元就合併棧頂兩個元素
生字尾時,開字尾棧sfex即suffix expression與臨時符號棧
1、先不看括號,易發現數字與符號是交錯的,演算法中數字直接入字尾棧,加減乘除四個符號都是倒序(因為數字正序押入)押完前面若干個符號入字尾後,自己再入符號棧,這就保證了他的運算分隔了左右的數,一定是對左右的部分進行運算;
2、在解字尾表示式時由左到右掃先出現的符號先運算,所以符號押入字尾棧的先後就是運算的先後,且易知每一時刻符號棧中由頂到底的符號優先順序是依次降低的;
3、考慮括號,左括號時是不執行操作的,但出現右括號後就把兩括號間的符號依次打進字尾棧,這保證了括號進麵的運算形成乙個整體,在解字尾時必然括號內的表示式優先會形成乙個數
4、最後看四則運算,加減號會把符號棧頂的加減乘除壓入字尾棧,這就是說押入符號棧時棧頂只能是左弧或者空,而乘除號會把符號棧頂的乘除壓入字尾棧,就是說乘除插入符號棧時棧頂只能是左弧或者加減,不難理解,加減在乘除下面則必然導致乘除先出棧再到加減出棧,也就是乘除先於加減運算
從整體角度看,分了加減,乘除,括號三種優先順序的符號來運算
加減優先順序最低,所以符號棧裡的待入字尾棧符號,包括同級的加減(從左往右計算所以同級的先入棧的加減也是優先於當前加減)和乘除都可以馬上入字尾棧,因為比當前符號優先運算
乘除次之,符號棧棧頂的同級的乘除先入棧(從左往右計算原則)
括號優先順序最高(範圍最高),一出場就要保證裡面的要先算完再算括號外面,所以括號包著的都可以入字尾棧
逆波蘭表示式 字尾表示式
字首表示式又稱波蘭式,字首表示式的運算子位於運算元之前。比如 3 4 5 6中綴表示式就是常見的運算表示式,如 3 4 5 6字尾表示式又稱逆波蘭表示式,與字首表示式相似,只是運算子位於運算元之後,比如 3 4 5 6 人類最熟悉的一種表示式1 2,1 2 3,3 42 4等都是中綴表示法。對於人們...
字尾表示式 逆波蘭表示式 轉換
維基百科 字尾表示式 將中綴表示式轉換為字尾表示式,比如 5 2 8 3 4轉換為5 2 8 3 4 將表示式的字元逐一處理,如果是數字 變數 則直接輸出,如果是字元入棧,並按以下規則進行處理.低優先順序,所以將棧中的所有運算子出棧,之後將自己入棧.or 高優先順序,將棧中的其他乘除運算子出棧,之後...
表示式的逆波蘭表示
字尾表示式又叫逆波蘭表示式。那麼如何講中綴表示式轉化為字尾表示式呢?比如已知中綴表示式a b c d e f g,如何將其轉化為字尾表示式abc de f g 呢?有4個基本原則。1.當讀到運算元時,立即輸出 由字尾表示式的形式明顯可以看出,運算元的輸出優先順序要比操作符要高 當讀到操作符時,並不立...