首页 > 试题广场 >

表达式求值

[编程题]表达式求值
  • 热度指数:81101 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
请写一个整数计算器,支持加减乘三种运算和括号。

数据范围:,保证计算结果始终在整型范围内

要求:空间复杂度: ,时间复杂度
示例1

输入

"1+2"

输出

3
示例2

输入

"(2*(3-4))*5"

输出

-10
示例3

输入

"3+2*3*4-1"

输出

26
class Solution:
    def solve(self , s ):
        # write code here
        return eval(s)
发表于 2021-04-07 20:50:31 回复(3)
看了很久别人的答案,自己写了一个简洁易懂的版本。
【双栈思路】
情况1:是数,直接压nums栈;
情况2:是 '(' ,直接压opts栈;
情况3:是 ')' ,先计算opts栈中 '(' 前的操作符,然后将 '('弹出;
情况4:是 '+-*' ,先计算opts栈中 '(' 前的、优先级>=它的操作符,然后将它压栈;
import java.util.*;

public class Solution {
    public static int solve (String s) {
        Map<Character,Integer> map = new HashMap<>();    //存优先级的map
        map.put('-', 1);
        map.put('+', 1);
        map.put('*', 2);
        Deque<Integer> nums = new ArrayDeque<>();    // 数字栈
        Deque<Character> opts = new ArrayDeque<>();    // 操作符栈
        s.replaceAll(" ","");    // 去空格
        char[] chs = s.toCharArray();
        int n = chs.length;

        for(int i = 0; i < n; i++){
            char c = chs[i];
            if(isNumber(c)){    // 情况1
                int num = 0;
                int j = i;
                // 读取连续数字符号
                while(j < n && isNumber(chs[j])){
                    num = 10*num + chs[j++] - '0';    
                }
                nums.push(num);
                i = j - 1;
            }else if (c == '('){    // 情况2
                opts.push(c);
            }else if (c == ')' ){    // 情况3
                while(opts.peek() != '('){
                    cal(nums, opts);
                }
                opts.pop();
            }else{    // 情况4
                while(!opts.isEmpty() && opts.peek()!='(' && map.get(opts.peek()) >= map.get(c)){
                    cal(nums, opts);
                }
                opts.push(c);
            }
        }
        while(!opts.isEmpty()) {    // 计算栈中剩余操作符
            cal(nums, opts);
        }
        return nums.pop();
    }
    
    public static boolean isNumber(Character c){
        return Character.isDigit(c);
    }
    public static void cal(Deque<Integer> nums, Deque<Character> opts){
        int num2 = nums.pop();
        int num1 = nums.pop();
        char opt = opts.pop();
        if(opt == '+'){
            nums.push(num1 + num2);
        }else if(opt == '-'){
            nums.push(num1 - num2);
        }else if(opt == '*'){
            nums.push(num1 * num2);
        }
    }
}




发表于 2022-03-28 15:28:43 回复(2)
A=input().replace('"','') print(eval(A))

发表于 2021-12-19 12:39:50 回复(0)
class Solution:
    def solve(self , s: str) -> int:
        # write code here
        return eval(s)
发表于 2023-03-18 17:02:43 回复(2)
// 第一种方法
function solve( s ){
    let stack = [],i = 0,sign='+',num=0; 
    while(i < s.length){
        if(s[i]=='('){
            let flag= 1, start = i+1;
            while(flag>0){
                i++;
                if(s[i]==')') flag--;
                if(s[i]=='(') flag++;
            }
            num = solve(s.slice(start,i));
            i--;
        }else if(s[i]>='0'&&s[i]<='9'){
            num = num*10 + Number(s[i]);
        }
        if((s[i]<'0'|| s[i]>'9') || i==s.length-1){
            if(sign=='*') stack.push(Number(stack.pop())*num);
            if(sign=='+') stack.push(Number(num));
            if(sign=='-') stack.push(Number(num)*-1);
            if(sign=='/') stack.push(Number(stack.pop())/num);
            sign = s[i];
            num = 0;
        }
        i++;
    }
    return stack.reduce((total,n)=>{return total+n},0);
}
// 第二种
function solve ( s ) {
    return eval(s);
}
// 第三种
function solve ( s ) {
    let func = new Function(`return ${s}`);
    return func();
}

发表于 2021-09-05 14:22:11 回复(6)

递归

from collections import deque


class Solution:
    def solve(self, s):
        s = deque(s)

        def dfs():
            num, sign, stk = 0, '+', []
            while s:
                ch = s.popleft()
                if ch == '(':
                    num = dfs()

                if ch.isdigit():
                    num = num * 10 + int(ch)

                if (not ch.isdigit() and ch != ' ') or not s:
                    if sign == '+':
                        stk.append(num)
                    elif sign == '-':
                        stk.append(-num)
                    elif sign == '*':
                        stk.append(stk.pop() * num)
                    num, sign = 0, ch

                if ch == ')':
                    break

            return sum(stk)

        return dfs()
发表于 2021-05-05 18:15:51 回复(2)
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 返回表达式的值
     * @param s string字符串 待计算的表达式
     * @return int整型
     */
       public int solve(String s)
    {

        // 请写一个整数计算器,支持加减乘三种运算和括号。
        // write code here
        //idea the () could be regarded as a computing element using the recursion method
        Stack<Integer> stack = new Stack<>();
        int number = 0;
        int sum = 0;
        char sign = '+';
        char[] c = s.toCharArray();
        int n = s.length();
        for (int i = 0; i < n; i++)
        {
            char ele = c[i];
            //process the numerical situation
            if (Character.isDigit(ele))
            {
                number = number * 10 + ele - '0';
            }
            //process the () situation
            if (ele == '(')
            {
                int j = i + 1;
                int counterPar = 1;
                String subPar = "";
                //extract the most outer group and recursevely preocess
                while (counterPar > 0)
                {
                    if (c[j] == '(')
                    {
                        counterPar++;
                    }
                    if (c[j] == ')')
                    {
                        counterPar--;
                    }
                    j++;
                }
                subPar = s.substring(i + 1, j);
                number=solve(subPar);
                i = j-1;
            }
            //real work block
            if (ele != ' ' && !Character.isDigit(ele) || i == n - 1)
            {
                if (sign == '+')
                {
                    stack.push(number);
                }
                else if (sign == '-')
                {
                    stack.push(-1 * number);
                }
                else if (sign == '*')
                {
                    stack.push(stack.pop() * number);
                }
                else if (sign == '/')
                {
                    stack.push(stack.pop() / number);
                }
                //change the sign and number
                number = 0;
                sign = ele;
            }

        }
        while (!stack.isEmpty())
        {
            sum+=stack.pop();
        }
        return sum;
    }
}

发表于 2020-10-21 13:39:11 回复(2)
理解起来不难,但实际代码敲逻辑处理非常复杂,很容易出毛病,不是背代码从0开始慢慢写估计得写得调个把钟,结果这只是个中等题
发表于 2021-11-24 00:57:41 回复(1)
用了递归。
#include <string.h>

//返回字符串长度
int sizestr(char* s) {
    int i = 0;
    while (s[i] != '\0')
        i++;
    return i + 1;
}

int solve(char* s) {
    // write code here
    int data[100], sign[100];
    int no = 0, no_s = 0;
    for (int i = 0;s[i] != '\0';i++) {
        if (s[i] == '(')
            data[no++] = solve(s + i + 1);//遇到'('时递归
        if (s[i] == ')') {
            memcpy(s, s + i + 1, sizestr(s + i + 1));//函数退出时,清理已经计算过的表达式,防止重复计算
            break;
        }

        if (s[i] >= '0' && s[i] <= '9') {
            int num = 0;
            while (s[i] >= '0' && s[i] <= '9') {//字符数转int,存入数组
                num = num * 10 + s[i] - '0';
                i++;
            }
            i--;
            data[no++] = num;
        }

        if (s[i] == '*') {//乘法可以先计算,先算后存
            i++;
            if (s[i] >= '0' && s[i] <= '9') {
                int num = 0;
                while (s[i] >= '0' && s[i] <= '9') {
                    num = num * 10 + s[i] - '0';
                    i++;
                }
                i--;
                data[no - 1] *= num;//计算结果覆盖存入
            }
            else if (s[i] == '(')//出现'*('时的情况
                data[no - 1] *= solve(s + i + 1);//同样先计算括号里的
        }
        else if (s[i] == '+') {//加减法,先存再算,此时只要存符号,数字上面存了
            sign[no_s++] = s[i];
        }
        else if (s[i] == '-') {
            sign[no_s++] = s[i];
        }
    }
    for (int i = 0, j = 0;i < no_s;i++) {//计算
        if (sign[i] == '+') {
            data[j + 1] = data[j] + data[j + 1];
            data[j++] = 0;
        }
        else if (sign[i] == '-') {
            data[j + 1] = data[j] - data[j + 1];
            data[j++] = 0;
        }
    }
    return data[no - 1];
}


发表于 2023-07-12 19:24:03 回复(0)
拿C写这东西
char* noBlank(char *s){
    char *p = (char *)malloc(sizeof(char) * (strlen(s)+1));
    strcpy(p, s);
    int len = strlen(s);
    
    for(int i=0; i<len; i++){
        if(*(p+i) == ' '){
            for(int j=i; j<len; j++){
                *(p+j) = *(p+j+1);
            }
            len--;
            i--;
        }
    }
    return p;
}

int solve(char* s ) {
    // write code here
    char *p;
    char *q;
    int t;
    int len = strlen(s);
    int quelen = 10;
    
    p = noBlank(s);
    
    int stackInt[quelen];
    memset(stackInt, 0, sizeof(stackInt));
    char stackChar[quelen];
    memset(stackChar, 0, sizeof(stackChar));
    int lock = 0;
    int up = 0, top = 0;
    
    while(*p != '\0'){
        if(48 <= *p && *p <= 57){    //如果是数字
            stackInt[up] = stackInt[up]*10 + (*p - 48);
            lock = 1;
        }
        else{
            if(stackChar[top-1] != 0){
                if(*p == ')'){
                    t = top;
                    while(stackChar[t-1] != '('){
                        switch (stackChar[t-1]){
                            case '+':
                                stackInt[up-2] = stackInt[up-2] + stackInt[up-1];
                                stackInt[--up] = 0;
                                break;
                            case '-':
                                stackInt[up-2] = stackInt[up-2] - stackInt[up-1];
                                stackInt[--up] = 0;
                                break;
                            case '*':
                                stackInt[up-2] = stackInt[up-2] * stackInt[up-1];
                                stackInt[--up] = 0;
                                break;
                            case '(':
                                break;
                        }
                        t--;
                        top--;
                    }
                    top--;
                }
                else if(*p == '('){
                    stackChar[top++] = *p;
                }
                else{
                    switch (*p){
                        case '*':
                            switch (stackChar[top-1]){
                                case '(':
                                    stackChar[top++] = *p;
                                    break;
                                case '*':
                                    stackInt[up-2] = stackInt[up-2] * stackInt[up-1];
                                    stackInt[--up] = 0;
                                    stackChar[top-1] = *p;
                                    break;
                                case '+':
                                    stackChar[top++] = *p;
                                    break;
                                case '-':
                                    stackChar[top++] = *p;
                                    break;
                            }
                            break;
                        case '+':
                            switch (stackChar[top-1]){
                                case '(':
                                    stackChar[top++] = *p;
                                    break;
                                case '*':
                                    stackInt[up-2] = stackInt[up-2] * stackInt[up-1];
                                    stackInt[--up] = 0;
                                    stackChar[top-1] = *p;
                                    break;
                                case '+':
                                    stackInt[up-2] = stackInt[up-2] + stackInt[up-1];
                                    stackInt[--up] = 0;
                                    stackChar[top-1] = *p;
                                    break;
                                case '-':
                                    stackInt[up-2] = stackInt[up-2] - stackInt[up-1];
                                    stackInt[--up] = 0;
                                    stackChar[top-1] = *p;
                                    break;
                            }
                            break;
                        case '-':
                            switch (stackChar[top-1]){
                                case '(':
                                    stackChar[top++] = *p;
                                    break;
                                case '*':
                                    stackInt[up-2] = stackInt[up-2] * stackInt[up-1];
                                    stackInt[--up] = 0;
                                    stackChar[top-1] = *p;
                                    break;
                                case '+':
                                    stackInt[up-2] = stackInt[up-2] + stackInt[up-1];
                                    stackInt[--up] = 0;
                                    stackChar[top-1] = *p;
                                    break;
                                case '-':
                                    stackInt[up-2] = stackInt[up-2] - stackInt[up-1];
                                    stackInt[--up] = 0;
                                    stackChar[top-1] = *p;
                                    break;
                            }
                            break;
                    }}
            }
            else
                stackChar[top++] = *p;
        }
        if(!(48 <= *(p+1) &&  *(p+1) <= 57) && lock == 1){
            up++;
            lock = 0;
        }
            
        p++;
    }
    while(top != 0){
        switch (stackChar[top-1]){
            case '+':
                stackInt[up-2] = stackInt[up-2] + stackInt[up-1];
                stackInt[--up] = 0;
                break;
            case '-':
                stackInt[up-2] = stackInt[up-2] - stackInt[up-1];
                stackInt[--up] = 0;
                break;
            case '*':
                stackInt[up-2] = stackInt[up-2] * stackInt[up-1];
                stackInt[--up] = 0;
                stackChar[top-1] = *p;
                break;
        }
        top--;
    }
    
    return stackInt[0];
}


发表于 2022-07-29 18:51:38 回复(1)

非常好懂的,有注释喔

 function solve(s) {
  // write code here
  let ops = []; // 用来存储运算符
  let nums = []; // 用来存储数值和每次计算的结果
//   console.log(isNaN(parseInt(s[0])));
  for (let i = 0; i < s.length; i++) {
     if('(*'.indexOf(s[i]) > -1) { // 判断 s[i] 是否为  ( 和 * 
         ops.push(s[i])  // 是就入栈
     } else if(!isNaN(s[i])) { // 判断是否为 一个数字 ->number
         let temp = '' // 临时变量
         while(i<s.length && !isNaN(s[i])) {
             temp = temp + s[i++] // 因为 s 给的是一个字符串 所以通过这个办法 可以把 两位数的数字拼在一起
         }
         i-- // 如果 s[0] 和 s[1] 是一个操作数值12 经过上面的操作拼完了之后 i 会等于2 所以这里等让 i - 1 变回1 指向s[1]
         nums.push(parseInt(temp)) // 随后入栈
     } else if(s[i] == '+' || s[i] == '-') { // 如果是加号 或者 减号
         while(ops.length > 0 && '*+-'.indexOf(ops[ops.length - 1]) > -1) { // 就将 ops数组里
            //的  * + - 等运算符 pop 出去进行操作            
             let num1 = nums.pop()
             let num2 = nums.pop()
             let res = calc(ops.pop(), num1, num2)  // 加减乘 操作函数 在下面
             nums.push(res) // 将得出的结果入栈  ,  如果你有疑问, 为什么最后栈中的就一顶只有结果,没有别的操作数字, 因为
             // 上面 num1 和 num2 赋值的时候 都 pop出去了
         }
         ops.push(s[i]) // 最后将 此次遇到的 + 号丢进栈里
     } else if(s[i] == ')') { // 如果遇到 )
         while(ops.length > 0 && ops[ops.length - 1] != '(') { // 只要栈不空, 和不遇到 (
             // 就一直循环
             let num1 = nums.pop()
             let num2 = nums.pop()
             let res = calc(ops.pop(), num1, num2) // 思想和上面一样
             nums.push(res) // 结果入栈
         }
         ops.pop() // 把左括号丢出去
     }
  }
    while(ops.length > 0) {  // 最后 ops 不空 不停
        let num1=  nums.pop()
        let num2 = nums.pop()
        let temp_res = calc(ops.pop(), num1, num2)
        nums.push(temp_res) // 最后的结果 丢进去
    }
    return nums.pop() // 最后的结果 return 出去
}

function calc(op ,b ,a) {
    if(op == '+') return a + b
    if(op == '-') return a - b
    if(op == '*') return a * b
    return 0
}

module.exports = {
  solve: solve,
};
发表于 2022-08-02 20:41:05 回复(0)
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 返回表达式的值
     * @param s string字符串 待计算的表达式
     * @return int整型
     */
    int solve(string s) {
        // write code here
        string cs;
        for (char &c : s) if (c != ' ') cs += c;
        int n = cs.size();
        stack<int> nums;
        nums.push(0);
        stack<char> ops;
        for (int i = 0; i < n; ++i) {
            char c = cs[i];
            if (c == '(') ops.push(c);
            else if (c == ')') {
                while (!ops.empty()) {
                    if (ops.top() != '(') calc(nums, ops);
                    else {
                        ops.pop();
                        break;
                    }
                }
            } else {
                if (isdigit(c)) {
                    int u = 0, j = i;
                    while (j < n && isdigit(cs[j])) u = u * 10 + (cs[j++] - '0');
                    nums.push(u);
                    i = j - 1;
                } else {
                    if (i > 0 && (cs[i - 1] == '(' || cs[i - 1] == '+' || cs[i - 1] == '-')) {
                        nums.push(0);
                    }
                    while (!ops.empty() && ops.top() != '(') {
                        char prev = ops.top();
                        if (m[prev] >= m[c]) {
                            calc(nums, ops);
                        } else {
                            break;
                        }
                    }
                    ops.push(c);
                }
            }
        }
        while (!ops.empty() && ops.top() != '(') calc(nums, ops);
        return nums.top();
    }
    void calc(stack<int> &nums, stack<char> &ops) {
        if (nums.empty() || nums.size() < 2) return;
        if (ops.empty()) return;
        int b = nums.top();
        nums.pop();
        int a = nums.top();
        nums.pop();
        char op = ops.top();
        ops.pop();
        int ans = 0;
        if (op == '+') ans = a + b;
        else if (op == '-') ans = a - b;
        else if (op == '*') ans = a * b;   
        nums.push(ans);
    }
    
    unordered_map<char, int> m = {{'-', 1}, {'+', 1}, {'*', 2}};
};

发表于 2022-07-22 17:17:26 回复(0)
import java.util.*;
public class Solution {
    public int solve (String s) {
        // 单栈+递归
        char[] arr = s.replaceAll(" ","").toCharArray();
        LinkedList<Integer> stack=new LinkedList<>();
        int num=0;
        char sign='+';
        for(int i=0;i<arr.length;i++){
            char c=arr[i];
            if(Character.isDigit(c)){
                num=num*10+c-'0';
            }
            //遇到括号就截取括号内的字符串,再递归
            if(c=='('){
                int j=i+1;
                int flag=1;
                while(flag>0){
                    if(arr[j]=='(') flag++;
                    if(arr[j]==')') flag--;
                    j++;
                }
                num=solve(s.substring(i+1,j-1));
                i=j-1;
            }
            if(!Character.isDigit(c) || i==arr.length-1){
                //+-直接放,*/栈顶*num(遍历到的数字)再放
                if(sign == '+') stack.push(num);
                else if(sign == '-') stack.push(-1 * num);
                else if(sign == '*') stack.push(stack.pop() * num);
                else if(sign == '/') stack.push(stack.pop() / num);
                num=0;
                sign=c;
            }
        }
        int res=0;
        while(!stack.isEmpty()){
            res+=stack.pop();
        }
        return res;
    }
}

发表于 2022-03-11 23:16:29 回复(0)
23333333333
function solve( s ) {
    // write code here
    return ~~eval(s)
}

发表于 2021-11-15 14:57:56 回复(1)
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 返回表达式的值
     * @param s string字符串 待计算的表达式
     * @return int整型
     */
    int solve(string s) {
        vector<string> nums;
        int len=s.size();
//         int pre=0;
        stack<char> sign;
        unordered_map<char,int> priority={{'(',0},{'+',1},{'-',1},{'*',2},{')',3}};
        for(int i=0;i<len;++i) {
            if(s[i]>='0' && s[i]<='9') {
                int j=i+1;
                while(j<len && s[j]>='0' && s[j]<='9')
                    ++j;
                nums.push_back(s.substr(i,j-i));
                i=j-1;
            } else {
                //运算符
                if(s[i]==')') {
                    while(sign.top()!='(') {
                        //将优先级小于等于当前符号的之前的符号出栈
                        nums.push_back(string(1,sign.top()));
                        sign.pop();
                    }
                    sign.pop();
                } else if(s[i]=='(') {
                    sign.push(s[i]);
                }else {
                    while(!sign.empty() && priority[sign.top()]>=priority[s[i]]) {
                        //将优先级大于等于当前符号的之前的符号出栈
                        nums.push_back(string(1,sign.top()));
                        sign.pop();
                    }
                    sign.push(s[i]);
                }
            }
        }
        while(!sign.empty()) {
            nums.push_back(string(1,sign.top()));
            sign.pop();
        }
        stack<int> res;
        for(string& cur: nums) {
            if(cur[0]>='0' && cur[0]<='9') {
                res.push(atoi(cur.c_str()));
            } else {
                int b=res.top(); res.pop();
                int a=res.top(); res.pop();
                switch(cur[0]) {
                    case '+': res.push(a+b); break;
                    case '-': res.push(a-b); break;
                    case '*': res.push(a*b); break;
                }
            }
        }
        return res.top();
    }
};

发表于 2021-09-14 21:44:29 回复(0)
js一行搞定
function solve( s ) {
    return eval(s);
}


发表于 2021-08-06 13:35:35 回复(2)
先转化为逆波兰式,再进行求值
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 返回表达式的值
     * @param s string字符串 待计算的表达式
     * @return int整型
     */
    int solve(string s) {
		vector<string> tokens = toRPN(s);
		return helper(tokens);
	}
private:
    //运算符优先级
    int priority(string &s)
    {
        if(s == "*")
            return 2;
        if(s == "+" || s == "-")
            return 1;
        if(s == "(")
            return 0;
        return -1;
    }
    
    //转化为逆波兰式
	vector<string> toRPN(string &str)
	{
		int i = 0, n = str.size();
		vector<string> s;
		while (i < n)
		{
			string temp = "";
			if(isdigit(str[i]))
				while (i < n && isdigit(str[i]))
				{
					temp += str[i];
					++i;
				}
			else
				temp += str[i++];
			s.push_back(temp);
		}

		n = s.size();
		stack<string> st;
		vector<string> res;
		
		for (auto &it : s)
		{
			if (isdigit(it[0]))
			{
				res.push_back(it);
			}
				
			else if (st.empty() || it == "(")
				st.push(it);
			else if (it == ")")
			{
				while (!st.empty() && st.top() != "(")
				{
					res.push_back(st.top());
					st.pop();
				}
				st.pop();
			}
			else
			{
				while (priority(it) <= priority(st.top()))
				{
					res.push_back(st.top());
					st.pop();
					if (st.empty())
						break;
				}
				st.push(it);
			}
			
		}
		while (!st.empty())
		{
			res.push_back(st.top());
			st.pop();
		}
		return res;
	}
    
    
    //逆波兰式求值
    int helper(vector<string> &t)
    {
        stack<int> num;
        for(int i = 0;i < t.size();++i)
        {
            if(t[i] == "+" || t[i] == "-" || t[i] == "*")
            {
                int res;
                int n2 = num.top();
                num.pop();
                int n1 = num.top();
                num.pop();
                switch(t[i][0])
                {
                    case '+':
                        res = n1 + n2;
                        break;
                    case '-':
                        res = n1 - n2;
                        break;
                    case '*':
                        res = n1 * n2;
                        break;
                }
                num.push(res);
            }
            else
                num.push(stoi(t[i]));
        }
        return num.top();
    }
};


发表于 2021-07-30 12:35:25 回复(0)
import java.util.*;


public class Solution {
    public int cal(int k2,int k1,char o){
        if(o=='+'){
            return k2+k1;
        }else if(o=='-'){
            return k2-k1;
        }else{
            return k2*k1;
        }
    }
    public int solve (String s) {
        //"(3+4)*(5+(2-3))"
        Stack<Integer> num = new Stack<>();
        Stack<Character> op = new Stack<>();
        int i = 0;
        while(i<s.length()){
            if(s.charAt(i)>='0' && s.charAt(i)<='9'){
                int k = 0;
                while(i<s.length() && s.charAt(i)>='0' && s.charAt(i)<='9'){
                    k = 10*k + (s.charAt(i)-'0');
                    i++;
                }
                num.push(k);
            }else{
                if(s.charAt(i)=='(')
                    op.push(s.charAt(i));
                else if(s.charAt(i)==')'){
                    while(op.peek()!='('){
                        int k1 = num.pop();
                        int k2 = num.pop();
                        char o = op.pop();
                        num.push(cal(k2,k1,o));
                    }
                    op.pop();
                }else if(s.charAt(i)=='*'){ //乘号不影响运算结果,不需要区分前一个运算符是加号还是乘号
                    op.push(s.charAt(i));
                }else{
                    while(num.size()>=2){
                        if(op.peek()=='(')//注意 运算符不能越过小括号
                            break;
                        int k1 = num.pop();
                        int k2 = num.pop();
                        char o = op.pop();
                        num.push(cal(k2,k1,o));
                    }
                    op.push(s.charAt(i));
                }
                i++;
            }
        }
        while(!op.isEmpty()){
            int k1 = num.pop();
            int k2 = num.pop();
            char o = op.pop();
            num.push(cal(k2,k1,o));
        }
        int res = num.pop();
        return res;
    }
}

发表于 2021-07-16 10:29:56 回复(0)
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);
    }
}

发表于 2023-10-13 22:14:55 回复(0)
class Solution {
  public:
    stack<int> num;
    stack<char> op;
    //优先级表
    map<char, int> h{ {'+', 1}, {'-', 1}, {'*', 2}};
    void eval() {
        int a = num.top();
        num.pop();
        int b = num.top();
        num.pop();
        int r = 0;
        if (op.top() == '+')
            r = a + b;
        if (op.top() == '-')
            r = b - a;
        if (op.top() == '*')
            r = a * b;
        op.pop();
        num.push(r);
    }
    int solve(string s) {
        for (int i = 0; i < s.size(); i++) {
            if (isdigit(
                        s[i])) { //数字入栈      isdigit(x)判断x是否是阿拉伯数字1~9
                int x = 0, j = i;//计算数字
                while (j < s.size() && isdigit(s[j])) {
                    x = x * 10 + s[j] - '0';
                    j++;
                }
                num.push(x);//数字入栈
                i = j - 1;
            }
            //左括号无优先级,直接入栈
            else if (s[i] == '(') { //左括号入栈
                op.push(s[i]);
            }
            //括号特殊,遇到左括号直接入栈,遇到右括号计算括号里面的
            else if (s[i] == ')') { //右括号
                while (op.top() != '(') //一直计算到左括号
                    eval();
                op.pop();//左括号出栈
            } else {
                while (op.size() &&
                        h[op.top()] >= h[s[i]])//待入栈运算符优先级低,则先计算
                    eval();
                op.push(s[i]);//操作符入栈
            }
        }
        while (op.size()) eval();//剩余的进行计算
        return num.top();
    }
};

发表于 2023-10-10 16:38:41 回复(0)