首页 > 试题广场 >

四则运算

[编程题]四则运算
  • 热度指数:130678 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
输入一个表达式(用字符串表示),求这个表达式的值。
保证字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。且表达式一定合法。

数据范围:表达式计算结果和过程中满足 ,字符串长度满足


输入描述:

输入一个算术表达式



输出描述:

得到计算结果

示例1

输入

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("异常数据,计算失败!");
    }
}

发表于 2021-11-19 22:33:13 回复(3)
代码有点略长。整体思路用逆波兰算法就可以了,但需要额外考虑负数和多位数的情况

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;
    }
}


发表于 2021-09-10 15:56:01 回复(1)
这是经历了什么啊!!!
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;
    }
}


发表于 2021-04-09 21:58:05 回复(3)
//利用了递归求解,程序十分简短
#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;
}

编辑于 2016-08-11 17:47:07 回复(1)

第一步,先考虑无括号的情况,先乘除后加减,遇到数字先压栈,如果下一个是乘号或除号,先出栈,和下一个数进行乘除运算,再入栈,最后就能保证栈内所有数字都是加数,最后对所有加数求和即可。

第二步,遇到左括号,直接递归执行第一步即可,最后检测到右括号,返回括号内的计算结果,退出函数,这个结果作为一个加数,返回上一层入栈。

# JAVA 版本

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));
    }
    
}
       



发表于 2021-03-03 11:17:45 回复(0)
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();
    }

}

编辑于 2019-06-18 20:28:24 回复(1)
javascript 不用 eval() 解法,正则表达式绕了我好久,欢迎改进。

while(line=readline()){
    var str = line.trim();
    var str = str.replace(/[\{\[]/g,"(").replace(/[\}\]]/g,")");

    console.log(cal(str));
}
function cal(str){
    var reg = /\(([^\(\)]+)\)/g;        
    while(reg.test(str)){
        str = str.replace(reg,function($1,$2){
            return cal2($2);
        })
    }
    return cal2(str); 
}
function cal2(str){
    var arr = [];
    var sub = "";
    for(var i = 0; i < str.length; i++){
        if(/[\+\*\/-]/.test(str[i]) && !(/[\+\*\/-]/.test(str[i-1]))){
            arr.push(sub);
            sub = "";
            arr.push(str[i]);
        }else{
            sub += str[i];
        }
    }
    arr.push(sub);
    var temp = [];
    var result = [];
    for(var i = 0; i < arr.length; i++){
        if(/[\*\/]/.test(arr[i])){
            var num1 = Number(temp.pop());
            var num2 = Number(arr[i+1]);
            if(arr[i] == "*"){
                temp.push(num1*num2);
            }else{
                temp.push(num1/num2);
            }
            i++;
        }else{
            temp.push(arr[i]);
        }
    }
    for(var i = 0; i < temp.length; i++){
        if(/[\+-]/.test(temp[i])){
            var num1 = Number(result.pop());
            var num2 = Number(temp[i+1]);
            if(temp[i] == "+"){
                result.push(num1+num2);
            }else{
                result.push(num1-num2);
            }
            i++;
        }else{
            result.push(temp[i]);
        }
    }
    return result[0];
}
发表于 2018-08-06 20:50:22 回复(1)
#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;
}

发表于 2017-03-17 15:00:00 回复(0)
两行搞定
s=input();
print(s);
发表于 2016-03-16 18:26:13 回复(6)
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字符串求解。
发表于 2021-04-11 11:39:32 回复(3)
投机取巧,利用js的eval()函数,但是只能识别圆括号,所以需要替换下。
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);
        }
    }
}


发表于 2021-12-20 17:48:38 回复(1)
我只想说,大括号和中括号,都是小括号!
发表于 2022-06-15 16:21:40 回复(0)
import re
a = input()
b = re.sub(r'\{|\[', '(', a)
c = re.sub(r'\}|\]', ')', b)
print(int(eval(c)))

发表于 2022-02-28 00:54:22 回复(0)
这题真的简单?反正我感觉这是我写过最杂乱的代码,毫无章法已经放飞自我了😐😐😑。还好本地调试后提交oj一次过。
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 + "" ;
    }
}


发表于 2021-09-23 20:33:28 回复(0)
print(eval(input()))
果然又是个python3一行就能AC的题。。。
发表于 2021-08-13 17:46:31 回复(0)
#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;
}
谢了很久,标记一下
发表于 2021-04-17 22:22:03 回复(0)
python的话可以很流氓地使用eval函数直接AC。
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;
    }
}

编辑于 2021-04-03 21:08:29 回复(0)
我的思路:
1、把输入的式子中其它{}[]转化为()的形式
2、输入的式子可能有负值,将其转化为减法运算,既前面加0
3、对于"("和空运算符栈情况下,运算符直接入栈
4、数字判断长度后,转化为int入栈
5、对于* /,运算符栈顶元素若是同级,则栈顶元素出栈运算,这样避免同出现8/2/2=8的情况
6、对于+ -,同级或高级的栈顶运算符也要出栈运算,注意2-2*3+2的特殊情况处理,代码129-142就是处理这种情况。
7对于),则直接出栈运算直到(即可
#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();
}


发表于 2021-02-20 13:32:53 回复(0)
看了好几个答案,总感觉不太优雅,最后参考了这篇博客:
下面是优雅的代码:
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 + "";
    }
}


发表于 2020-11-10 16:45:39 回复(0)
const line = readline()
const result = line.replace('{', '(').replace('}',')')
console.log(eval(result))

发表于 2020-10-19 15:46:49 回复(0)

问题信息

难度:
398条回答 47892浏览

热门推荐

通过挑战的用户

查看代码
四则运算