首页 > 试题广场 >

公式字符串求值

[编程题]公式字符串求值
  • 热度指数:2226 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个字符串str,str表示一个公式,公式里可以有整数,加减乘除和左右括号,返回公式的计算结果(注意:题目中所有运算都是整型运算,向下取整,且保证数据合法,不会出现除0等情况)。

输入描述:
输出一行字符串,代表str(保证str计算的结果不会出现除零,int溢出等情况)。


输出描述:
输出一个整数,代表表达式的计算结果。
示例1

输入

48*((70-65)-43)+8*1

输出

-1816
示例2

输入

3+1*4

输出

7
用的左老师的解法,遇到左括号不去管与之匹配的右括号在哪,而是直接跳过括号,递归计算括号中表达式的值返回来使用。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Stack;
import java.util.LinkedList;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String expression = br.readLine().trim();
        System.out.println(process(expression.toCharArray(), 0)[0]);
    }
    
    // 计算表达式expression从i开始到第一个遇到的右括号或字符串尾的结果
    private static int[] process(char[] expression, int i) {
        Stack<String> stack = new Stack<>();
        int num = 0;
        while(i < expression.length && expression[i] != ')'){
            if(expression[i] >= '0' && expression[i] <= '9'){
                // 遇到数字
                num = num * 10 + expression[i] - '0';
                i++;
            }else if(expression[i] != '('){     // 遇到运算符
                addNum(stack, num);
                stack.push(String.valueOf(expression[i]));
                num = 0;
                i++;
            }else{
                // 遇到左括号或结尾
                int[] pair = process(expression, i + 1);      // 跳过左括号算后面的表达式
                num = pair[0];
                i = pair[1] + 1;
            }
        }
        addNum(stack, num);
        return new int[]{getNum(stack), i};
    }
    
    private static void addNum(Stack<String> stack, int cur) {
        if(!stack.isEmpty()){
            String opt = stack.pop();
            if(opt.equals("+") || opt.equals("-")){
                stack.push(opt);
            }else{
                // 栈顶为乘除运算,先计算再压栈
                int prev = Integer.parseInt(stack.pop());
                cur = opt.equals("*")? prev * cur: prev / cur;
            }
        }
        stack.push(String.valueOf(cur));
    }
    
    private static int getNum(Stack<String> stack) {
        LinkedList<String> que = new LinkedList<>(stack);     // 最后清算阶段得从左往右计算,还是得顺序表
        int res = 0;
        boolean add = true;
        int num = 0;
        while(!que.isEmpty()){
            String cur = que.pollFirst();
            if(cur.equals("+")){
                add = true;
            }else if(cur.equals("-")){
                add = false;
            }else{
                num = Integer.valueOf(cur);
                res += add? num: -num;
            }
        }
        return res;
    }
}

发表于 2021-12-03 23:21:50 回复(0)