772. Basic Calculator III

LeetCode medium original: C# #csharp #hash-table #leetcode #math #medium #stack #string
Văn bản bài toán được dịch từ tiếng Nga theo ngôn ngữ giao diện. Mã không thay đổi.

Реализуйте базовый калькулятор для вычисления простого строкового выражения.

chuỗi выражения содержит только неотрицательные целые числа, операторы '+', '-', '*', '/' и открывающие '(' и закрывающие скобки ')'. Целочисленное деление должно округляться к нулю.

Предполагается, что данное выражение всегда корректно. Все промежуточные результаты будут находиться в диапазоне [-2^31, 2^31 - 1].

Примечание: нельзя использовать встроенные функции для вычисления строк как математических выражений, такие как eval().

Ví dụ:

Input: s = "1+1"

Output: 2

C# lời giải

đã khớp/gốc
public class Solution {
    private string Evaluate(char operator, string first, string second) {
        int x = int.Parse(first);
        int y = int.Parse(second);
        int res = 0;
        
        if (operator == '+') {
            res = x;
        } else if (operator == '-') {
            res = -x;
        } else if (operator == '*') {
            res = x * y;
        } else {
            res = x / y;
        }
        
        return res.ToString();
    }
    
    public int Calculate(string s) {
        Stack<string> stack = new Stack<string>();
        string curr = "";
        char previousOperator = '+';
        s += "@";
        HashSet<string> operators = new HashSet<string>(new string[] {"+", "-", "*", "/"});
        
        foreach (char c in s) {
            if (char.IsDigit(c)) {
                curr += c;
            } else if (c == '(') {
                stack.Push(previousOperator.ToString());
                previousOperator = '+';
            } else {
                if (previousOperator == '*' || previousOperator == '/') {
                    stack.Push(Evaluate(previousOperator, stack.Pop(), curr));
                } else {
                    stack.Push(Evaluate(previousOperator, curr, "0"));
                }
                
                curr = "";
                previousOperator = c;
                if (c == ')') {
                    int currentTerm = 0;
                    while (!operators.Contains(stack.Peek())) {
                        currentTerm += int.Parse(stack.Pop());
                    }
                    
                    curr = currentTerm.ToString();
                    previousOperator = stack.Pop()[0];
                }
            }
        }
        
        int ans = 0;
        foreach (string num in stack) {
            ans += int.Parse(num);
        }
        return ans;
    }
}

C++ lời giải

bản nháp tự động, xem lại trước khi gửi
#include <bits/stdc++.h>
using namespace std;

// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
class Solution {
public:
    private string Evaluate(char operator, string first, string second) {
        int x = int.Parse(first);
        int y = int.Parse(second);
        int res = 0;
        
        if (operator == '+') {
            res = x;
        } else if (operator == '-') {
            res = -x;
        } else if (operator == '*') {
            res = x * y;
        } else {
            res = x / y;
        }
        
        return res.ToString();
    }
    
    public int Calculate(string s) {
        stack<string> stack = new stack<string>();
        string curr = "";
        char previousOperator = '+';
        s += "@";
        HashSet<string> operators = new HashSet<string>(new string[] {"+", "-", "*", "/"});
        
        foreach (char c in s) {
            if (char.IsDigit(c)) {
                curr += c;
            } else if (c == '(') {
                stack.push(previousOperator.ToString());
                previousOperator = '+';
            } else {
                if (previousOperator == '*' || previousOperator == '/') {
                    stack.push(Evaluate(previousOperator, stack.pop(), curr));
                } else {
                    stack.push(Evaluate(previousOperator, curr, "0"));
                }
                
                curr = "";
                previousOperator = c;
                if (c == ')') {
                    int currentTerm = 0;
                    while (!operators.Contains(stack.Peek())) {
                        currentTerm += int.Parse(stack.pop());
                    }
                    
                    curr = currentTerm.ToString();
                    previousOperator = stack.pop()[0];
                }
            }
        }
        
        int ans = 0;
        foreach (string num in stack) {
            ans += int.Parse(num);
        }
        return ans;
    }
}

Java lời giải

đã khớp/gốc
class Solution {
    private String evaluate(char operator, String first, String second) {
        int x = Integer.parseInt(first);
        int y = Integer.parseInt(second);
        int res = 0;
        
        if (operator == '+') {
            res = x;
        } else if (operator == '-') {
            res = -x;
        } else if (operator == '*') {
            res = x * y;
        } else {
            res = x / y;
        }
        
        return Integer.toString(res);
    }
    
    public int calculate(String s) {
        Stack<String> stack = new Stack<>();
        String curr = "";
        char previousOperator = '+';
        s += "@";
        Set<String> operators = new HashSet<>(Arrays.asList("+", "-", "*", "/"));
        
        for (char c: s.toCharArray()) {
            if (Character.isDigit(c)) {
                curr += c;
            } else if (c == '(') {
                stack.push("" + previousOperator);
                previousOperator = '+';
            } else {
                if (previousOperator == '*' || previousOperator == '/') {
                    stack.push(evaluate(previousOperator, stack.pop(), curr));
                } else {
                    stack.push(evaluate(previousOperator, curr, "0"));
                }
                
                curr = "";
                previousOperator = c;
                if (c == ')') {
                    int currentTerm = 0;
                    while (!operators.contains(stack.peek())) {
                        currentTerm += Integer.parseInt(stack.pop());
                    }
                    
                    curr = Integer.toString(currentTerm);
                    previousOperator = stack.pop().charAt(0);
                }
            }
        }
        
        int ans = 0;
        for (String num: stack) {
            ans += Integer.parseInt(num);
        }

        return ans;
    }
}

JavaScript lời giải

đã khớp/gốc
class Solution {
    evaluate(operator, first, second) {
        const x = parseInt(first)
        const y = parseInt(second)
        let res = 0

        if (operator === '+') {
            res = x
        } else if (operator === '-') {
            res = -x
        } else if (operator === '*') {
            res = x * y
        } else {
            res = Math.trunc(x / y)
        }

        return res.toString()
    }

    calculate(s) {
        const stack = []
        let curr = ""
        let previousOperator = '+'
        s += "@"
        const operators = new Set(["+", "-", "*", "/"])

        for (const c of s) {
            if (/\d/.test(c)) {
                curr += c
            } else if (c === '(') {
                stack.push(previousOperator)
                previousOperator = '+'
            } else {
                if (previousOperator === '*' || previousOperator === '/') {
                    stack.push(this.evaluate(previousOperator, stack.pop(), curr))
                } else {
                    stack.push(this.evaluate(previousOperator, curr, "0"))
                }

                curr = ""
                previousOperator = c
                if (c === ')') {
                    let currentTerm = 0
                    while (!operators.has(stack[stack.length - 1])) {
                        currentTerm += parseInt(stack.pop())
                    }

                    curr = currentTerm.toString()
                    previousOperator = stack.pop()
                }
            }
        }

        let ans = 0
        for (const num of stack) {
            ans += parseInt(num)
        }

        return ans
    }
}

Python lời giải

đã khớp/gốc
class Solution:
    def evaluate(self, operator, first, second):
        x = int(first)
        y = int(second)
        if operator == '+':
            return str(x)
        elif operator == '-':
            return str(-x)
        elif operator == '*':
            return str(x * y)
        else:
            return str(x // y)

    def calculate(self, s: str) -> int:
        stack = []
        curr = ""
        previousOperator = '+'
        s += "@"
        operators = set("+-*/")
        
        for c in s:
            if c.isdigit():
                curr += c
            elif c == '(':
                stack.append(previousOperator)
                previousOperator = '+'
            else:
                if previousOperator in "*/":
                    stack.append(self.evaluate(previousOperator, stack.pop(), curr))
                else:
                    stack.append(self.evaluate(previousOperator, curr, "0"))
                
                curr = ""
                previousOperator = c
                if c == ')':
                    currentTerm = 0
                    while stack[-1] not in operators:
                        currentTerm += int(stack.pop())
                    curr = str(currentTerm)
                    previousOperator = stack.pop()
        
        return sum(int(num) for num in stack)

Go lời giải

đã khớp/gốc
package main

import (
    "strconv"
)

type Solution struct{}

func (sol *Solution) evaluate(operator byte, first, second string) string {
    x, _ := strconv.Atoi(first)
    y, _ := strconv.Atoi(second)
    res := 0

    if operator == '+' {
        res = x
    } else if operator == '-' {
        res = -x
    } else if operator == '*' {
        res = x * y
    } else {
        res = x / y
    }

    return strconv.Itoa(res)
}

func (sol *Solution) calculate(s string) int {
    stack := []string{}
    curr := ""
    previousOperator := byte('+')
    s += "@"
    operators := map[string]struct{}{"+": {}, "-": {}, "*": {}, "/": {}}

    for i := 0; i < len(s); i++ {
        c := s[i]
        if c >= '0' && c <= '9' {
            curr += string(c)
        } else if c == '(' {
            stack = append(stack, string(previousOperator))
            previousOperator = '+'
        } else {
            if previousOperator == '*' || previousOperator == '/' {
                top := stack[len(stack)-1]
                stack = stack[:len(stack)-1]
                stack = append(stack, sol.evaluate(previousOperator, top, curr))
            } else {
                stack = append(stack, sol.evaluate(previousOperator, curr, "0"))
            }

            curr = ""
            previousOperator = c
            if c == ')' {
                currentTerm := 0
                for len(stack) > 0 {
                    top := stack[len(stack)-1]
                    if _, ok := operators[top]; ok {
                        break
                    }
                    stack = stack[:len(stack)-1]
                    val, _ := strconv.Atoi(top)
                    currentTerm += val
                }
                curr = strconv.Itoa(currentTerm)
                previousOperator = stack[len(stack)-1][0]
                stack = stack[:len(stack)-1]
            }
        }
    }

    ans := 0
    for _, num := range stack {
        val, _ := strconv.Atoi(num)
        ans += val
    }

    return ans
}

func main() {}

Algorithm

Определите вспомогательную функцию evaluate, которая принимает оператор и numberвые аргументы. Заметьте, что эта функция идентична той, что представлена в подходе "Basic Calculator II". Инициализируйте несколько переменных: стек для хранения промежуточных результатов, curr для отслеживания текущего числа, которое мы строим, и previousOperator для отслеживания предыдущего оператора. Добавьте в строку s случайный символ, который не будет появляться во Đầu vàoных данных, наVí dụ "@".

Итерация по Đầu vàoным данным. Для каждого символа c: если c является цифрой, добавьте его к curr. В противном случае, если c == '(', мы начинаем вычисление нового изолированного выражения. В этом случае сохраните previousOperator в стек и установите previousOperator = "+".

Если c является оператором, то необходимо вычислить значение curr. Используйте функцию evaluate, чтобы применить previousOperator к curr, и добавьте результат в стек. Затем сбросьте curr до нуля и обновите previousOperator = c. Если c == ')', это означает, что мы находимся в конце изолированного выражения и должны полностью его вычислить. Извлекайте из стека до тех пор, пока не достигнете оператора, суммируя все извлеченные числа в curr. Как только достигнете оператора, обновите previousOperator = stack.pop(). return сумму всех чисел в стеке.

😎

Vacancies for this task

việc làm đang hoạt động with overlapping task tags are đã hiển thị.

Tất cả việc làm
Chưa có việc làm đang hoạt động.