保证字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。且表达式一定合法。
数据范围:表达式计算结果和过程中满足 ,字符串长度满足
数据范围:表达式计算结果和过程中满足 ,字符串长度满足
输入一个算术表达式
得到计算结果
3+2*{1+2*[-4/(8-6)+7]}
25
import java.util.ArrayList; import java.util.List; import java.util.Scanner; import java.util.Stack; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNextLine()) { String str = sc.nextLine(); // 初始化,将"{}""[]"替换为"()" str = str.replace("[", "(") .replace("{", "(") .replace("]", ")") .replace("}", ")"); System.out.println(culSuffix(infixToSuffix(str))); } } // 中缀表达式 转 后缀表达式 public static List<String> infixToSuffix(String str) { List<String> result = new ArrayList<>(); Stack<Character> operateStack = new Stack<>(); boolean flag = true; String temp = ""; for (char c : str.toCharArray()) { // 负数开头处理(补零) if (flag && c == '-') { result.add("0"); } flag = false; // 多位数处理 if (c >= '0' && c <= '9') { temp += c; continue; } // 数字入栈(集合) if (temp.length() > 0) { result.add(temp); temp = ""; } // 符号入栈(集合) if (operateStack.empty() || operateStack.peek() == '(') { operateStack.push(c); } else if (c == '(') { operateStack.push(c); flag = true; } else if (c == ')'){ while (operateStack.peek() != '(') { result.add(operateStack.pop() + ""); } operateStack.pop(); } else { while (!operateStack.empty() && operateStack.peek() != '(' && getPriority(c) <= getPriority(operateStack.peek())) { result.add(operateStack.pop() + ""); } operateStack.push(c); } } // 后续处理 if (temp.length() > 0) { result.add(temp); } while (!operateStack.empty()) { result.add(operateStack.pop() + ""); } return result; } // 获取操作符优先级 public static int getPriority(char c) { if (c == '+' || c == '-') { return 1; } if (c == '*' || c == '/') { return 2; } throw new RuntimeException("异常操作符!"); } // 计算后缀表达式 public static int culSuffix(List<String> list) { Stack<Integer> numStack = new Stack<>(); Stack<String> operateStack = new Stack<>(); Integer temp = null; for (String item : list) { switch (item) { case "+" : case "-" : case "*" : case "/" : temp = cul(numStack.pop(), numStack.pop(), item); numStack.push(temp); break; default : numStack.push(Integer.parseInt(item)); } } return numStack.peek(); } // 计算加 减 乘 除 public static int cul(int num1, int num2, String operate) { switch (operate) { case "+" : return num2 + num1; case "-" : return num2 - num1; case "*" : return num2 * num1; case "/" : return num2 / num1; } throw new RuntimeException("异常数据,计算失败!"); } }
import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { String exp = scanner.next(); System.out.println(method1(exp)); } } /** * 四则运算问题,优先使用栈及逆波兰算法 * 1. 先从中缀符号转为后缀符号 * 2. 使用后缀符号计算表达式 * * @param exp * @return */ private static int method1(String exp) { // 中缀表达式转后缀表达式 ArrayList<String> suffixExp = infixToSuffixExp(exp); // 使用后缀表达式计算结果 return computeResult(suffixExp); } /** * 使用后缀表达式计算结果 * 后缀表达式计算结果的方式: * 从左到右遍历后缀表达式,按如下规则进行 * - 若为数字,则入栈 * - 若为符号,则将栈内的前两个数字取出,先出栈作为减数/除数,后出栈的作为被减数/被除数,之后再将结果入栈。 * * 循环以上步骤,直到遍历结束 * @param suffixExp * @return */ private static int computeResult(ArrayList<String> suffixExp) { Stack<Integer> stack = new Stack<>(); for (String s : suffixExp) { switch (s) { case "-": Integer minuend = stack.pop(); stack.push(stack.pop() - minuend); break; case "/": Integer divisor = stack.pop(); stack.push(stack.pop() / divisor); break; case "*": stack.push(stack.pop() * stack.pop()); break; case "+": stack.push(stack.pop() + stack.pop()); break; default: stack.push(Integer.parseInt(s)); break; } } return stack.pop(); } /** * 中缀表达式转后缀表达式: * 从左到右遍历字符串,按如下规则进行 * - 若为数字,直接输出 * - 若为符号,则判断与栈顶元素的优先级,如果优先级大于栈顶元素,则入栈,否则栈顶元素依次出栈并输出,随后当前元素入栈。 * - 若为左括号,直接入栈 * - 若为右括号,则一直出栈并输出至前一个左括号,但括号不输出 * 遍历结束后,将所有栈顶元素出栈 * @param exp * @return */ private static ArrayList<String> infixToSuffixExp(String exp) { // 用于通过右括号匹配到对应的左括号 Map<Character, Character> symbol = new HashMap<Character, Character>() { { put('}', '{'); put(']', '['); put(')', '('); } }; // 定义优先级,优先级越高数字越小 Map<Character, Integer> priority = new HashMap<Character, Integer>() { { put('*', 1); put('/', 1); put('-', 2); put('+', 2); } }; ArrayList<String> result = new ArrayList<>(); Stack<Character> stack = new Stack<>(); boolean minus = priority.containsKey(exp.charAt(0)); for(int i = 0; i < exp.length(); ++i) { char item = exp.charAt(i); // 若为数字时,直接输出 if (item >= '0' && item <= '9') { StringBuilder builder = new StringBuilder(); int j = i; // 循环处理多位数的情况 while(j < exp.length() && exp.charAt(j) >= '0' && exp.charAt(j) <= '9') { builder.append(exp.charAt(j)); j++; } i = --j; result.add(builder.toString()); minus = false; continue; } // 对负数的处理,当上一次保存的数据也是符号时,本次保存符号前增加一个 0 if (priority.containsKey(item)) { if (minus) { result.add("0"); } else { minus = true; } } // 若栈中没有数据,并且不为数字时,直接入栈 if (stack.empty()) { stack.push(item); continue; } // 若为左括号时,直接入栈 if (symbol.containsValue(item)) { stack.push(item); continue; } // 若为右括号时,将栈中左括号之前的符号全部出栈 if (symbol.containsKey(item)) { while (!stack.peek().equals(symbol.get(item))) { result.add(String.valueOf(stack.pop())); } // 最后一次需要将左括号移除 stack.pop(); continue; } // 当前元素优先级小于或等于栈顶元素则输出栈顶元素.(还需要保证 stack 不为空以及在优先级中能找到对应的类型) while (!stack.empty() && priority.containsKey(stack.peek()) && priority.get(stack.peek()) <= priority.get(item) ) { result.add(String.valueOf(stack.pop())); } // 当前元素入栈 stack.push(item); } // 所有栈中元素出栈 while(!stack.empty()) { result.add(String.valueOf(stack.pop())); } return result; } }
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { Deque<Integer> result = new ArrayDeque<>(); List<String> postfix = toPostfix(sc.next()); for (String e : postfix) { if (e.equals("_")) { int temp = -result.pop(); result.push(temp); } else if (e.equals("+") || e.equals("-") || e.equals("*") || e.equals("/")) { int b = result.pop(); int a = result.pop(); if (e.equals("+")) { result.push(a + b); } else if (e.equals("-")) { result.push(a - b); } else if (e.equals("*")) { result.push(a * b); } else { result.push(a / b); } } else { result.push(Integer.parseInt(e)); } } System.out.println(result.pop()); } } private static List<String> toPostfix(String exp) { List<String> postfix = new ArrayList<>(); Deque<String> stack = new ArrayDeque<>(); for (int i = 0; i < exp.length(); ++i) { if (exp.charAt(i) == '+') { if (stack.isEmpty()) { stack.push(String.valueOf(exp.charAt(i))); } else { while (!stack.isEmpty() && (stack.peek().equals("_") || stack.peek().equals("*") || stack.peek().equals("/") || stack.peek().equals("+") || stack.peek().equals("-"))) { postfix.add(stack.pop()); } stack.push(String.valueOf(exp.charAt(i))); } } else if (exp.charAt(i) == '-') { if (i == 0) { stack.push("_"); } else { if (exp.charAt(i - 1) == '(' || exp.charAt(i - 1) == '[' || exp.charAt(i - 1) == '{') { stack.push("_"); } else { if (stack.isEmpty()) { stack.push("-"); } else { while (!stack.isEmpty() && (stack.peek().equals("_") || stack.peek().equals("*") || stack.peek().equals("/") || stack.peek().equals("+") || stack.peek().equals("-"))) { postfix.add(stack.pop()); } stack.push("-"); } } } } else if (exp.charAt(i) == '*' || exp.charAt(i) == '/') { if (stack.isEmpty()) { stack.push(String.valueOf(exp.charAt(i))); } else { while (!stack.isEmpty() && (stack.peek().equals("_") || stack.peek().equals("*") || stack.peek().equals("/"))) { postfix.add(stack.pop()); } stack.push(String.valueOf(exp.charAt(i))); } } else if (exp.charAt(i) == '(' || exp.charAt(i) == '[' || exp.charAt(i) == '{') { stack.push(String.valueOf(exp.charAt(i))); } else if (exp.charAt(i) == ')') { while (!stack.isEmpty() && !stack.peek().equals("(")) { postfix.add(stack.pop()); } stack.pop(); } else if (exp.charAt(i) == ']') { while (!stack.isEmpty() && !stack.peek().equals("[")) { postfix.add(stack.pop()); } stack.pop(); } else if (exp.charAt(i) == '}') { while (!stack.isEmpty() && !stack.peek().equals("{")) { postfix.add(stack.pop()); } stack.pop(); } else { StringBuilder num = new StringBuilder(); while (i < exp.length() && (exp.charAt(i) >= '0' && exp.charAt(i) <= '9')) { num.append(exp.charAt(i)); ++i; } --i; postfix.add(num.toString()); } } while (!stack.isEmpty()) { postfix.add(stack.pop()); } return postfix; } }
//利用了递归求解,程序十分简短 #include <iostream> #include <string> #include <sstream> #include <deque> using namespace std; void addNum(deque<string>& Q,int num){ if(!Q.empty()){ int cur=0; if(Q.back()=="*"||Q.back()=="/"){ string top=Q.back(); Q.pop_back(); stringstream ss(Q.back()); ss>>cur; Q.pop_back(); num=top=="*"?(cur*num):(cur/num); } } stringstream ss; ss<<num; Q.push_back(ss.str()); } int getNum(deque<string>& Q){ int num=0,R=0; string f("+"); while(!Q.empty()){ stringstream ss(Q.front()); ss>>num; Q.pop_front(); R=(f=="+")?(R+num):(R-num); if(!Q.empty()){ f=Q.front(); Q.pop_front(); } } return R; } int* value(string& s,int i){ deque<string> Q; int pre=0; while(i<s.length()&&s[i]!=')'&&s[i]!=']'&&s[i]!='}'){ if(s[i]>='0'&&s[i]<='9'){ pre=pre*10+s[i++]-'0'; }else if(s[i]!='('&&s[i]!='['&&s[i]!='{'){ addNum(Q,pre); string ss; ss+=s[i++]; Q.push_back(ss); pre=0; }else{ int* bra=NULL; bra=value(s,i+1); pre=bra[0]; i=bra[1]+1; } } addNum(Q,pre); int *R=new int[2]; R[0]=getNum(Q); R[1]=i; return R; } int main(){ string s; while(cin>>s){ int *R=value(s,0); cout<<R[0]<<endl; } return 0; }
第一步,先考虑无括号的情况,先乘除后加减,遇到数字先压栈,如果下一个是乘号或除号,先出栈,和下一个数进行乘除运算,再入栈,最后就能保证栈内所有数字都是加数,最后对所有加数求和即可。
import java.io.*; import java.util.Stack; public class Main{ static int pos; public static int compute(String s){ char ops = '+'; int num = 0; Stack<Integer> val = new Stack<>(); int temp; while(pos < s.length()){ if(s.charAt(pos) == '{' || s.charAt(pos) == '[' || s.charAt(pos) == '('){ pos++; num = compute(s); } while(pos < s.length() && Character.isDigit(s.charAt(pos))){ num = num * 10 + s.charAt(pos) - '0'; pos++; } switch (ops){ case '+': val.push(num); break; case '-': val.push(-num); break; case '*': temp = val.pop(); temp = temp * num; val.push(temp); break; case '/': temp = val.pop(); temp = temp / num; val.push(temp); break; } num = 0; if(pos < s.length()) { ops = s.charAt(pos); if(s.charAt(pos) == '}' || s.charAt(pos) == ']' || s.charAt(pos) == ')'){ pos++; break; } } pos++; } int sum = 0; while(!val.isEmpty()){ sum += val.pop(); } return sum; } public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str = br.readLine(); pos = 0; System.out.println(compute(str)); } }
import java.util.ArrayList; import java.util.Scanner; import java.util.Stack; public class Main { private static Stack<Character> stack = new Stack<>(); private static StringBuilder postFix = new StringBuilder(); private static ArrayList<Integer> digitCnt = new ArrayList<>(); public static void main(String[] args) { Scanner sc= new Scanner(System.in); while (sc.hasNext()) { String str = sc.next(); String postFix = trans(str); int res = cal(postFix); System.out.println(res); } } //中缀表达式转成后缀表达式 static String trans(String inFix){ String newInFix = inFix.replace('{', '(') //都换成小括号 .replace('}', ')') .replace(']', ')') .replace('[', '('); char[] chars = newInFix.toCharArray(); for (int i = 0; i < chars.length; ++i){ if (Character.isDigit(chars[i])){ int temp = 0; //加上i < chars.length,否则数组越界 while (i < chars.length && Character.isDigit(chars[i])) { postFix.append(chars[i]); ++i; ++temp; } --i; digitCnt.add(temp); }else if (chars[i] == '('){ stack.push(chars[i]); }else if (chars[i] == '+' || chars[i] == '-'){ if (chars[i] == '-' && chars[i - 1] == '('){ postFix.append('0'); digitCnt.add(1); } while (!stack.isEmpty() && (stack.peek() == '*' || stack.peek() == '/' || stack.peek() == '+' || stack.peek() == '-')){ postFix.append(stack.peek()); stack.pop(); } stack.push(chars[i]); }else if (chars[i] == '*' || chars[i] == '/'){ while (!stack.isEmpty() && (stack.peek() == '*' || stack.peek() == '/')){ postFix.append(stack.peek()); stack.pop(); } stack.push(chars[i]); }else { while (!stack.isEmpty() && stack.peek() != '('){ postFix.append(stack.peek()); stack.pop(); } stack.pop(); } } while (!stack.isEmpty()){ postFix.append( stack.pop()); } return postFix.toString(); } //计算后缀表达式的值 static int cal(String postFix){ int index = 0; Stack<Integer> stack1 = new Stack<>(); char[] chas = postFix.toCharArray(); for (int i = 0; i < chas.length; i++) { if (Character.isDigit(chas[i])){ int total = 0; int cnt = digitCnt.get(index); while (cnt-- > 0){ total = 10 * total + (chas[i++] - '0'); } --i; stack1.push(total); ++index; }else { int num1 = stack1.peek(); stack1.pop(); int num2 = stack1.peek(); stack1.pop(); if (chas[i] == '+'){ stack1.push(num1 + num2); }else if (chas[i] == '-'){ stack1.push(num2 - num1); }else if (chas[i] == '*'){ stack1.push(num1 * num2); }else { stack1.push(num2 / num1); } } } return stack1.peek(); } }
}function cal2(str){
#include<iostream> #include<stack> #include<vector> #include<string> using namespace std; //先转为逆波兰表达式再求值 class Solution { public: int evaluateExpression(vector<string> &expression) { if (expression.empty()) return 0; vector<string> op; //符号栈 vector<int> exp; //结果栈 for (unsigned int i = 0; i < expression.size(); ++i) {//逐个扫描 if (expression[i] == "+" || expression[i] == "-") {//处理"+","-" if (op.size() == 0) op.push_back(expression[i]); else {//满足以下情况一直出栈 while (op.size() != 0 && (op[op.size() - 1] == "+" || op[op.size() - 1] == "-" || op[op.size() - 1] == "*" || op[op.size() - 1] == "/")) { string s = op.back(); op.pop_back(); int op2 = exp.back(); exp.pop_back(); int op1 = exp.back(); exp.pop_back(); if (s == "+") exp.push_back(op1 + op2); else if (s == "-") exp.push_back(op1 - op2); else if (s == "*") exp.push_back(op1 * op2); else exp.push_back(op1 / op2); } op.push_back(expression[i]); } }//end +,- else if (expression[i] == "*" || expression[i] == "/") {//处理*,/ if (op.size() == 0) op.push_back(expression[i]); else if (op[op.size() - 1] == "*" || op[op.size() - 1] == "/") { string s = op.back(); op.pop_back(); int op2 = exp.back(); exp.pop_back(); int op1 = exp.back(); exp.pop_back(); if (s == "*") exp.push_back(op1 * op2); else exp.push_back(op1 / op2); op.push_back(expression[i]); } else op.push_back(expression[i]); }//end *,/ else if (expression[i] == "(") { op.push_back(expression[i]); } else if (expression[i] == ")") {//处理右括号 while (op.back() != "(") { string s = op.back(); op.pop_back(); int op2 = exp.back(); exp.pop_back(); int op1 = exp.back(); exp.pop_back(); if (s == "+") exp.push_back(op1 + op2); else if (s == "-") exp.push_back(op1 - op2); else if (s == "*") exp.push_back(op1 * op2); else exp.push_back(op1 / op2); } op.pop_back(); }//end ) else {//处理数字 exp.push_back(atoi(expression[i].c_str())); }//done }//end if while (!op.empty()) { string s = op.back(); op.pop_back(); int op2 = exp.back(); exp.pop_back(); int op1 = exp.back(); exp.pop_back(); if (s == "+") exp.push_back(op1 + op2); else if (s == "-") exp.push_back(op1 - op2); else if (s == "*") exp.push_back(op1 * op2); else exp.push_back(op1 / op2); } if (exp.empty()) return 0; return exp[0]; } }; void preDeal(vector<string>& res, string str) { for (int i = 0; i < str.size();++i) { if (str[i] == '+' || str[i] == '*' || str[i] == '/' || str[i] == '(' || str[i] == ')') res.push_back(str.substr(i, 1)); else if (str[i] == '-') { if (i == 0 || (!isalnum(str[i - 1]) && str[i - 1] != ')')) res.push_back("0"); res.push_back("-"); } else if (str[i] == '{' || str[i] == '[') res.push_back("("); else if (str[i] == '}' || str[i] == ']') res.push_back(")"); else {//digit(s?) int j = 1; while (i + j < str.size() && isalnum(str[i + j])) ++j; res.push_back(str.substr(i, j)); i += j - 1; } } } int main() { string str; Solution s; while (getline(cin, str)) { vector<string> tmp; preDeal(tmp, str); //for (auto s : tmp) cout << s << " "; cout << s.evaluateExpression(tmp) << endl; } return 0; }
import java.util.Scanner; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; public class Main{ public static void main(String[] args) throws Exception{ Scanner scanner = new Scanner(System.in); while (scanner.hasNextLine()) { String input = scanner.nextLine(); ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("js"); Object result = engine.eval(input); System.out.println(result.toString()); } scanner.close(); } }这个可能是最简单的java解法,评估为js字符串求解。
import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import java.util.Scanner; public class Main { public static void main(String[] args) throws ScriptException { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { String str = sc.nextLine().replaceAll("\\{","(").replaceAll("\\[","(") .replaceAll("}",")").replaceAll("]",")"); ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine se = manager.getEngineByName("js"); Object o = se.eval(str); System.out.println(o); } } }
import re a = input() b = re.sub(r'\{|\[', '(', a) c = re.sub(r'\}|\]', ')', b) print(int(eval(c)))
import java.util.Scanner; import java.util.Stack; /** * @author Yuliang.Lee * @version 1.0 * @date 2021/9/23 18:37 * 四则运算: 输入一个表达式(用字符串表示),求这个表达式的值。 保证字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。且表达式一定合法。 * 解题思路:(栈、递归) 第一步,先考虑无括号的情况,先乘除后加减,这个用栈很容易解决,遇到数字先压栈,如果下一个是乘号或除号,先出栈,和下一个数进行乘除运算,再入栈,最后就能保证栈内所有数字都是加数,最后对所有加数求和即可。 (注:将所有的减号都看成是负数,乘除则出栈运算后再将结果入栈,所以最后数字栈中的所有元素之间的运算符必定都是加号) 第二步,遇到左括号,直接递归执行第一步即可,最后检测到右括号,返回括号内的计算结果,退出函数,这个结果作为一个加数,返回上一层入栈。 * 示例 输入:3+2*{1+2*[-4/(8-6)+7]} 输出:25 */ public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); while (in.hasNext()) { String expr = in.nextLine(); System.out.println(calculate(expr, 0)); } } public static String calculate(String expr, int index) { // 数字栈(包含负数) Stack<Integer> numbers = new Stack<>(); // 考虑有负数和减号的情况 boolean negative = false; // 考虑有多位数的情况 StringBuilder tmp = new StringBuilder(); // flag为1的时候即运算符为乘除时,等待运算;为0才可以允许本趟的数字压栈 int flag = 0; char op = ' '; for (int i = index; i < expr.length(); i++) { char ch = expr.charAt(i); if (ch >= '0' && ch <= '9') { tmp.append(ch); } else { if (tmp.length() > 0) { // 数字入栈 if (flag == 0 ) { numbers.push(Integer.parseInt(negative ? ('-' + tmp.toString()) : tmp.toString())); tmp.delete(0, tmp.length()); negative = false; } // 进行乘除运算 else { int a = numbers.pop(); int b = Integer.parseInt(negative ? ('-' + tmp.toString()) : tmp.toString()); switch (op) { case '*': numbers.push(a * b); break; case '/': numbers.push(a / b); break; default: break; } tmp.delete(0, tmp.length()); negative = false; flag = 0; op = ' '; } } // 处理本次字符 if (ch == '-') { negative = true; } else if (ch == '*' || ch == '/') { flag = 1; op = ch; } else if (ch == '{' || ch == '[' || ch == '(') { // 递归调用函数 String[] middleResult = calculate(expr, i+1).split(","); // 处理递归返回的结果 tmp.append(middleResult[0]); i = Integer.parseInt(middleResult[1]); } else if (ch == '}' || ch == ']' || ch == ')') { // 计算函数的结果值 int sum = 0; for (Integer number : numbers) { sum += number; } // 返回递归值 return sum + "," + i; } } } // 处理最后一次的数字和运算 if (tmp.length() != 0) { int b = Integer.parseInt(negative ? ('-' + tmp.toString()) : tmp.toString()); if (flag == 1) { int a = numbers.pop(); switch (op) { case '*': numbers.push(a * b); break; case '/': numbers.push(a / b); break; default: break; } } else { numbers.push(b); } } // 返回最终的结果值 int result = 0; for (Integer number : numbers) { result += number; } return result + "" ; } }
#include <iostream> #include <stack> using namespace std; string expresstrancela( string mid_express) { //中缀表达式转后缀表达式 string post_express; stack<char> oprerator_stack; oprerator_stack.push('#'); //将表达式中的大括号中括号替换为小括号 for (int i=0;i<mid_express.size();i++) { char c = mid_express[i]; if ((c=='[')||(c=='{')) { mid_express[i] = '('; } if ((c==']')||(c=='}')) { mid_express[i] = ')'; } } if (*mid_express.begin() == '-') { mid_express.insert(mid_express.begin(),0); } for (auto m = mid_express.begin()+1; m!= mid_express.end();m++ ) { if (((*m == '-')&& ((*(m-1) < '0') || *(m-1) > '9')) && (*(m-1) != ')')) { mid_express.insert(m,'0'); } } for (int i=0;i<mid_express.size();i++) { char c = mid_express[i]; if (isdigit(mid_express[i])) { if (((i+1)<mid_express.size())&&(isdigit(mid_express[i+1]))) { post_express.push_back(mid_express[i++]); post_express.push_back(mid_express[i]); post_express.push_back(','); } else { post_express.push_back(mid_express[i]); post_express.push_back(','); } continue; } if (c == '(') { oprerator_stack.push(c); continue; } if (c == ')') { while('(' != oprerator_stack.top()) { char c_temp = oprerator_stack.top(); post_express.push_back(c_temp); post_express.push_back(','); oprerator_stack.pop(); } oprerator_stack.pop(); continue; } if (((c =='*')||(c =='/'))&&(('+'== oprerator_stack.top())||('-'== oprerator_stack.top()))) { oprerator_stack.push(c); continue; } else { if ((c =='+')||(c =='-')) { while((oprerator_stack.top() == '+')||(oprerator_stack.top() == '-')||(oprerator_stack.top() == '*')||(oprerator_stack.top() == '/')) { post_express.push_back(oprerator_stack.top()); post_express.push_back(','); oprerator_stack.pop(); } oprerator_stack.push(c); } if ((c =='*')||(c =='/')) { while((oprerator_stack.top() == '*')||(oprerator_stack.top() == '/')) { post_express.push_back(oprerator_stack.top()); post_express.push_back(','); oprerator_stack.pop(); } oprerator_stack.push(c); } continue; } } while(oprerator_stack.top()!='#') { post_express.push_back(oprerator_stack.top()); post_express.push_back(','); oprerator_stack.pop(); } return post_express; } int calpost_express(string post_express) { stack<int> digtal_stack; while( post_express.find(',') != string::npos ) { int ipos = post_express.find(','); string sub = post_express.substr(0,ipos); post_express = post_express.substr(ipos+1,post_express.size()-ipos-1); //char c_temp = post_express[i]; if ((string::npos == sub.find('+'))&&(string::npos == sub.find('-'))&&(string::npos == sub.find('*'))&&(string::npos == sub.find('/'))) { int digtal = stoi(sub); digtal_stack.push(digtal); } if ("+" == sub) { int b = digtal_stack.top(); digtal_stack.pop(); int a = digtal_stack.top(); digtal_stack.pop(); int c = a + b; digtal_stack.push(c); } if ("-" == sub) { int b = digtal_stack.top(); digtal_stack.pop(); int a = digtal_stack.top(); digtal_stack.pop(); int c = a - b; digtal_stack.push(c); } if ("*" == sub) { int b = digtal_stack.top(); digtal_stack.pop(); int a = digtal_stack.top(); digtal_stack.pop(); int c = a * b; digtal_stack.push(c); } if ("/" == sub) { int b = digtal_stack.top(); digtal_stack.pop(); int a = digtal_stack.top(); digtal_stack.pop(); int c = a / b; digtal_stack.push(c); } } return digtal_stack.top(); } int main() { string mid_express; while(cin>>mid_express) { //中缀转后缀 string post_express = expresstrancela(mid_express); //计算后缀表达式值 int value = calpost_express(post_express); cout << value << endl; } return 0; }谢了很久,标记一下
print(eval(raw_input().replace('{', '(').replace('}', ')').replace('[', '(').replace(']', ')')))但是面试的话这么搞肯定GG,正儿八经地做应该是先把中缀表达式转化为后缀表达式,然后用栈对后缀表达式进行计算。这里负数需要注意一下:如果当前字符为'-',则在前一个字符为左括号或者当前字符'-'为第一个字符时,不能将它视为减号,应该将其与后面的数字字符看作一个整体,为负数。
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.util.ArrayList; import java.util.Stack; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String expr; while((expr = br.readLine()) != null) { // 先把大括号和中括号都替换为小括号 expr = expr.trim().replaceAll("\\{", "\\(").replaceAll("\\[", "\\(").replaceAll("\\}", "\\)").replaceAll("\\]", "\\)"); ArrayList<String> list = new ArrayList<>(); Stack<String> stack = new Stack<>(); // 中缀表达式转后缀表达式 int i = 0, sign = 1; while(i < expr.length()){ if(expr.charAt(i) >= '0' && expr.charAt(i) <= '9'){ int num = 0; while(i < expr.length() && expr.charAt(i) >= '0' && expr.charAt(i) <= '9'){ num = 10*num + (expr.charAt(i) - '0'); i ++; } list.add(String.valueOf(sign * num)); sign = 1; // 符号用完之后先变成正 }else if(expr.charAt(i) == '('){ // 遇到左括号直接入栈 stack.push(expr.substring(i, i + 1)); i ++; }else if(expr.charAt(i) == ')'){ // 遇到右括号先要进行一波弹栈,知道遇到左括号 while(!(stack.peek().equals("("))) list.add(stack.pop()); stack.pop(); // 将左括号也弹出 i ++; }else{ // 减号是数字前面的负号的情况 if((i == 0 && expr.charAt(i) == '-') || (i > 0 && expr.charAt(i) == '-' && expr.charAt(i - 1) == '(')){ sign = -1; i ++; continue; } // 遇到运算符要判断优先级 while(!stack.isEmpty() && priority(expr.charAt(i)) <= priority(stack.peek().toCharArray()[0])) list.add(stack.pop()); stack.push(expr.substring(i, i + 1)); // 优先级比栈顶大直接入栈 i ++; } } while(!stack.isEmpty()) list.add(stack.pop()); // 计算后缀表达式 Stack<Integer> nums = new Stack<>(); for(String item: list){ if(item.matches("-?\\d+")) nums.push(Integer.parseInt(item)); else{ int num2 = nums.pop(); int num1 = nums.pop(); if(item.equals("+")) nums.push(num1 + num2); else if(item.equals("-")) nums.push(num1 - num2); else if(item.equals("*")) nums.push(num1 * num2); else if(item.equals("/")) nums.push(num1 / num2); } } System.out.println(nums.pop()); } } // 获得运算符优先级 private static int priority(char op) { if(op == '+' || op == '-') return 1; else if(op == '*' || op == '/') return 2; return 0; } }
#include <iostream> #include <stack> #include <string> #include <algorithm> using namespace std; void change_bracket(string& str); //改变'{'['为'(',改']','}'为')' void addZero(string& str); //判断表达式的是否为有负值,有则前面加0,改为剑减法 int handler(string& str); int caculate(char s, int a, int b); //进行计算 int main() { string input; cin >> input; change_bracket(input); addZero(input); int sum = handler(input); cout << sum << endl; } void change_bracket(string& str) { for (auto it = str.begin(); it != str.end(); it++) { if (*it == '{' || *it == '[') *it = '('; if (*it == '}' || *it == ']') *it = ')'; } } void addZero(string& str) { if (*str.begin() == '-') { str.insert(str.begin(), '0'); } for (auto m = str.begin() + 1; m != str.end(); m++) { if (((*m == '-' && *(m - 1) < '0') || (*m == '-' && *(m - 1) > '9'))&&*(m-1)!=')') m = str.insert(m, '0'); } } int caculate(char s, int a, int b) { int c = 0; switch (s) { case '*': c = a * b; break; case '/': c = a / b; break; case '+': c = a + b; break; case '-': c = a - b; break; default: break; } return c; } int handler(string& str) { int sum = 0; stack<int> in_num; //数字栈 stack<char> in_char; //运算符栈 char tmp; int a = 0, b = 0; for (int i = 0; i < str.length(); i++) { if (isdigit(str[i])) {//处理数字 int j = i, num = 0; while (i + 1 < str.length() && isdigit(str[i + 1])) { i++; } //拷贝子串数字 string str_num = str.substr(j, i - j + 1); for (int k = 0; k < str_num.size(); k++) {//转为数字 num = num * 10 + str_num[k] - '0'; } //压入数字栈 in_num.push(num); } //处理(,空运算符栈,直接压入 else if (str[i] == '(' || in_char.empty()) in_char.push(str[i]); //处理*,/,既同级的直接前一个先算 else if (str[i] == '*' || str[i] == '/') { tmp = in_char.top(); if (!in_char.empty() && (tmp == '/' || tmp == '*'))//要弹出/进行计算 { b = in_num.top(); in_num.pop(); a = in_num.top(); in_num.pop(); in_num.push(caculate(tmp, a, b)); in_char.pop(); } in_char.push(str[i]); } //处理+ - else if (str[i] == '+' || str[i] == '-') { //同理,同级和高级的先处理 tmp = in_char.top(); if (!in_char.empty() && (tmp == '+' || tmp == '-' || tmp=='*' ||tmp=='/' )) { b = in_num.top(); in_num.pop(); a = in_num.top(); in_num.pop(); in_num.push(caculate(tmp, a, b)); in_char.pop(); } if (!in_char.empty()) { tmp = in_char.top(); if (tmp == '+' || tmp == '-') { b = in_num.top(); in_num.pop(); a = in_num.top(); in_num.pop(); in_num.push(caculate(tmp, a, b)); in_char.pop(); } } in_char.push(str[i]); } //处理) else if (str[i] == ')') { tmp = in_char.top(); while (tmp != '(') { b = in_num.top(); in_num.pop(); a = in_num.top(); in_num.pop(); in_num.push(caculate(tmp, a, b)); in_char.pop(); //更新tmp tmp = in_char.top(); } //弹出( in_char.pop(); } } while (!in_char.empty()) { tmp = in_char.top(); b = in_num.top(); in_num.pop(); a = in_num.top(); in_num.pop(); in_num.push(caculate(tmp, a, b)); in_char.pop(); } return in_num.top(); }
import java.util.Scanner; import java.util.Stack; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Arithmetic { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { String input = scanner.next(); System.out.println(getResult(input)); } } public static int getResult(String input) { Pattern pattern = Pattern.compile("((?<![\\d)])-?\\d+(\\.\\d+)?|[+\\-*/()])"); input = input.replaceAll("[{\\[]", "(").replaceAll("[}\\]]", ")"); Matcher matcher = pattern.matcher(input); Stack<String> number = new Stack<>(); Stack<String> operator = new Stack<>(); operator.push("null"); while (matcher.find()) { String temp = matcher.group(); if (temp.matches("[()]")) { if ("(".equals(temp)) { operator.push("("); } else { String b = null; while (!(b = operator.pop()).equals("(")) { number.push(calculate(b, number.pop(), number.pop())); } } } else if (temp.matches("[+\\-*/]")) { if (getPriority(temp) > getPriority(operator.peek())) { operator.push(temp); } else { while (getPriority(temp) <= getPriority(operator.peek())) { number.push(calculate(operator.pop(), number.pop(), number.pop())); } operator.push(temp); } } else { number.push(temp); } } while (number.size() > 1) { number.push(calculate(operator.pop(), number.pop(), number.pop())); } return (int) Double.parseDouble(number.pop()); } private static int getPriority(String b) { switch (b) { case "null": return 1; case "(": return 2; case "+": case "-": return 3; case "*": case "/": return 4; } return 0; } private static String calculate(String b, String a1, String a2) { double result = 0; double d1 = Double.parseDouble(a2); double d2 = Double.parseDouble(a1); switch (b) { case "+": result = d1 + d2; break; case "-": result = d1 - d2; break; case "*": result = d1 * d2; break; case "/": result = d1 / d2; break; } return result + ""; } }
const line = readline() const result = line.replace('{', '(').replace('}',')') console.log(eval(result))