请写一个整数计算器,支持加减乘三种运算和括号。
数据范围:,保证计算结果始终在整型范围内
要求:空间复杂度: ,时间复杂度
/** * @author tt * @Date Created in 2024/4/10 下午4:21 */ public static int solve(String s) { Set<String> symbol = Stream.of("+", "-", "*", "(", ")").collect(Collectors.toSet()); Deque<String> symbolStack = new ArrayDeque<>(); Deque<Integer> numberStack = new ArrayDeque<>(); List<String> stringList = getStringList(s); for (String str : stringList) { if (!symbol.contains(str)) { // 数字 numberStack.push(Integer.valueOf(str)); } else { // 符号 switch (str) { case "+": case "-": while ("*".equals(symbolStack.peek())) { int opt2 = numberStack.poll(); int opt1 = numberStack.poll(); symbolStack.poll(); numberStack.push(opt1 * opt2); } symbolStack.push(str); break; case "*": case "(": symbolStack.push(str); break; case ")": Deque<String> tempSymbolStack = new ArrayDeque<>(); Deque<Integer> tempNumberStack = new ArrayDeque<>(); while (!"(".equals(symbolStack.peek())) { tempSymbolStack.addLast(symbolStack.poll()); tempNumberStack.addLast(numberStack.poll()); } tempNumberStack.addLast(numberStack.poll()); symbolStack.poll(); while ("*".equals(tempSymbolStack.peek())) { int opt2 = tempNumberStack.poll(); int opt1 = tempNumberStack.poll(); tempSymbolStack.poll(); tempNumberStack.push(opt1 * opt2); } while (!tempSymbolStack.isEmpty()) { String currentSymbol = tempSymbolStack.pollLast(); int opt1 = tempNumberStack.pollLast(); int opt2 = tempNumberStack.pollLast(); tempNumberStack.addLast(compute(opt1, opt2, currentSymbol)); } numberStack.push(tempNumberStack.poll()); break; } } } // 最后执行一次普通运算 while ("*".equals(symbolStack.peek())) { int opt2 = numberStack.poll(); int opt1 = numberStack.poll(); symbolStack.poll(); numberStack.push(opt1 * opt2); } while (!symbolStack.isEmpty()) { String currentSymbol = symbolStack.pollLast(); int opt1 = numberStack.pollLast(); int opt2 = numberStack.pollLast(); numberStack.addLast(compute(opt1, opt2, currentSymbol)); } return numberStack.peek(); } private static int compute(int opt1, int opt2, String currentSymbol) { switch (currentSymbol) { case "*": return opt1 * opt2; case "+": return opt1 + opt2; case "-": return opt1 - opt2; } return 0; } /** * 拆解字符串 * * @param s 原始字符串 * @return 将数字和符号拆解 * @author tt * @Date Created in 2024/4/10 下午4:22 */ private static List<String> getStringList(String s) { List<String> strList = new ArrayList<>(); StringBuilder stringBuilder = new StringBuilder(); Set<String> numberSet = Stream.of("1", "2", "3", "4", "5", "6", "7", "8", "9", "0").collect(Collectors.toSet()); for (String str : s.split("")) { // 判断是否为数字 if (numberSet.contains(str)) { stringBuilder.append(str); } else { if (stringBuilder.length() != 0) { strList.add(stringBuilder.toString()); stringBuilder = new StringBuilder(); } strList.add(str); } } if (stringBuilder.length() != 0) { strList.add(stringBuilder.toString()); } return strList; }
public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 返回表达式的值 * @param s string字符串 待计算的表达式 * @return int整型 */ public int solve (String s) { // write code here if(s.isEmpty()){ return 0; } if(s.length() == 1){ return Integer.parseInt(s); } //存储数字的栈 Stack<String> sStack = new Stack<>(); //存储符号的栈 Stack<String> sSymbol = new Stack<>(); //临时存储数字字符串--防止有两位的数字 String tempIntString = ""; int sLength = s.length(); for(int i = 0;i < sLength;i++){ String symbol = String.valueOf(s.charAt(i)); //如果符号为(则直接添加到符号栈 if(symbol.equals("(")){ sSymbol.push(symbol); }else if(symbol.equals("*")){ //如果符号为*则进行判断 if(!tempIntString.isEmpty()){ //如果存储数字字符不为空, if(!sSymbol.isEmpty()){ //并且符号栈部位空最后一个也为* if(sSymbol.peek().equals("*")){ //除去乘号 sSymbol.pop(); //数字栈添加进行乘法运算后的数字 sStack.push(String.valueOf(Integer.parseInt(sStack.pop()) * Integer.parseInt(tempIntString))); tempIntString = ""; sSymbol.push(symbol); }else{ //符号栈最后一个不是乘号 sStack.push(tempIntString); tempIntString = ""; sSymbol.push(symbol); } }else{ //符号栈为空 sStack.push(tempIntString); tempIntString = ""; sSymbol.push(symbol); } }else{ //存储数字字符串为空时,直接符号入栈 sSymbol.push(symbol); } }else if(symbol.equals("-")){ //存储数字字符串不为空,那么-号就不可能是负数 if(!tempIntString.isEmpty()){ //如果符号栈不为空, if(!sSymbol.isEmpty()){ //数字栈也不为空 if(!sStack.isEmpty()){ //符号栈最后一个为* if(sSymbol.peek().equals("*")){ int leftNum = Integer.parseInt(sStack.pop()); sStack.push(String.valueOf((leftNum) * (Integer.parseInt(tempIntString)))); tempIntString = ""; //删除* sSymbol.pop(); //添加- sSymbol.push(symbol); }else{ sStack.push(tempIntString); tempIntString = ""; sSymbol.push(symbol); } }else{ //数字栈为空 sStack.push(tempIntString); tempIntString = ""; sSymbol.push(symbol); } }else{ //符号栈为空 sStack.push(tempIntString); tempIntString = ""; sSymbol.push(symbol); } }else{ //存储数字字符串为空时 if(sStack.isEmpty()){ //数字栈也为空,那就负号 tempIntString = tempIntString.concat("-"); }else{ //数字栈不为空,符号栈也不为空 if(!sSymbol.isEmpty()){ //符号栈是(,那也是负号 if(sSymbol.peek().equals("(")){ tempIntString = tempIntString.concat("-"); }else{ sSymbol.push(symbol); } }else{ //其他情况都是符号 sSymbol.push(symbol); } } } }else if(symbol.equals("+")){ //存储数字字符串不为空 if(!tempIntString.isEmpty()){ //符号栈不为空 if(!sSymbol.isEmpty()){ //数字栈也不为空 if(!sStack.isEmpty()){ //符号栈最后一个为* if(sSymbol.peek().equals("*")){ int leftNum = Integer.parseInt(sStack.pop()); sStack.push(String.valueOf((leftNum) * (Integer.parseInt(tempIntString)))); tempIntString = ""; sSymbol.pop(); sSymbol.push(symbol); }else{ sStack.push(tempIntString); tempIntString = ""; sSymbol.push(symbol); } }else{ sStack.push(tempIntString); tempIntString = ""; sSymbol.push(symbol); } }else{ sStack.push(tempIntString); tempIntString = ""; sSymbol.push(symbol); } }else{ //数字字符串为空时,不管什么情况它都是符号 sSymbol.push(symbol); } }else if(symbol.equals(")")){ //当数字字符串不为空时 if(!tempIntString.isEmpty()){ int rightNum = Integer.parseInt(tempIntString); tempIntString = ""; while(!sSymbol.peek().equals("(")){ String tempSymbol = sSymbol.pop(); int leftInt = Integer.parseInt(sStack.pop()); if(tempSymbol.equals("+")){ rightNum = (leftInt) + (rightNum); }else if(tempSymbol.equals("-")){ rightNum = (leftInt) - (rightNum); }else{ rightNum = (leftInt) * (rightNum); } } sStack.push(String.valueOf(rightNum)); //删除( sSymbol.pop(); }else{ //数字字符串为空时,,此时存在的可能性就是在()中进行了一次乘法运算 int rightNum = Integer.parseInt(sStack.pop()); while(!sSymbol.peek().equals("(")){ String tempSymbol = sSymbol.pop(); int leftInt = Integer.parseInt(sStack.pop()); if(tempSymbol.equals("+")){ rightNum = (leftInt) + (rightNum); }else if(tempSymbol.equals("-")){ rightNum = (leftInt) - (rightNum); }else{ rightNum = (leftInt) * (rightNum); } } sStack.push(String.valueOf(rightNum)); //删除( sSymbol.pop(); } //判断括号中运算完成后的第一个符号是否为* if(!sSymbol.isEmpty() && sSymbol.peek().equals("*")){ int rightNum = Integer.parseInt(sStack.pop()); sSymbol.pop(); int leftNum = Integer.parseInt(sStack.pop()); sStack.push(String.valueOf((leftNum) * (rightNum))); } }else{ //数字的时候 tempIntString = tempIntString.concat(symbol); } } //清空数字栈和符号栈,此时符号栈中只有+,- if(!tempIntString.isEmpty()){ sStack.push(tempIntString); tempIntString = ""; } //最后要么只剩乘法,要么只剩加减,栈中的数字倒过来,由左至右正常加减乘即可 Stack<String> sSymbolReverse = new Stack<>(); Stack<String> sStackReverse = new Stack<>(); while(!sSymbol.isEmpty()){ sSymbolReverse.push(sSymbol.pop()); } while(!sStack.isEmpty()){ sStackReverse.push(sStack.pop()); } while(!sSymbolReverse.isEmpty()){ int leftNum = Integer.parseInt(sStackReverse.pop()); String tempSymbol = sSymbolReverse.pop(); int rightNum = Integer.parseInt(sStackReverse.pop()); if(tempSymbol.equals("+")){ rightNum = (leftNum) + (rightNum); }else if(tempSymbol.equals("-")){ rightNum = (leftNum) - (rightNum); }else{ rightNum = (leftNum) * (rightNum); } sStackReverse.push(String.valueOf(rightNum)); } return Integer.parseInt(sStackReverse.pop()); } }
HashMap<Character ,Integer> map=new HashMap<Character ,Integer>(){{ put('+' ,1); put('-' ,1); put('*' ,2); }}; public int solve (String s) { // write code here Stack<Character> s1=new Stack<>(); Stack<Integer> s2=new Stack<>(); s2.push(0); char[] cs=s.replaceAll(",","").toCharArray(); for(int i=0;i<cs.length;i++){ // 1、遇到左括号 if(cs[i]=='('){ s1.push('('); }else if(Character.isDigit(cs[i])){ //2、遇到数字 int num=0; while(i<cs.length && Character.isDigit(cs[i])){ num=num*10+(cs[i++]-'0'); } i--; s2.push(num); }else if(cs[i]==')'){// 3、遇到右括号 while(s1.peek()!='('){ cacl(s1 ,s2); } s1.pop(); }else{// 4、遇到计算符号 if(i>0 && cs[i-1]=='('){ // 4.1 如果左括号后紧跟一个计算符号,需要在符号前加个0 ,便于进行计算 s2.push(0); } // 4.2 符号优先级高的会先进行计算 while(!s1.isEmpty() && s1.peek()!='(' && map.get(cs[i])<=map.get(s1.peek())){ cacl(s1 ,s2); } // 4.3 处理完紧跟左括号和优先级计算,需要将当前的符号压栈 s1.push(cs[i]); } } // 5、将没计算完的情况进行计算,如只有1+2 while(!s1.isEmpty()){ cacl(s1 ,s2); } return s2.pop(); } public void cacl(Stack<Character> s1 ,Stack<Integer> s2){ if(s1.size()<1 || s2.size()<2){ return; } char c=s1.pop(); int n=s2.pop() ,m=s2.pop(); if(c=='+'){ s2.push(m+n); }else if(c=='-'){ s2.push(m-n); }else{ s2.push(m*n); } }
时间超时啊 import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 返回表达式的值 * @param s string字符串 待计算的表达式 * @return int整型 */ public int solve (String s) { // write code here int result = 0; List<String> transList = transList(s); System.out.println(transList); List<String> reversePolish = reversePolish(transList); System.out.println(reversePolish); result = calculate(reversePolish); return result; } private int calculate(List<String> reversePolish) { // TODO Stack<String> temp = new Stack<>(); reversePolish.stream().forEach(e-> { if (e.matches("//d")) { temp.add(e); } else { int num1 = Integer.parseInt(temp.pop()); int num2 = Integer.parseInt(temp.pop()); int res = calc(num1, num2, e); temp.add(res + ""); } }); return Integer.parseInt(temp.pop()); } private int calc(int num1, int num2, String e) { // TODO int res = 0; switch (e) { case "+": res = num1 + num2; break; case "-": res = num1 - num2; break; case "*": res = num1 * num2; break; case "/": res = num1 / num2; break; } return res; } private List<String> reversePolish(List<String> transList) { // TODO List<String> res = new ArrayList<>(); // 队列,用于保存后缀表达式 Stack<String> opt = new Stack<>(); //暂时保存运算符的栈 transList.stream().forEach(e-> { if (e.matches("//d")) { // 正则表达式来判断,如果是数字,则直接入队; res.add(e); } else { if (e.equals("(")) { // 若是左括号,直接入运算符栈 opt.add("("); } else if ( e.equals(")")) { // 如果是右括号,则将运算符栈中的运算符出栈 并入队到表达式队列中 while (!opt.isEmpty() && !opt.peek().equals("(")) { res.add(opt.pop()); } opt.pop(); // 最后把左括号出栈; } else { // 如过是四则运算符+ - * /,则先和运算符栈顶元素比较优先级,若优先级比栈顶的高则直接入栈, // 否则将运算符栈出栈并入到表达式队列,直到优先级大于栈顶元素,再入栈 while (!opt.isEmpty() && getValue(opt.peek()) >= getValue(e)) { res.add(opt.pop()); } opt.add(e); } } }); while (!opt.isEmpty()) { res.add(opt.pop()); } return res; } private int getValue(String opt) { // TODO int reslut = 0; switch (opt) { case "+": reslut = 1; break; case "-": reslut = 1; break; case "*": reslut = 2; break; case "/": reslut = 2; break; } return reslut; } private List<String> transList(String s) { // TODO List<String> express = new ArrayList<>(); int i = 0; String str; // 用于拼接多位数字 while (i < s.length()) { char ch = s.charAt(i); if (ch < 48 || ch > 57) { express.add(ch + ""); } else { str = ""; while (i < s.length() && (s.charAt(i) >= 48 && s.charAt(i) <= 57)) { str = str + s.charAt(i) + ""; i++; } express.add(str); } } return express; } }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 返回表达式的值 * @param s string字符串 待计算的表达式 * @return int整型 */ // 存放操作数 Stack<Integer> nums = new Stack<Integer>(); // 存放运算符 Stack<Character> ops = new Stack<Character>(); // 维护运算符优先级,数字越大优先级越高 HashMap<Character, Integer> map = new HashMap<Character, Integer>(); public int solve (String s) { // write code here map.put('+', 1); map.put('-', 1); map.put('*', 2); // 遍历表达式 for (int i = 0; i < s.length(); i++) { char ch = s.charAt(i); // 遇到数字 if (Character.isDigit(ch)) { int num = 0; int j = i; // 判断是否为多位数 while (j < s.length() && Character.isDigit(s.charAt(j))) { num = s.charAt(j++) - '0' + num * 10; } // 将数字加入操作数集 nums.push(num); // 下轮循环i应该从数字的后一位开始,即j-1,因为while中j < s.length()时 // j指向了数字的下一位,如果令i=j,则for过程i++时,i将从数字下下一位开始 i = j - 1; // ops为空,运算符和左括号直接入栈 } else if (ops.size() == 0 && ch != ')') { ops.push(ch); } // 遇到左括号直接入栈 else if (ch == '(') { ops.push(ch); } // 遇到右括号,则计算,运算符出栈(由eval完成),直到遇到栈顶为左括号,并舍弃左右括号。左括号前的运算符 // 会在eval()中出栈 else if (ch == ')') { while (ops.peek() != '(') { eval(); } ops.pop(); } // 遇到运算符 else { // 运算符栈不为空,且栈顶元素不为左括号且当前运算符优先级不大于栈顶运算符优先级, // 则对ops弹栈通过eval()进行运算,ops弹栈由eval计算过程中完成,计算直到栈顶的 // 运算符优先级小于当前运算符优先级为止,并将当前运算符入栈 while (ops.size() != 0 && ops.peek() != '(' && map.get(ops.peek()) >= map.get(ch)) { eval(); } ops.push(ch); } } // 栈中还有运算符时,循环运算至ops为空 while (ops.size() != 0) { eval(); } // 最后栈中只剩下计算结果,直接弹栈 return nums.pop(); } // 计算 public void eval() { int b = nums.pop(); int a = nums.pop(); char c = ops.pop(); int res = 0; switch (c) { case '+': res = a + b; break; case '-': res = a - b; break; case '*': res = a * b; break; } // if(c=='+') res = a + b; // else if (c=='-') res = a - b; // else if (c=='*') res = a * b; nums.push(res); } }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 返回表达式的值 * @param s string字符串 待计算的表达式 * @return int整型 */ public int solve (String s) { // write code here Map<Character,Integer> map = new HashMap<Character,Integer> (); map.put('+',1); map.put('-',1); map.put('*',2); Stack<Integer> nums = new Stack<Integer>(); Stack<Character> ops = new Stack<Character>(); int num = s.length(); char[] ss = s.toCharArray(); for (int i = 0 ; i < num; i++) { char ch = ss[i]; if (isNumber(ch)) { int temp = 0; int j = i; while (j < num && isNumber(ss[j])) { temp = temp * 10 + (ss[j] - '0'); j++; } nums.push(temp); i = j - 1; } else if (ch == '(') { ops.push(ch); }else if(ch==')'){ while(ops.peek()!='('){ calcu(nums,ops); } ops.pop(); }else{ while(!ops.isEmpty()&&ops.peek()!='('&&(map.get(ops.peek())>=map.get(ch))){ calcu(nums,ops); } ops.push(ch); } } while(!ops.isEmpty()){ calcu(nums,ops); } return nums.pop(); } public boolean isNumber (char a) { return Character.isDigit(a); } public void calcu (Stack<Integer> nums, Stack<Character> ops) { int num1 = nums.pop(); int num2 = nums.pop(); char op = ops.pop(); if (op == '+') { nums.push(num1 + num2); } else if (op == '-') { nums.push(num2 - num1) ; } else if (op == '*') { nums.push(num1 * num2); } } }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 返回表达式的值 * @param s string字符串 待计算的表达式 * @return int整型 */ public int solve (String s) { char[] chars = s.toCharArray(); Stack<Integer> numStack = new Stack<>();//运算数 Stack<Character> operatorStack = new Stack<>();//运算符 for(int i=0;i<chars.length;i++){ char curchar = chars[i]; if(isDight(curchar)){//数字 int num = 0; while(i<chars.length && isDight(chars[i])){//循环读取当前数字(多位) num = num*10+(chars[i]-'0'); i++; } i--;//将i-1当前指针指向当前数的最后一位 numStack.push(num);//数字入栈 }else if(curchar=='('){//'('入栈 operatorStack.push(curchar); }else if(curchar==')'){//遇到')'开始运算()内的表达式 while(operatorStack.peek()!='('){//多个()嵌套处理 operate(numStack,operatorStack); } operatorStack.pop();// '('出栈 }else { while(!operatorStack.isEmpty() && getPriority(curchar) <= getPriority(operatorStack.peek()) ){//当前优先级<栈内优先级 operate(numStack,operatorStack);//提取表达式计算 } operatorStack.push(curchar);//当前运算符入栈 } } while(!operatorStack.isEmpty()){//运算符不为空,继续计算 operate(numStack,operatorStack); } return numStack.pop();//返回最后结果 } private int getPriority(Character character) {//优先级 if(character == '+' || character=='-'){ return 1; }else if(character =='*' || character =='/'){ return 2; } return -1;//遇见'()'的优先级 } private void operate(Stack<Integer> numStack, Stack<Character> operatorStack) {//提取当前表达式计算 char operator = operatorStack.pop(); int rightnum = numStack.pop(); int leftnum = numStack.pop(); int newnum = compute(leftnum,operator,rightnum);//计算 numStack.push(newnum);//添加运算结果入栈 } private int compute(int a, char operator, int b) { switch (operator){ case '+': return a + b; case '-': return a-b; case '*': return a*b; case '/': if(b==0){ throw new RuntimeException("cannot not divide 0!"); } return a/b; default : throw new UnsupportedOperationException(); } } private boolean isDight(char curchar) { return curchar>='0' && curchar <='9'; } }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 返回表达式的值 * @param s string字符串 待计算的表达式 * @return int整型 */ public int solve1 (char ch, int a, int b) { switch (ch) { case '+': return b + a; case '-': return b - a; case '*': return b * a; } return 0; } public int solve (String s) { // write code here Stack<Character> stack1 = new Stack<>(); Stack<Integer> stack2 = new Stack<>(); char ch; int i = 0; String s1 = ""; short flag1 = 0; short flag2 = 0; while (i < s.length()) { ch = s.charAt(i); if (!stack1.empty() && stack1.peek() == '*'){ flag1 = 1; } if ( ch == ')') { while (stack1.peek() != '(') { int eg = solve1(stack1.pop(), stack2.pop(), stack2.pop()); stack2.push(eg); } stack1.pop(); if (flag1 == 1 && flag2 >0){ flag2--; } i++; } else { s1 = ""; while (ch != '+' && ch != '*' && ch != '-' && ch != '(' && ch != ')') { if (i < s.length() - 1) { s1 += ch; ch = s.charAt(++i); } else if (i == s.length() - 1) { s1 += ch; i++; } if (i == s.length()) { break; } } if (s1 != "") { stack2.push(Integer.parseInt(s1)); } if (flag1 == 1 && ch == '(' ){ flag2++; } if (flag1 == 1 && flag2 == 0 && !stack1.empty()){ int eg = solve1(stack1.pop(), stack2.pop(), stack2.pop()); stack2.push(eg); flag1 = 0; } if (ch == '+' || ch == '*' || ch == '(' || ch == '-') { stack1.push(ch); i++; } } } while (!stack1.empty() ) { char eg1 = stack1.pop(); if (!stack1.empty() && stack1.peek() == '-') { if (eg1 == '-') eg1 = '+'; else eg1 = '-'; } int eg2 = solve1(eg1, stack2.pop(), stack2.pop()); stack2.push(eg2); } return stack2.pop(); } }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 返回表达式的值 * @param s string字符串 待计算的表达式 * @return int整型 */ public int solve (String s) { // write code here return func(s, 0, s.length() - 1); } public int func(String s, int startIndex, int endIndex) { Stack<Integer> st = new Stack<>(); char op = '+'; for (int i = startIndex; i <= endIndex; i++) { int num = 0; boolean isNum = false; if (s.charAt(i) >= '0' && s.charAt(i) <= '9') { isNum = true; num = s.charAt(i) - '0'; while (i+1 <= endIndex && s.charAt(i+1) >= '0' && s.charAt(i+1) <= '9') { i++; num = num * 10 + (s.charAt(i) - '0'); } } if (isNum && op == '+') { st.push(num); } else if (isNum && op == '-') { st.push(0 - num); } else if (isNum && op == '*') { int preNum = st.pop(); st.push(preNum * num); } else if (!isNum && s.charAt(i) == '(') { int leftCount = 0; int nextStart = i + 1; i++; while (i <= s.length() - 1 && (s.charAt(i) != ')' || leftCount != 0)) { if (s.charAt(i) == '(') { leftCount++; } else if (s.charAt(i) == ')') { leftCount--; } i++; } int nextEnd = i - 1; num = func(s, nextStart, nextEnd); if (op == '+') { st.push(num); } else if (op == '-') { st.push(0 - num); } else if (op == '*') { int preNum = st.pop(); st.push(preNum * num); } } else if (!isNum && (s.charAt(i) == '+' || s.charAt(i) == '-' || s.charAt(i) == '*')) { op = s.charAt(i); } } int ans = 0; while (!st.isEmpty()) { ans += st.pop(); } return ans; } }
public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 返回表达式的值 * @param s string字符串 待计算的表达式 * @return int整型 */ Stack<Integer> numStack = new Stack<>(); // 数栈 Stack<Integer> operStack = new Stack<>(); // 符号栈 // 中缀表达式 /** public int solve (String s) { // 作为索引遍历表达式 int i = 0; int ch; // 存储每次取出的字符 while (true){ ch = s.charAt(i); // 根据取出的字符ch 来决定接下来的操作 if(isOper(ch)){ // 如果是运算符的话 // 如果当前符号栈为空,那么直接将符号压入栈 // 否则有两种情况, // 1.如果当前符号的优先级小于等于栈中的符号,那么就将数栈pop两个数,符号栈pop一个符号,进行运算,将运算结果压入数栈,再将当前操作符压入符号栈 // 2.如果当前符号的优先级大于栈中符号,那么就直接将符号压入栈 if(!operStack.isEmpty()){ //1.如果当前符号的优先级小于等于栈中的符号,那么就将数栈pop两个数,符号栈pop一个符号,进行运算, // 将运算结果压入数栈,再将当前操作符压入符号栈 if(priority(ch) <= priority(operStack.peek())){ cal(); } // 如果当前符号的优先级大于栈中符号,那么就直接将符号压入栈 operStack.push(ch); }else{ operStack.push(ch); } }else if(ch == '('){ // 如果是左括号,正常加入符号栈 operStack.push(ch); }else if(ch == ')'){ // 如果是右括号 //那么需要循环不断地取出数和运算符进行计算,直到找到符号栈中的左括号 while (operStack.peek() != '(') cal(); // 符号栈栈顶的符号是左括号时,while结束。那么仅需要弹出左括号即可 operStack.pop(); }else if(isNumber(ch)){ // 如果是数字 i++; // i后移一位 int tempNum = ch - '0'; // 先存储当前ch这个数字, 因为char类型的数字,转int是编码表的代码,减去0(0的代码是48)所在的代码后,正好就是当前数字的真实值 // i只要不越界,循环继续 while (i < s.length()){ // 根据i取出字符 ch = s.charAt(i); // 如果不是数字的话,就跳出while循环 if(! isNumber(ch)) break; // 执行到这里说明是数字,那么就将原来的数字 * 10 再加上当前的数字 tempNum = tempNum * 10 + (ch - '0'); // i索引后移 i++; } // 循环结束i-1,因为i此时索引位置在不等于数字的位置,因为下面有i++,所以这里返回到上一位即可 i--; // 数栈压入最终读取到的数字 numStack.push(tempNum); }else{ throw new RuntimeException("表达式解析错误"); } // 指针后移,并判断是否i越界,越界即是表达式遍历完完毕 i++; if(i >= s.length()){ break; } } // 上面循环结束后,表达式已经遍历完毕,现在只需要把数栈和符号栈的值依次取出,进行运算, // 最终数栈的最后一个数就是总的计算结果 // 只要符号栈不为空,就一直计算 while (!operStack.isEmpty()) cal(); // 最终返回数栈最后一个数 return numStack.pop(); } // 判断当前操作符号的优先级 public int priority(int ch){ if(ch == '/' || ch == '*'){ return 1; }else if(ch == '+' || ch == '-'){ return 0; } return -1; } // 判断是否是运算符 public boolean isOper(int oper){ return oper == '+' || oper == '-' || oper == '*' || oper == '/'; } // 判断是否是数字 public boolean isNumber(int ch){ return ch >= '0' && ch <= '9'; } // 计算两个数,并将结果压入数栈 public void cal(){ int num1 = numStack.pop(); int num2 = numStack.pop(); int oper = operStack.pop(); int res = 0; switch (oper){ case '+': res = num1 + num2; break; case '-': res = num2 - num1; break; case '*': res = num1 * num2; break; case '/': res = num2 / num1; break; default: throw new RuntimeException("符号错误"); } numStack.push(res); } */ // 逆波兰表达式 public int solve (String s) { // 1. 先将表达式 转为后缀表达式 List<String> expression = getExpression(s); // 2. 然后开始计算,遇到数则入数栈,遇到符号,则弹出两个数进行计算,并重新将结果压入数栈 Stack<Integer> numStack = new Stack<>(); for (String s1 : expression) { if(s1.matches("\\d+")){ numStack.push(Integer.parseInt(s1)); }else{ cal(numStack, s1); } } return numStack.pop(); } /** 将中缀表达式 转成 后缀表达式 * 步骤 * 1.初始化两个容器,运算符栈s1, 和存储中间结果的List集合s2 * 2.从左至右扫描中缀表达式 * 3.遇到操作数时,将其压入s2 * 4.遇到运算符时,比较其与s1栈顶运算符的优先级: * ① 如果s1为空 或者 s1栈顶运算符为左括号( ,则将运算符压入s1 * ② 否则,若优先级比s1栈顶运算符的高,也将其压入s1 * ③ 否则,将s1栈顶的运算符弹出并压入到s2中,再次转到(4.1) 与 s1中新的栈顶运算符相比较 * 5.遇到括号时: * ① 如果是左括号(, 则直接压入s1 * ② 如果是右括号 ), 则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将着一对括号丢弃 * 6.重复此步骤2至5,直到表达式遍历完 * 7.将s1中剩余的运算符依次弹出并压入s2 * 8.依次弹出s2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式 * * */ private List<String> getExpression(String expression){ // 初始化两个容器,运算符栈s1, 和存储中间结果的List集合s2 Stack<String> s1 = new Stack<>(); List<String> s2 = new ArrayList<>(); int i = 0; char ch; while(i < expression.length()){ if(isNumber((ch = expression.charAt(i)))){ // 如果是操作数 int temp = ch - '0'; while (++i < expression.length() && isNumber((ch = expression.charAt(i)))){ temp = temp * 10 + ch - '0'; } s2.add(String.valueOf(temp)); continue; }else if(isOper(ch)){ // 如果是运算符 while(true){ if(s1.isEmpty() || "(".equals(s1.peek())){ // 4.1 如果s1为空 或者 s1栈顶运算符为左括号( ,则将运算符压入s1 s1.push(String.valueOf(ch)); break; }else{ if(priority(ch+"") > priority(s1.peek())){ // 4.2 否则,若优先级比s1栈顶运算符的高,也将其压入s1 s1.push(String.valueOf(ch)); break; }else{ // 4.3 否则,将s1栈顶的运算符弹出并压入到s2中,再次转到(4.1) 与 s1中新的栈顶运算符相比较 s2.add(s1.pop()); } } } }else if(ch == '('){ // 如果是左括号(, 则直接压入s1 s1.push(String.valueOf(ch)); }else if(ch == ')'){ // 如果是右括号 ), 则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将着一对括号丢弃 while(!s1.isEmpty() && !"(".equals(s1.peek())) s2.add(s1.pop()); if(!s1.isEmpty()) s1.pop(); } i++; } // 7.将s1中剩余的运算符依次弹出并压入s2 while (! s1.isEmpty()) s2.add(s1.pop()); // list中 即为后缀表达式 return s2; } private boolean isNumber(int ch){ return ch >= '0' && ch <= '9'; } private boolean isOper(int ch){ return ch == '+' || ch == '-' || ch == '*' || ch == '/'; } private int priority(String ch){ if(ch.equals("+") || ch.equals("-")){ return 0; }if(ch.equals("*") || ch.equals("/")){ return 1; } return -1; } private void cal(Stack<Integer> numStack, String oper){ Integer num1 = numStack.pop(); Integer num2 = numStack.pop(); if("+".equals(oper)){ numStack.push(num1 + num2); }else if("*".equals(oper)){ numStack.push(num1 * num2); }else if("-".equals(oper)){ numStack.push(num2 - num1); }else if("/".equals(oper)){ numStack.push(num2 / num1); } } }