逆波兰表达式[栈 C 语言 实现]
逆波蘭表達(dá)式
逆波蘭表達(dá)式又叫做后綴表達(dá)式。在通常的表達(dá)式中,二元運(yùn)算符總是置于與之相關(guān)的兩個運(yùn)算對象之間,這種表示法也稱為中綴表示。波蘭邏輯學(xué)家J.Lukasiewicz于1929年提出了另一種表示表達(dá)式的方法,按此方法,每一運(yùn)算符都置于其運(yùn)算對象之后,故稱為后綴表示。
?
a+b ---> a,b,+
a+(b-c) ---> a,b,c,-,+
a+(b-c)*d ---> a,b,c,-,d,*,+
a+d*(b-c)--->a,d,b,c,-,*,+
1、將一個中序表達(dá)式轉(zhuǎn)化成為逆波蘭表達(dá)式
?
構(gòu)造兩個棧S1,S2,S1用來存放表達(dá)式,S2用來暫時存放運(yùn)算符,最后完成后,該棧是清空的。
(1)如果遇到的是數(shù)字,直接進(jìn)棧S1
(2)如果遇到的是左括號,進(jìn)棧S2
(3)如果遇到的是右括號,將S2中的運(yùn)算符全部出棧壓入S1中,注意括號不壓入
(4)如果遇到的運(yùn)算符
?
? ? ? ? ?1.如果此時棧S2為空,則直接將運(yùn)算符加入到棧S2中;
? ? ? ? ?2.如果此時棧S2不為空,當(dāng)前運(yùn)算符的優(yōu)先級大于等于棧頂運(yùn)算符的優(yōu)先級,那么直接入棧S2;
? ? ? ? ?3.如果此時棧S2不為空,當(dāng)前運(yùn)算符的優(yōu)先級小于棧頂運(yùn)算符的優(yōu)先級,則將棧頂運(yùn)算符一直出棧壓入到棧S1中, ?直到棧為空或者遇到一個運(yùn)算符的優(yōu)先級小于等于當(dāng)前遍歷的運(yùn)算符的優(yōu)先級,然后將該運(yùn)算符壓入到棧S2中。 ? ?
(5)遍歷完整個中序表達(dá)式之后,如果棧S2中仍然存在運(yùn)算符,那么將這些運(yùn)算符依次出棧壓入到棧S1中,直到棧為空。
2、利用逆波蘭表達(dá)式求值
?
維護(hù)一個結(jié)果棧S3,該棧最后存放的是表達(dá)式的值。從左至右的遍歷棧S1
(1)如果遇到的是數(shù)字,直接將數(shù)字壓入到S3中
(2)如果遇到的是單目運(yùn)算符,取S3棧頂?shù)囊粋€元素進(jìn)行運(yùn)算之后,將結(jié)果壓入到棧S3中
(3)如果遇到的是雙目運(yùn)算符,取S3棧頂?shù)膬蓚€元素,首先出棧的在左,后出棧的在右進(jìn)行雙目運(yùn)算符的計(jì)算,將結(jié)果壓入到S3中
遍歷完整個棧S1,最后S3中的值就是逆波蘭表達(dá)式的值。
?
棧實(shí)現(xiàn)表達(dá)式計(jì)算【數(shù)據(jù)結(jié)構(gòu)】
思路:
所包含的運(yùn)算符有‘+’,‘-’,‘*’,‘/’,‘(’,‘)’。
(1)建立兩個棧,一個用來存儲操作數(shù),另一個用來存儲運(yùn)算符, 開始時在運(yùn)算符棧中先壓入‘/0’,一個表達(dá)式的結(jié)束符。
(2)然后從左至右依次讀取表達(dá)式中的各個符號(操作數(shù)或者運(yùn)算符);
(3)如果讀到的是操作數(shù)直接存入操作數(shù)棧;
(4)如果讀到的是運(yùn)算符,則作進(jìn)一步判斷:
若讀到的是‘/0’結(jié)束符,而且此時運(yùn)算符棧的棧頂元素也是‘/0’結(jié)束符,則運(yùn)算結(jié)束,輸出操作數(shù)棧中的元素即為最后結(jié)果。
若讀到的是‘(’或者讀到的運(yùn)算符的優(yōu)先級比目前的運(yùn)算符棧中的棧頂元素的優(yōu)先級高,則將運(yùn)算符直接存入運(yùn)算符棧,繼續(xù)讀表達(dá)式中的下一個符號,重復(fù)步驟(3)和(4);
若讀到的是‘)’,而且此時運(yùn)算符棧的棧頂元素是‘(’結(jié)束符,則將運(yùn)算符棧中的棧頂元素退出來,繼續(xù)讀表達(dá)式中的下一個符號,重復(fù)步驟(3)和(4);
若讀到的運(yùn)算符的優(yōu)先級等于或小于之前的運(yùn)算符的優(yōu)先級,則從操作數(shù)中退出2個,從運(yùn)算符中退出一個進(jìn)行運(yùn)算,將運(yùn)算結(jié)果存入操作數(shù)棧;再把之前讀到的運(yùn)算符與目前的運(yùn)算符棧頂比較,重復(fù)步驟(4)(即現(xiàn)在不讀下一個元素);
?
/* 輸入: 9+(3-1)*3+10/2 輸出 20注意:其實(shí)注釋的地方可以用來調(diào)試,本人主要根據(jù)大話數(shù)據(jù)結(jié)構(gòu)的思路寫出來的如果有什么地方錯了,多謝提出。 */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> using namespace std; struct stack{char data[101];int top; };struct stack2{int data1[101];int top; }; struct stack tak; struct stack2 tak2;bool jia(char s){if(s=='+' || s=='-')return true;else return false; } bool ch(char s){if(s=='*' || s=='/')return true;else return false; } int number(int y, int x, char s){if(s=='+')return x + y;if(s=='-')return x - y;if(s=='*')return x * y;if(s=='/' )return x / y; }int main(){char s1[20];scanf("%s",&s1);getchar();tak.top = 0;tak2.top = 0;//中綴表達(dá)式轉(zhuǎn)化為后綴表達(dá)式 for(int i=0;i<strlen(s1);i++){if(s1[i]>='0' && s1[i]<='9'){int tep = s1[i]-'0';while(s1[i+1]>='0' && s1[i+1]<='9'){tep *= 10;i++;tep += s1[i]-'0'; } // printf("%d ",tep);tak2.top++;tak2.data1[tak2.top] = tep;}else{if(tak.top==0 || tak.data[tak.top]=='('){tak.top++;tak.data[tak.top] = s1[i];}else{char temp = tak.data[tak.top];if( jia(temp) && (ch(s1[i]) || jia(s1[i]) || s1[i]=='(') ){tak.top++;tak.data[tak.top] = s1[i]; }else if(ch(temp) && (ch(s1[i]) || s1[i]=='(')){tak.top++;tak.data[tak.top] = s1[i];}else if(s1[i]==')'){while(tak.top>0){if(tak.data[tak.top]=='('){tak.top--;break;} // printf("%c ",tak.data[tak.top]);int t1 = tak2.data1[tak2.top];tak2.top--;int t2 = tak2.data1[tak2.top];int t3 = number(t1,t2,tak.data[tak.top]);tak2.data1[tak2.top] = t3;tak.top--;}}else if(ch(temp) && jia(s1[i])){while(tak.top>0){if(tak.data[tak.top]=='('){break;} // printf("%c ",tak.data[tak.top]);int t1 = tak2.data1[tak2.top];tak2.top--;int t2 = tak2.data1[tak2.top];int t3 = number(t1,t2,tak.data[tak.top]);tak2.data1[tak2.top] = t3;tak.top--;}tak.top++;tak.data[tak.top] = s1[i];}} } }while(tak.top>0){ // printf("%c ",tk.data[tak.top]);int t1 = tak2.data1[tak2.top];tak2.top--;int t2 = tak2.data1[tak2.top];int t3 = number(t1,t2,tak.data[tak.top]);tak2.data1[tak2.top] = t3; // cout<<" t3 = "<<t3<<endl;tak.top--;}printf("%d",tak2.data1[tak2.top]);return 0; }?
轉(zhuǎn)載于:https://www.cnblogs.com/0526yao/p/10372092.html
總結(jié)
以上是生活随笔為你收集整理的逆波兰表达式[栈 C 语言 实现]的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: visio2016 两线相交去圆弧
- 下一篇: 20190501-编写一个函数来查找字符