前缀表达式--转换+求值
生活随笔
收集整理的這篇文章主要介紹了
前缀表达式--转换+求值
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
到現在寫的比較多的是后綴表達式,然而到前綴表達式還沒什么思路
這里整理一下中綴表達式轉前綴表達式及前綴表達式的求值
中綴轉前綴
轉換原則
有個比較簡單的看法:(選擇題可以用)
將中綴表達式按計算順序加括號,前綴表達式則將括號中的運算符移到括號前面,后綴則移到后面,再將所有括號去掉即可
eg.
注意要在運算符對應括號層級移動
實現思路
不同于后綴表達式,前綴表達式相當于倒著掃描(從右往左);且后綴表達式可以直接輸出,前綴要先放到棧里再彈出(實現翻轉)(即前綴出來首先是反著的)
先看一下轉前綴與轉后綴的對比,下面再仔細寫實現思路
從右往左掃描:
代碼
先轉一個后綴
python
from pythonds.basic.stack import Stackdef infixToPostfix(infixexpr):prec = {}prec["*"] = 3prec["/"] = 3prec["+"] = 2prec["-"] = 2prec["("] = 1opStack = Stack()postfixList = []tokenList = infixexpr.split()for token in tokenList:if token in "QWERTYUIOPASDFGHJKLZXCVBNM" or token in "1234567890":postfixList.append(token)elif token == '(': # 左括號直接壓入棧中opStack.push(token)elif token == ')': # 讀到右括號就把棧中的操作符彈出直到讀到(topToken = opStack.pop()while topToken != '(':postfixList.append(topToken)topToken = opStack.pop()else:while (not opStack.isEmpty()) and \(prec[opStack.peek()] >= prec[token]): # 只要棧里面的操作符比目前讀到的操作符優先級高,就優先輸出棧中的操作符postfixList.append(opStack.pop())opStack.push(token) # 將讀到的字符壓入棧中while not opStack.isEmpty(): # 將棧中的剩余字符全部彈出postfixList.append(opStack.pop())return " ".join(postfixList)print(infixToPostfix(input()))C++
#include<bits/stdc++.h> using namespace std; int main() {string s;getline(cin,s);stack<char> mark;map<char,int> lst;lst['+'] = lst['-'] = 1;lst['*'] = lst['/'] = 2;bool flag=1;for(int i=0;i<s.length();i++){//先處理直接輸出的——數字if(isdigit(s[i]) || s[i]=='.' || ((!i||s[i-1]=='(') && (s[i]=='+' || s[i]=='-'))){if(!flag) cout << " ";else flag=0;if(s[i]!='+') cout << s[i];while(s[i+1]=='.' || isdigit(s[i+1]))cout << s[++i];}else{if(s[i]=='(') mark.push(s[i]);else if(s[i]==')'){while(!mark.empty()&&mark.top()!='('){cout << " " << mark.top();mark.pop();}mark.pop();}else if(mark.empty() || lst[s[i]]>lst[mark.top()]) mark.push(s[i]);else{while(!mark.empty()&&lst[mark.top()]>=lst[s[i]]){cout << " " << mark.top();mark.pop();}mark.push(s[i]);}}}while(!mark.empty()){cout << " " << mark.top();mark.pop();} }前綴
正在調試中ing…
前綴表達式求值
💿 借題👉PTA
基本想法
最簡單的就像樣例中一樣,沒有小數和負數,先完成這個
按剛剛實現的思路,求值也得是先求后面(倒著求)
先跑到最里面——>堆棧 or 遞歸
用遞歸實現起來更直觀(畢竟底層用的堆棧)
因為是前綴表達式,操作符肯定都在前面,因此把操作符——入棧
若遇到數字,就取出一個操作符,兩個操作數進行處理了然后繼續循環,直到所有操作數處理完畢
復雜情況
完整思路:
- 若是空格,直接將x壓入棧B
- 若是小數點,再取小數點下一個數,直到遇到空格,合并得到完整小數,壓入B
- 若是數字,表示則表明x和y同為某一小數的小數部分,且y是x的前一位,則不斷循環,直到找到小數點,再加上小數點后面的數字,3者合并,得到一個完整的小數,然后壓入堆棧B中
總體來說,前綴表達式不用管優先級,遇到運算符就用
寫了改改了不對不對又寫然后寫了好幾天的代碼……
一開始是寫到小數點那整蒙了……
將數字字符轉成對應數字
但是問題是要是碰到不止一位數就要倒著X10相加,然后要是又是小數的話碰到小數點還得10的倒數再換……
所以使代碼復雜的是獲取完整數字這一塊
那就先從頭遍歷,截取完整的數字串,用stof轉換成小數存到棧里(非數字也直接入棧),然后出棧再算
然后是日常糾結的代碼……
總結
以上是生活随笔為你收集整理的前缀表达式--转换+求值的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SETP7 Basic V11 SP2
- 下一篇: FHS