日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构:栈实现逆波兰计算器

發布時間:2025/3/21 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构:栈实现逆波兰计算器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

棧實現逆波蘭計算器

前言

上篇博文中已經介紹了棧實現中綴表達式計算器,中綴表達式形如 “1+((2+3)*4)-5” 對人比較容易計算,但對于計算機卻是一件比較困難的事,而后綴表達式 "1 2 3 + 4 * + 5 -"恰恰相反,對人計算起來不是很方便,但對于計算機比較方便并且高效,因此本博文將講解如何將中綴表達式轉換為后綴表達式和實現后綴表達式的計算。


1.中綴表達式轉換為后綴表達式

1.1思路

  • 初始化兩個棧:運算符棧s1和儲存中間結果的棧s2
  • 從左至右掃描中綴表達式
  • 掃描到數字時,將其入棧s2
  • 掃描到運算符時,將其該運算符的運算優先級和s1棧頂的運算符作比較
    • 如果s1為空或者為左括號")",直接入棧
    • 否則,如果該運算符的運算優先級比棧頂優先級高直接入棧s1
    • 否則,如果該運算符的運算優先級小于或等于棧頂優先級,先將棧頂運算符入棧s2,最后再將該運算符入棧s1
  • 掃描到左括號"(",則直接入棧
  • 掃描到右括號")",則依次彈出s1的運算符并入棧s2,直至彈出左括號 —> 這一步操作可以將左右括號抵消
  • 將s1中剩余的運算符依次入棧s2
  • 依次將s2的元素彈出并輸出,輸出的結果的逆序就是中綴表達式轉化后的后綴表達式

以下是 前綴表達式"1 + ( ( 2 + 3 ) * 4 ) - 5" 轉化為后綴表達式"1 2 3 + 4 * + 5 -"的流程示意圖

1.2代碼實現

  • 先將中綴表達式轉換為列表
/*** 將中綴表達式字符串轉換為列表* @param string* @return*/ public static List<String> toInfixExpression(String string) {int beginNumberAsciiCode = 48;int endNumberAsciiCode = 57;ArrayList<String> list = new ArrayList<>();//用于遍歷表達式的指針int i = 0;//用于多位數的拼接String numBuilder;//遍歷到一個字符就放入cchar c;do {//如果c是一個操作符添加至listif ((c = string.charAt(i)) < beginNumberAsciiCode || (c = string.charAt(i))> endNumberAsciiCode){list.add(String.valueOf(c));//指針后移i++;}else{//進行重置numBuilder = "";//如果是一個數 則需要考慮多位數的問題 0->[48] 9->[57]while ((i < string.length() && (c = string.charAt(i)) >= beginNumberAsciiCode && (c = string.charAt(i)) <= endNumberAsciiCode)){//拼接多位數numBuilder+=c;i++;}//將拼接好的多位數添加至listlist.add(numBuilder);}}while (i < string.length());return list; }
  • 將中綴表達式列表轉換為后綴表達式列表
/*** 將中綴表達式的list轉換為后綴表達式的list* @param list 存儲后綴表達式的列表* @return*/ public static List<String> parseSuffixExpressionList(List<String> list) {Stack<String> operationStack = new Stack<>();//實際上應該使用棧,但是整個過程中不需要出棧操作所以也可以用列表來代替棧List<String> numberStack = new ArrayList<>();for (String item : list) {//如果是一個數字直接入棧if (item.matches("\\d+")){numberStack.add(item);}else if (item.equals("(")){operationStack.add(item);}else if (item.equals(")")){//如果是右括號則依次彈出符號棧中的運算符知道遇到左括號--左右括號抵消if (!operationStack.peek().equals("(")){numberStack.add(operationStack.pop());}//消掉左括號operationStack.pop();}else{//item為運算符//當item運算優先級小于等于符號棧棧頂的運算符時,將棧頂運算符彈出并存入數棧然后重復以上步驟while (operationStack.size() != 0 && getPriority(item) <= getPriority(operationStack.peek())){numberStack.add(operationStack.pop());}//當item運算優先級大于符號棧棧頂的運算符優先級//將item入棧operationStack.push(item);}}while (!operationStack.isEmpty()){numberStack.add(operationStack.pop());}return numberStack;}

2.后綴表達式的計算

2.1思路

  • 首先初始化一個棧用來存儲中間數
  • 從左向右掃描后綴表達式
    • 掃描到數字直接入棧
    • 掃描到運算符,先彈出數棧的兩個數進行運算,得到運算結果后將結果入棧
  • 重復上述步驟,數棧最后一個數即為結果

2.2代碼實現

/*** 完成對逆波蘭表達式的計算* 1.從左往右掃描將數字壓入棧* 2.遇到運算符,彈出數棧的兩個元素計算得結果,再將結果入數棧* 3.重復進行上述步驟得到最終結果* @param list* @return*/ public static int calculate(List<String> list) {Stack<String> stack = new Stack<>();for (String item : list) {//正則表達式匹配多位數if (item.matches("\\d+")){stack.push(item);}else{//運算符:從數棧中pop出兩個數進行運算int num1 = Integer.parseInt(stack.pop());int num2 = Integer.parseInt(stack.pop());int result = calculate(num1, num2, item);stack.push(String.valueOf(result));}}return Integer.parseInt(stack.pop()); }/*** 將彈出的兩個數進行運算* @param num1* @param num2* @param operation* @return 返回運算結果入數棧*/ private static int calculate(int num1, int num2, String operation) {int result = 0;switch (operation){case "+":result = num2 + num1;break;case "-"://注意順序result = num2 - num1;break;case "*":result = num2 * num1;break;case "/"://注意順序result = num2 / num1;break;default:throw new RuntimeException("運算符有誤,請重新輸入....");}return result; }

3.測試

public class PolandNotation {public static void main(String[] args){String expression = "1+((2+3)*4)-5";List<String> list = toInfixExpression(expression);System.out.println(list);List<String> parseSuffixExpressionList = parseSuffixExpressionList(list);System.out.println(parseSuffixExpressionList);int result = calculate(parseSuffixExpressionList);System.out.println("Result:"+result);} }//---------------------------------------------------輸出結果------------------------------------------------------ OriginalList ---> [1, +, (, (, 2, +, 3, ), *, 4, ), -, 5] parseSuffixExpressionList ---> [1, 2, 3, +, 4, *, +, 5, -] Result:16

以上。

如有不足或錯誤歡迎評論指正。

總結

以上是生活随笔為你收集整理的数据结构:栈实现逆波兰计算器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。