前綴中綴后綴表達式的計算求值

原文在這里

表達式

前綴表達式(波蘭表達式)

  1. 前綴表達式又稱波蘭式,前綴表達式的運算符位于操作數之前
  2. 舉例說明: (3+4)×5-6 對應的前綴表達式就是 - × + 3 4 5 6

前綴表達式求值

前綴表達式的計算機求值

從右至左掃描表達式,遇到數字時,將數字壓入堆棧,遇到運算符時,彈出棧頂的兩個數,用運算符對它們做相應的計算(棧頂元素 和 次頂元素),并將結果入棧;重復上述過程直到表達式最左端,最后運算得出的值即為表達式的結果

例如: (3+4)×5-6 對應的前綴表達式就是 - × + 3 4 5 6 , 針對前綴表達式求值步驟如下:

  • 從右至左掃描,將6、5、4、3壓入堆棧
  • 遇到+運算符,因此彈出34(3為棧頂元素,4為次頂元素),計算出3+4的值,得7,再將7入棧
  • 接下來是×運算符,因此彈出75,計算出7×5=35,將35入棧
  • 最后是-運算符,計算出35-6的值,即29,由此得出最終結果

中綴表達式

中綴表達式

中綴表達式就是常見的運算表達式,如(3+4)×5-6

中綴表達式的求值是我們人最熟悉的,但是對計算機來說卻不好操作(前面我們講的案例就能看的這個問題),因此,在計算結果時,往往會將中綴表達式轉成其它表達式來操作(一般轉成后綴表達式.)

中綴表達式對于我們人來好搞,計算機他算不算明白,就離譜

計算機不知道怎么算這個優先級

后綴表達式(逆波蘭表達式)

后綴表達式

后綴表達式又稱逆波蘭表達式,與前綴表達式相似,只是運算符位于操作數之后

中舉例說明: (3+4)×5-6 對應的后綴表達式就是 3 4 + 5 × 6 –

再比如:

正常的表達式逆波蘭表達式
a+ba b +
a+(b-c)a b c - +
a+(b-c)*da b c – d * +
a+d*(b-c)a d b c - * +
a=1+3a 1 3 + =

后綴表達式的計算機求值

從左至右掃描表達式,遇到數字時,將數字壓入堆棧,遇到運算符時,彈出棧頂的兩個數,用運算符對它們做相應的計算(次頂元素 和 棧頂元素),并將結果入棧;重復上述過程直到表達式最右端,最后運算得出的值即為表達式的結果

例如: (3+4)×5-6 對應的后綴表達式就是 3 4 + 5 × 6 - , 針對后綴表達式求值步驟如下:

  1. 從左至右掃描,將3和4壓入堆棧;
  2. 遇到+運算符,因此彈出4和3(4為棧頂元素,3為次頂元素),計算出3+4的值,得7,再將7入棧;
  3. 將5入棧;
  4. 接下來是×運算符,因此彈出5和7,計算出7×5=35,將35入棧;
  5. 將6入棧;
  6. 最后是-運算符,計算出35-6的值,即29,由此得出最終結果

我們完成一個逆波蘭計算器,要求完成如下任務:

  1. 輸入一個逆波蘭表達式(后綴表達式),使用棧(Stack), 計算其結果
  2. 支持小括號和多位數整數,因為這里我們主要講的是數據結構,因此計算器進行簡化,只支持對整數的計算。
  3. 思路分析
  4. 代碼完成
package com.atguigu.stack;/*** ClassName:  <br/>* Description:  <br/>* Date: 2021-02-20 14:27 <br/>* @project data_algorithm* @package com.atguigu.stack*/import java.util.ArrayList;
import java.util.List;
import java.util.Stack;public class PolandNotation {}
//編寫一個類 Operation 可以返回一個運算符 對應的優先級
class Operation {private static int ADD = 1;private static int SUB = 1;private static int MUL = 2;private static int DIV = 2;//寫一個方法,返回對應的優先級數字public static int getValue(String operation) {int result = 0;switch (operation) {case "+":result = ADD;break;case "-":result = SUB;break;case "*":result = MUL;break;case "/":result = DIV;break;default:System.out.println("不存在該運算符" + operation);break;}return result;}}
//完成對逆波蘭表達式的運算
/** 1)從左至右掃描,將3和4壓入堆棧;2)遇到+運算符,因此彈出4和3(4為棧頂元素,3為次頂元素),計算出3+4的值,得7,再將7入棧;3)將5入棧;4)接下來是×運算符,因此彈出5和7,計算出7×5=35,將35入棧;5)將6入棧;6)最后是-運算符,計算出35-6的值,即29,由此得出最終結果*/public static int calculate(List<String> ls) {// 創建給棧, 只需要一個棧即可Stack<String> stack = new Stack<String>();// 遍歷 lsfor (String item : ls) {// 這里使用正則表達式來取出數if (item.matches("\\d+")) { // 匹配的是多位數// 入棧stack.push(item);} else {// pop出兩個數,并運算, 再入棧int num2 = Integer.parseInt(stack.pop());int num1 = Integer.parseInt(stack.pop());int res = 0;if (item.equals("+")) {res = num1 + num2;} else if (item.equals("-")) {res = num1 - num2;} else if (item.equals("*")) {res = num1 * num2;} else if (item.equals("/")) {res = num1 / num2;} else {throw new RuntimeException("運算符有誤");}//把res 入棧stack.push("" + res);}}//最后留在stack中的數據是運算結果return Integer.parseInt(stack.pop());
}
//將一個逆波蘭表達式, 依次將數據和運算符 放入到 ArrayList中
public static List<String> getListString(String suffixExpression) {//將 suffixExpression 分割String[] split = suffixExpression.split(" ");List<String> list = new ArrayList<String>();for(String ele: split) {list.add(ele);}return list;}
//方法:將 中綴表達式轉成對應的List
//  s="1+((2+3)×4)-5";
public static List<String> toInfixExpressionList(String s) {//定義一個List,存放中綴表達式 對應的內容List<String> ls = new ArrayList<String>();int i = 0; //這時是一個指針,用于遍歷 中綴表達式字符串String str; // 對多位數的拼接char c; // 每遍歷到一個字符,就放入到cdo {//如果c是一個非數字,我需要加入到lsif((c=s.charAt(i)) < 48 ||  (c=s.charAt(i)) > 57) {ls.add("" + c);i++; //i需要后移} else { //如果是一個數,需要考慮多位數str = ""; //先將str 置成"" '0'[48]->'9'[57]while(i < s.length() && (c=s.charAt(i)) >= 48 && (c=s.charAt(i)) <= 57) {str += c;//拼接i++;}ls.add(str);}}while(i < s.length());return ls;//返回
}
//即 ArrayList [1,+,(,(,2,+,3,),*,4,),-,5]  =》 ArrayList [1,2,3,+,4,*,+,5,–]
//方法:將得到的中綴表達式對應的List => 后綴表達式對應的List
public static List<String> parseSuffixExpreesionList(List<String> ls) {//定義兩個棧Stack<String> s1 = new Stack<String>(); // 符號棧//說明:因為s2 這個棧,在整個轉換過程中,沒有pop操作,而且后面我們還需要逆序輸出//因此比較麻煩,這里我們就不用 Stack<String> 直接使用 List<String> s2//Stack<String> s2 = new Stack<String>(); // 儲存中間結果的棧s2List<String> s2 = new ArrayList<String>(); // 儲存中間結果的Lists2//遍歷lsfor(String item: ls) {//如果是一個數,加入s2if(item.matches("\\d+")) {s2.add(item);} else if (item.equals("(")) {s1.push(item);} else if (item.equals(")")) {//如果是右括號“)”,則依次彈出s1棧頂的運算符,并壓入s2,直到遇到左括號為止,此時將這一對括號丟棄while(!s1.peek().equals("(")) {s2.add(s1.pop());}s1.pop();//!!! 將 ( 彈出 s1棧, 消除小括號} else {//當item的優先級小于等于s1棧頂運算符, 將s1棧頂的運算符彈出并加入到s2中,再次轉到(4.1)與s1中新的棧頂運算符相比較//問題:我們缺少一個比較優先級高低的方法while(s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(item) ) {s2.add(s1.pop());}//還需要將item壓入棧s1.push(item);}}//將s1中剩余的運算符依次彈出并加入s2while(s1.size() != 0) {s2.add(s1.pop());}return s2; //注意因為是存放到List, 因此按順序輸出就是對應的后綴表達式對應的List}

執行

public static void main(String[] args) {//完成將一個中綴表達式轉成后綴表達式的功能//說明//1. 1+((2+3)×4)-5 => 轉成  1 2 3 + 4 × + 5 –//2. 因為直接對str 進行操作,不方便,因此 先將  "1+((2+3)×4)-5" =》 中綴的表達式對應的List//   即 "1+((2+3)×4)-5" => ArrayList [1,+,(,(,2,+,3,),*,4,),-,5]//3. 將得到的中綴表達式對應的List => 后綴表達式對應的List//   即 ArrayList [1,+,(,(,2,+,3,),*,4,),-,5]  =》 ArrayList [1,2,3,+,4,*,+,5,–]String expression = "1+((2+3)*4)-5";//注意表達式List<String> infixExpressionList = toInfixExpressionList(expression);System.out.println("中綴表達式對應的List=" + infixExpressionList); // ArrayList [1,+,(,(,2,+,3,),*,4,),-,5]List<String> suffixExpreesionList = parseSuffixExpreesionList(infixExpressionList);System.out.println("后綴表達式對應的List" + suffixExpreesionList); //ArrayList [1,2,3,+,4,*,+,5,–]System.out.printf("expression=%d", calculate(suffixExpreesionList)); // ?/*//先定義給逆波蘭表達式//(30+4)×5-6  => 30 4 + 5 × 6 - => 164// 4 * 5 - 8 + 60 + 8 / 2 => 4 5 * 8 - 60 + 8 2 / +//測試//說明為了方便,逆波蘭表達式 的數字和符號使用空格隔開//String suffixExpression = "30 4 + 5 * 6 -";String suffixExpression = "4 5 * 8 - 60 + 8 2 / +"; // 76//思路//1. 先將 "3 4 + 5 × 6 - " => 放到ArrayList中//2. 將 ArrayList 傳遞給一個方法,遍歷 ArrayList 配合棧 完成計算List<String> list = getListString(suffixExpression);System.out.println("rpnList=" + list);int res = calculate(list);System.out.println("計算的結果是=" + res);*/
}

原文在這里

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/455087.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/455087.shtml
英文地址,請注明出處:http://en.pswp.cn/news/455087.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

psnr 計算

PSNR是“Peak Signal to Noise Ratio”的縮寫&#xff0c;峰值信噪比。psnr一般是用于最大值信號和背景噪音之間的一個工程項目。 PSNR計算公式如下&#xff1a; 8bits表示法中&#xff0c;peak的最大值為255&#xff1b;MSE指Mean Square Error&#xff08;均方誤差&#xff0…

光源時間_縮短背光源的使用壽命的原因

許多場所都會使用到led這種產品&#xff0c;這種產品經常用于背光的照亮中。但是由于使用led的局限性較大&#xff0c;所以led逐漸被背光源這種產品所代替&#xff0c;常常用于背景的照亮讓宣傳圖可以展現出更好的視覺&#xff0c;這也是許多人選擇背光源的原因。那么&#xff…

《結對-貪吃蛇-需求分析》

結對編程&#xff1a;貪吃蛇項目 準備階段&#xff1a;安裝Python、pygame 編寫階段&#xff1a;1. 設置游戲窗口 2. 設置游戲必要功能&#xff1a; a)開始、暫停、退出按鈕 b)貪吃蛇身體 c)食物 d)移動貪吃蛇所需按鍵 3. 完善游戲&#xff1a;添加游戲時間、貪吃蛇失敗次數…

視頻中場的問題2009-04-03 19:38(一)

視頻中場的問題2009-04-03 19:38(一) 場的用途&#xff1a; 讓25幀/秒的電視畫面幀速率&#xff0c;變為50幀/秒。使觀眾感受到更加流暢的畫面。 (二) 場的由來&#xff1a; 在電視制作的時候&#xff0c;電視掃描一副畫面的時間根據當地交流電源的頻率來確定。比如中國交流電源…

遞歸應用場景和調用機制

原文鏈接:傳送門 遞歸 迷宮問題(回溯) 概念 簡單吶的說: 遞歸就是方法自己調用自己,每次調用時傳入不同的變量,遞歸有助于編程者解決復雜的問題,同時讓代碼變得簡潔. 案例-遞歸調用機制 打印問題 public static void test(int n){if(n>2){test(n-1);}System.out.print…

在vivado里用rtl描述_如何利用Vivado HLS處理許多位準確或任意精度數據類型

我們在設計硬件時&#xff0c;它往往是要求更精確的位寬。例如&#xff0c;一個filter的輸入是12位和一個累加器的結果只需要一個最大范圍為27位。然而對于硬件設計來說&#xff0c;使用標準的C數據類型會造成硬件成本的浪費。這就會造成我們要使用更多的LUT和寄存器&#xff0…

Spring4.0之四:Meta Annotation(元注解)

Spring框架自2.0開始添加注解的支持&#xff0c;之后的每個版本都增加了更多的注解支持。注解為依賴注入&#xff0c;AOP&#xff08;如事務&#xff09;提供了更強大和簡便的方式。這也導致你要是用一個相同的注解到許多不同的類中去。這篇文章介紹meta annotation來解決這個問…

八皇后問題分析與Java實現

原文鏈接:傳送門 八皇后問題 八皇后問題&#xff0c;是一個古老而著名的問題&#xff0c;是回溯算法的典型案例。該問題是國際西洋棋棋手馬克斯貝瑟爾于1848年提出&#xff1a;在88格的國際象棋上擺放八個皇后&#xff0c;使其不能互相攻擊&#xff0c;即&#xff1a;任意兩個…

各種音視頻編解碼學習詳解 h264 ,mpeg4 ,aac 等所有音視頻格式

編解碼學習筆記&#xff08;一&#xff09;&#xff1a;基本概念 媒體業務是網絡的主要業務之間。尤其移動互聯網業務的興起&#xff0c;在運營商和應用開發商中&#xff0c;媒體業務份量極重&#xff0c;其中媒體的編解碼服務涉及需求分析、應用開發、釋放license收費等等。最…

shell 腳本比較字符串相等_shell腳本--邏輯判斷與字符串比較

涉及到比較和判斷的時候&#xff0c;要注意整數比較使用-lt&#xff0c;-gt&#xff0c;ge等比較運算符&#xff0c;詳情參考&#xff1a;整數比較文件測試使用 -d, -f, -x等運算發&#xff0c;詳情參考&#xff1a;文件測試邏輯判斷使用 &&(且)、||(或)、&#xff…

單例模式之惡漢模式(詳解)

一.設計模式 概念&#xff1a;設計模式是一套被反復使用、多人知曉的、經過分類編目的、代碼設計經驗的總結。 目的&#xff1a;是用設計模式可以重用代碼&#xff0c;讓代碼更容易被他人理解&#xff0c;保證代碼的可靠性。 二.為什么要使用單例模式&#xff1f; 如果創造出多…

JSP中的:request.getScheme()+://+request.getServerName()+:+request.getServer

String path request.getContextPath(); String basePath request.getScheme()"://"request.getServerName()":"request.getServerPort()path"/"; <base href" <%basePath%>"> 這個語句是用來拼裝當前網頁的相對…

迷宮回溯問題分析和實現

原文鏈接:傳送門 迷宮問題 說明: 小球得到的路徑&#xff0c;和程序員設置的找路策略有關即&#xff1a;找路的上下左右的順序相關再得到小球路徑時&#xff0c;可以先使用(下右上左)&#xff0c;再改成(上右下左)&#xff0c;看看路徑是不是有變化測試回溯現象思考: 如何求出…

canvas clear 指定屬性的元素_好程序員web前端分享CSS屬性組成及作用

好程序員web前端分享CSS屬性組成及作用學習目標1、css屬性和屬性值的定義2、css文本屬性3、css列表屬性4、css背景屬性5、css邊框屬性6、css浮動屬性一、css屬性和屬性值的定義屬性&#xff1a;屬性是指定選擇符所具有的屬性&#xff0c;它是css的核心&#xff0c;css2共有150多…

mybatis大于小于等于

大于&#xff1a;<![CDATA[>]]> 小于&#xff1a;<![CDATA[<]]> 等于&#xff1a;<![CDATA[]]> 大于等于&#xff1a;<![CDATA[>]]> 小于等于&#xff1a;<![CDATA[<]]>轉載于:https://www.cnblogs.com/YuanFan123/p/7234530.html

2017年秋招-廣聯達面試及思考

面試官提問&#xff1a; 自我介紹&#xff08;沒有做充分的準備&#xff0c;總感覺說的不好&#xff09;為什么選擇做前端&#xff1f;在前端方向&#xff0c;你認為自身有哪些優點&#xff1f;前端需要掌握哪些技術知識點&#xff1f;看過哪些比較好的網站&#xff1f;會不會使…

排序算法介紹和分類

原文鏈接:傳送門 排序算法的介紹 排序也成排序算法 排序也稱排序算法(Sort Algorithm)&#xff0c;排序是將一組數據&#xff0c;依指定的順序進行排列的過程。 排序的分類&#xff1a; 1) 內部排序: 指將需要處理的所有數據都加載到**內部存儲器(內存)**中進行排序。 2) 外…

認識高清視頻編碼(MPEG、H.264、WMV-HD、RMVB)

文章出處&#xff1a;www.net1980.com 原創 最近兩年&#xff0c;“高清”這個詞語非常火熱&#xff0c;已經成為家電和IT行業的最新潮流了。高清視頻和普通視頻有什么區別呢&#xff1f;主要是分辨率上的區別&#xff0c;720P視頻的分辨率為1280X720&#xff0c;1080P視頻的分…

解讀SPP / SPPF / SimSPPF / ASPP / RFB / SPPCSPC

SPP與SPPF 一、SPP的應用的背景 在卷積神經網絡中我們經常看到固定輸入的設計&#xff0c;但是如果我們輸入的不能是固定尺寸的該怎么辦呢&#xff1f; 通常來說&#xff0c;我們有以下幾種方法&#xff1a; &#xff08;1&#xff09;對輸入進行resize操作&#xff0c;讓他們…

go mongodb排序查詢_《MongoDB》day two

Mongodb的更新方式有&#xff1f;db.集合名.update() 函數:用于更新已存在的文檔。語法格式&#xff1a;db.COLLECTION_NAME.update({查詢條件},{更新內容},{更新參數(可選)}) 注&#xff1a;這種方式會覆蓋原有的文檔。使用更新操作符 使用 save()函數更新文檔 Mongodb的updat…