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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

(数据结构与算法)使用栈来实现综合计算器

發(fā)布時(shí)間:2025/3/20 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (数据结构与算法)使用栈来实现综合计算器 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 1.棧實(shí)現(xiàn)計(jì)算器(中綴表達(dá)式)
    • 1.1流程圖
    • 1.2 代碼實(shí)現(xiàn)
  • 2. 逆波蘭(后綴)表達(dá)式實(shí)現(xiàn)
    • 2.1 初步實(shí)現(xiàn)
    • 2.2 中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式
      • 2.2.1步驟
      • 2.2.2 代碼實(shí)現(xiàn)

1.棧實(shí)現(xiàn)計(jì)算器(中綴表達(dá)式)

1.1流程圖

1.2 代碼實(shí)現(xiàn)

public class Calculator {public static void main(String[] args) {String expression = "700*2*2-5+1-5+3-4";//創(chuàng)建數(shù)棧和運(yùn)算符棧ArrayStackCal numStack = new ArrayStackCal(10);ArrayStackCal operStack = new ArrayStackCal(10);int index = 0;//用于掃描int num1 = 0;int num2 = 0;int oper = 0;int res = 0;char ch = ' '; //將掃描結(jié)果保存到chString keepNum = "";//用于拼接字符串while (true){//遍歷表達(dá)式將字符保存到chch = expression.substring(index,index+1).charAt(0);//判斷是否為運(yùn)算符if (operStack.isOper(ch)) {if (!operStack.isEmpty()){if (operStack.priority(ch) <= operStack.priority(operStack.peek())) {//運(yùn)算優(yōu)先級小于棧頂時(shí)計(jì)算num1 = numStack.pop();num2 = numStack.pop();oper = operStack.pop();res = operStack.cal(num1, num2, oper);//將運(yùn)算結(jié)果入數(shù)棧numStack.push(res);//將當(dāng)前操作符入符號棧operStack.push(ch);} else {//運(yùn)算優(yōu)先級大于棧頂時(shí)入符號棧operStack.push(ch);}}else {//如果為空直接入棧operStack.push(ch);}}else {//如果下一位還是數(shù)字就拼接keepNum += ch;//如果ch已經(jīng)是expression的最后一位,就直接入棧if (index == expression.length() - 1) {numStack.push(Integer.parseInt(keepNum));}else{//判斷下一個(gè)字符是不是數(shù)字,如果是數(shù)字,就繼續(xù)掃描,如果是運(yùn)算符,則入棧//注意是看后一位,不是index++if (operStack.isOper(expression.substring(index+1,index+2).charAt(0))) {//如果后一位是運(yùn)算符,則入棧 keepNum = "1" 或者 "123"numStack.push(Integer.parseInt(keepNum));//重要的!!!!!!, keepNum清空keepNum = "";}}}index++;if (index>=expression.length()){break;}}//當(dāng)表達(dá)式遍歷完,就順序的從數(shù)棧和符號棧中pop出相應(yīng)的數(shù)和符號,并運(yùn)行while (true){if (operStack.isEmpty()){break;}num1 = numStack.pop();num2 = numStack.pop();oper = operStack.pop();res = operStack.cal(num1,num2,oper);numStack.push(res);}int res2 = numStack.pop();System.out.println("表達(dá)式"+expression+"="+res2);} }//繼承ArrayStack用數(shù)組實(shí)現(xiàn)棧 class ArrayStackCal extends ArrayStack{public ArrayStackCal() {}public ArrayStackCal(int maxSize) {super(maxSize);}/*** 返回運(yùn)算符的優(yōu)先級,用數(shù)字表示* @param oper* @return*/public int priority(int oper){if (oper=='*'||oper=='/'){return 1;}else if (oper=='+' || oper=='-'){return 0;}else {return -1;}}/*** 判斷是否是一個(gè)運(yùn)算符* @param val* @return*/public boolean isOper(char val){return val =='+' ||val =='-' || val =='*'|| val =='/';}/*** 返回計(jì)算結(jié)果* @param num1* @param num2* @param oper* @return*/public int cal(int num1,int num2,int oper){int res = 0;//計(jì)算結(jié)果switch (oper){case '+':res = num2 + num1;break;case '-':res = num2 - num1;break;case '*':res = num2 * num1;break;case '/':res = num2 / num1;break;default:break;}return res;}}

ArrayStack

class ArrayStack implements Stack1{public int maxSize;//棧的最大長度public int[] stack;public int top = -1;//棧頂public ArrayStack() {}public ArrayStack(int maxSize) {this.maxSize = maxSize;stack=new int[this.maxSize];}@Overridepublic int getSize() {return stack.length;}@Overridepublic boolean isEmpty() {return top==-1;}@Overridepublic void push(int value) {if (isFull()){System.out.println("棧滿!");return;}top++;stack[top]=value;}public boolean isFull(){return top==maxSize-1;}@Overridepublic int pop() {if (isEmpty()){throw new RuntimeException("棧空,無法取出數(shù)據(jù)!");}int value = stack[top];top--;return value;}@Overridepublic int peek() {//返回棧頂?shù)闹?/span>return stack[top];}public void traverse(){if (isEmpty()){System.out.println("棧空,無法取出數(shù)據(jù)!");return;}for (int i = top; i >=0 ; i--) {System.out.println("stack["+i+"]"+"="+stack[i]);}} }

stack1

public interface Stack1 {int getSize();boolean isEmpty();void push(int e);int pop();int peek(); }

2. 逆波蘭(后綴)表達(dá)式實(shí)現(xiàn)

例如:(3+4)X5-6對應(yīng)的后綴表達(dá)式就是,針對后綴表達(dá)式求值步驟如下:
1.從左至右掃描,將3和4壓入堆棧;
2.遇到+運(yùn)算符,因此彈出4和3 (4為棧頂元素,3為次頂元素),計(jì)算出3+4的值,得7,再將7入棧;
3.將5入棧;
4.接下來是X運(yùn)算符,因此彈出5和7,計(jì)算出7X5=35,將35入棧;
5.將6入棧;
6.最后是-運(yùn)算符,計(jì)算出35-6的值,即29,由此得出最終結(jié)果

2.1 初步實(shí)現(xiàn)

實(shí)現(xiàn)思路

  • 定義表達(dá)式

  • 將表達(dá)式按空格分割放入列表

  • 計(jì)算結(jié)果 :從左到右掃描,掃到的是數(shù)字就入棧,符號就pop出兩個(gè)數(shù)字然后進(jìn)行運(yùn)算,再將結(jié)果入棧循環(huán)執(zhí)行。直到最后還在棧中的元素就是結(jié)果。

  • 返回結(jié)果

  • //逆波蘭表達(dá)式的計(jì)算 public class PolanNotation {public static void main(String[] args) {//定義逆波蘭表達(dá)式String expression = "3 4 + 5 * 6 -";ArrayList<String> list = getListString(expression);System.out.println(list);int cal = cal(list);System.out.println(cal);}/*** 將表達(dá)式放入ArrayList中* @param expression* @return*/public static ArrayList<String> getListString(String expression){//將表達(dá)式按空格分割String[] s = expression.split(" ");ArrayList<String> list = new ArrayList<>();//將表達(dá)式放入ArrayList中for (String s1 : s) {list.add(s1);}return list;}public static int cal(ArrayList<String> list){Stack<String> stack = new Stack<>();int num1 = 0;int num2 = 0;int res = 0;//存放運(yùn)算結(jié)果for (String s : list) {//用正則表達(dá)式取出數(shù)if(s.matches("\\d+")){//匹配的是多位數(shù)stack.push(s);}else {num1 = Integer.parseInt(stack.pop());num2 = Integer.parseInt(stack.pop());switch (s){case "+":res = num2+num1;break;case "-":res = num2-num1;break;case "*":res = num2*num1;break;case "/":res = num2/num1;break;default:throw new RuntimeException("運(yùn)算符有誤");}//將計(jì)算結(jié)果入棧stack.push(""+res);}}//返回棧中最后剩下的元素return Integer.parseInt(stack.pop());} }


    這里表達(dá)式是后綴表達(dá)式,下面添加中綴轉(zhuǎn)后綴表達(dá)式的實(shí)現(xiàn)。

    2.2 中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式

    2.2.1步驟

    1)初始化兩個(gè)棧:運(yùn)算符棧s1和儲存中間結(jié)果的棧s2;
    2)從左至右掃描中綴表達(dá)式; .
    3)遇到操作數(shù)時(shí),將其壓s2;
    4)遇到運(yùn)算符時(shí),比較其與s1棧頂運(yùn)算符的優(yōu)先級:
    1.如果s1為空,或棧頂運(yùn)算符為左括號“(”,則直接將此運(yùn)算符入棧;
    2.否則,若優(yōu)先級比棧頂運(yùn)算符的高,也將運(yùn)算符壓入s1;
    3.否則,將s1棧頂?shù)倪\(yùn)算符彈出并壓入到s2中,再次轉(zhuǎn)到(4-1)與s1中新的棧頂運(yùn)算符相比較;
    5)遇到括號時(shí):
    (1) 如果是左括號“(”,則直接壓入s1
    (2)如果是右括號“)”,則依次彈出s1棧頂?shù)倪\(yùn)算符,并壓入s2,直到遇到左括號為止,此時(shí)將這一對括號丟棄
    6)重復(fù)步驟2至5,直到表達(dá)式的最右邊
    7)將s1中剩余的運(yùn)算符依次彈出并壓入s2
    8)依次彈出s2中的元素并輸出,結(jié)果的逆序即為中綴表達(dá)式對應(yīng)的后綴表達(dá)式

    舉例 1+((2+3)X4)-5

    掃描到的元素s2 (棧底->棧頂)s1(棧底->棧頂)說明
    11數(shù)字,入棧s2
    +1+s1為空,入棧s1
    (1+ (左括號,入棧s1
    (1+ ( (左括號,入棧s1
    21 2+ ( (數(shù)字,入棧s2
    +1 2+ ( ( +s1棧頂為左括號 ,入棧s1
    31 2 3+ ( ( +數(shù)字,入棧s2
    )1 2 3 ++ (右括號,彈出運(yùn)算符直到遇到左括號
    *1 2 3 ++ ( *s1棧頂為左括號,入棧s1
    41 2 3 + 4+ ( *數(shù)字,入棧s2
    )1 2 3 + 4 *+右括號,彈出運(yùn)算符直到遇到左括號
    -1 2 3 + 4 * +--與+優(yōu)先級相同,彈出+,壓入-
    51 2 3 + 4 * + 5-數(shù)字,入棧s2
    掃描結(jié)束1 2 3 + 4 * + 5 -s1剩余運(yùn)算符壓入s2

    2.2.2 代碼實(shí)現(xiàn)

    //逆波蘭表達(dá)式的計(jì)算 public class PolanNotation {public static void main(String[] args) {String expression2 = "1+((2+3)*4)-5";//將中綴表達(dá)式放入集合List<String> list1 = toInfixExpressionList(expression2);System.out.println("轉(zhuǎn)換前"+list1);//將中綴表達(dá)式轉(zhuǎn)為后綴表達(dá)式List<String> list2 = parseSuffixExpreesionList(list1);System.out.println("轉(zhuǎn)換后"+list2);int res = cal(list2);System.out.println(expression2+"="+res); // //定義逆波蘭表達(dá)式 // String expression = "3 4 + 5 * 6 -"; // ArrayList<String> list = getListString(expression); // System.out.println(list); // int cal = cal(list); // System.out.println(cal);}/*** 將中綴表達(dá)式轉(zhuǎn)為后綴表達(dá)式* @param list* @return*/public static List<String> parseSuffixExpreesionList(List<String> list){Stack<String> s1 = new Stack<>();//存放運(yùn)算符List<String> s2 = new ArrayList<>();//存放中間結(jié)果for (String s : list) {if (s.matches("\\d+")){//遇到操作數(shù)時(shí),將其放入s2;s2.add(s);}else if(s.equals("(")) {//如果是左括號“(”,則直接壓入s1s1.push(s);}else if(s.equals(")")){//)如果是右括號“)”,則依次彈出s1棧頂?shù)倪\(yùn)算符,并壓入s2,直到遇到左括號為止,此時(shí)將這一對括號丟棄while (!s1.peek().equals("(")) {s2.add(s1.pop());}s1.pop();//丟棄左括號}else {//如果是運(yùn)算符,判斷優(yōu)先級while (s1.size()!=0 && Operation.getValue(s1.peek())>= Operation.getValue(s)){//若當(dāng)前運(yùn)算符優(yōu)先級小于等于棧頂元素將s1棧頂?shù)倪\(yùn)算符彈出并放入到s2中,再次循環(huán)判斷s2.add(s1.pop());}//其他情況, 如果s1為空,或棧頂運(yùn)算符為左括號“(”,優(yōu)先級比棧頂運(yùn)算符的高,入棧s1.push(s);}}//將s1中剩余的運(yùn)算符依次彈出放入s2while (s1.size() !=0){s2.add(s1.pop());}return s2;}/*** 將中綴表達(dá)式放入集合* @param s* @return*/public static List<String> toInfixExpressionList(String s){List<String> list = new ArrayList<>();String str;//拼接字符串char c ;//存放遍歷的字符int i=0; //用于遍歷字符串do {if ((c=s.charAt(i))<48||(c=s.charAt(i))>57){//當(dāng)c為運(yùn)算符時(shí)list.add(""+c);i++;}else {//當(dāng)c為一個(gè)數(shù)時(shí)str="";//將str置空while (i<s.length() && (c=s.charAt(i))>=48 &&(c=s.charAt(i))<=57){str+=c;i++;}list.add(str);}}while (i < s.length());return list;}/*** 將后綴表達(dá)式放入ArrayList中* @param expression* @return*/public static List<String> getListString(String expression){//將表達(dá)式按空格分割String[] s = expression.split(" ");List<String> list = new ArrayList<>();//將表達(dá)式放入ArrayList中for (String s1 : s) {list.add(s1);}return list;}public static int cal(List<String> list){Stack<String> stack = new Stack<>();int num1 = 0;int num2 = 0;int res = 0;//存放運(yùn)算結(jié)果for (String s : list) {//用正則表達(dá)式取出數(shù)if(s.matches("\\d+")){//匹配的是多位數(shù)stack.push(s);}else {num1 = Integer.parseInt(stack.pop());num2 = Integer.parseInt(stack.pop());switch (s){case "+":res = num2+num1;break;case "-":res = num2-num1;break;case "*":res = num2*num1;break;case "/":res = num2/num1;break;default:throw new RuntimeException("運(yùn)算符有誤");}//將計(jì)算結(jié)果入棧stack.push(""+res);}}//返回棧中最后剩下的元素return Integer.parseInt(stack.pop());} } //編寫一個(gè)類 Operation 可以返回一個(gè)運(yùn)算符 對應(yīng)的優(yōu)先級 class Operation {private static int ADD = 1;private static int SUB = 1;private static int MUL = 2;private static int DIV = 2;//寫一個(gè)方法,返回對應(yīng)的優(yōu)先級數(shù)字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:break;}return result;}}

    總結(jié)

    以上是生活随笔為你收集整理的(数据结构与算法)使用栈来实现综合计算器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。