772. Basic Calculator III
Реализуйте базовый калькулятор для вычисления простого строкового выражения.
chaîne выражения содержит только неотрицательные целые числа, операторы '+', '-', '*', '/' и открывающие '(' и закрывающие скобки ')'. Целочисленное деление должно округляться к нулю.
Предполагается, что данное выражение всегда корректно. Все промежуточные результаты будут находиться в диапазоне [-2^31, 2^31 - 1].
Примечание: нельзя использовать встроенные функции для вычисления строк как математических выражений, такие как eval().
Exemple:
Input: s = "1+1"
Output: 2
C# solution
correspondant/originalpublic 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++ solution
brouillon automatique, à relire avant soumission#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 solution
correspondant/originalclass 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 solution
correspondant/originalclass 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 solution
correspondant/originalclass 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 solution
correspondant/originalpackage 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 случайный символ, который не будет появляться во Entréeных данных, наExemple "@".
Итерация по Entréeным данным. Для каждого символа c: если c является цифрой, добавьте его к curr. В противном случае, если c == '(', мы начинаем вычисление нового изолированного выражения. В этом случае сохраните previousOperator в стек и установите previousOperator = "+".
Если c является оператором, то необходимо вычислить значение curr. Используйте функцию evaluate, чтобы применить previousOperator к curr, и добавьте результат в стек. Затем сбросьте curr до нуля и обновите previousOperator = c. Если c == ')', это означает, что мы находимся в конце изолированного выражения и должны полностью его вычислить. Извлекайте из стека до тех пор, пока не достигнете оператора, суммируя все извлеченные числа в curr. Как только достигнете оператора, обновите previousOperator = stack.pop(). return сумму всех чисел в стеке.
😎
Vacancies for this task
offres actives with overlapping task tags are affichés.