227. Basic Calculator II

LeetCode medium оригинал: C# #csharp #leetcode #math #medium #stack #string

Дана строка s, представляющая выражение. Вычислите это выражение и верните его значение.

Целочисленное деление должно округляться к нулю.

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

Примечание: Запрещено использовать какие-либо встроенные функции, которые вычисляют строки как математические выражения, такие как eval().

Пример

Input: s = "3+2*2"

Output: 7

C# решение

сопоставлено/оригинал
public class Solution {
    public int Calculate(string s) {
        int length = s.Length;
        if (length == 0) return 0;
        int currentNumber = 0, lastNumber = 0, result = 0;
        char sign = '+';
        
        for (int i = 0; i < length; i++) {
            char currentChar = s[i];
            if (char.IsDigit(currentChar)) {
                currentNumber = (currentNumber * 10) + (currentChar - '0');
            }
            if (!char.IsDigit(currentChar) && !char.IsWhiteSpace(currentChar) || i == length - 1) {
                if (sign == '+' || sign == '-') {
                    result += lastNumber;
                    lastNumber = (sign == '+') ? currentNumber : -currentNumber;
                } else if (sign == '*') {
                    lastNumber *= currentNumber;
                } else if (sign == '/') {
                    lastNumber /= currentNumber;
                }
                sign = currentChar;
                currentNumber = 0;
            }
        }
        result += lastNumber;
        return result;  
    }
}

C++ решение

auto-draft, проверить перед отправкой
#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:
    public int Calculate(string s) {
        int length = s.size();
        if (length == 0) return 0;
        int currentNumber = 0, lastNumber = 0, result = 0;
        char sign = '+';
        
        for (int i = 0; i < length; i++) {
            char currentChar = s[i];
            if (char.IsDigit(currentChar)) {
                currentNumber = (currentNumber * 10) + (currentChar - '0');
            }
            if (!char.IsDigit(currentChar) && !char.IsWhiteSpace(currentChar) || i == length - 1) {
                if (sign == '+' || sign == '-') {
                    result += lastNumber;
                    lastNumber = (sign == '+') ? currentNumber : -currentNumber;
                } else if (sign == '*') {
                    lastNumber *= currentNumber;
                } else if (sign == '/') {
                    lastNumber /= currentNumber;
                }
                sign = currentChar;
                currentNumber = 0;
            }
        }
        result += lastNumber;
        return result;  
    }
}

Java решение

сопоставлено/оригинал
class Solution {
    public int calculate(String s) {
        int length = s.length();
        if (length == 0) return 0;
        int currentNumber = 0, lastNumber = 0, result = 0;
        char sign = '+';
        
        for (int i = 0; i < length; i++) {
            char currentChar = s.charAt(i);
            if (Character.isDigit(currentChar)) {
                currentNumber = (currentNumber * 10) + (currentChar - '0');
            }
            if (!Character.isDigit(currentChar) && !Character.isWhitespace(currentChar) || i == length - 1) {
                if (sign == '+' || sign == '-') {
                    result += lastNumber;
                    lastNumber = (sign == '+') ? currentNumber : -currentNumber;
                } else if (sign == '*') {
                    lastNumber = lastNumber * currentNumber;
                } else if (sign == '/') {
                    lastNumber = lastNumber / currentNumber;
                }
                sign = currentChar;
                currentNumber = 0;
            }
        }
        result += lastNumber;
        return result;  
    }
}

JavaScript решение

сопоставлено/оригинал
class Solution {
    calculate(s) {
        let length = s.length;
        if (length === 0) return 0;
        let currentNumber = 0, lastNumber = 0, result = 0;
        let sign = '+';
        
        for (let i = 0; i < length; i++) {
            let currentChar = s[i];
            if (!isNaN(currentChar) && currentChar !== ' ') {
                currentNumber = (currentNumber * 10) + parseInt(currentChar);
            }
            if (isNaN(currentChar) && currentChar !== ' ' || i === length - 1) {
                if (sign === '+' || sign === '-') {
                    result += lastNumber;
                    lastNumber = (sign === '+') ? currentNumber : -currentNumber;
                } else if (sign === '*') {
                    lastNumber *= currentNumber;
                } else if (sign === '/') {
                    lastNumber /= currentNumber;
                }
                sign = currentChar;
                currentNumber = 0;
            }
        }
        result += lastNumber;
        return result;
    }
}

Python решение

сопоставлено/оригинал
class Solution:
    def calculate(self, s: str) -> int:
        length = len(s)
        if length == 0:
            return 0
        currentNumber = 0
        lastNumber = 0
        result = 0
        sign = '+'
        
        for i in range(length):
            currentChar = s[i]
            if currentChar.isdigit():
                currentNumber = (currentNumber * 10) + int(currentChar)
            if not currentChar.isdigit() and not currentChar.isspace() or i == length - 1:
                if sign == '+' or sign == '-':
                    result += lastNumber
                    lastNumber = currentNumber if sign == '+' else -currentNumber
                elif sign == '*':
                    lastNumber *= currentNumber
                elif sign == '/':
                    lastNumber //= currentNumber
                sign = currentChar
                currentNumber = 0
        result += lastNumber
        return result

Go решение

сопоставлено/оригинал
package main

import (
    "strconv"
    "unicode"
)

func calculate(s string) int {
    length := len(s)
    if length == 0 {
        return 0
    }
    currentNumber, lastNumber, result := 0, 0, 0
    sign := '+'
    
    for i := 0; i < length; i++ {
        currentChar := rune(s[i])
        if unicode.IsDigit(currentChar) {
            num, _ := strconv.Atoi(string(currentChar))
            currentNumber = (currentNumber * 10) + num
        }
        if !unicode.IsDigit(currentChar) && !unicode.IsSpace(currentChar) || i == length-1 {
            if sign == '+' || sign == '-' {
                result += lastNumber
                lastNumber = currentNumber
                if sign == '-' {
                    lastNumber = -currentNumber
                }
            } else if sign == '*' {
                lastNumber *= currentNumber
            } else if sign == '/' {
                lastNumber /= currentNumber
            }
            sign = currentChar
            currentNumber = 0
        }
    }
    result += lastNumber
    return result
}

Algorithm

Вместо использования стека, используем переменную lastNumber для отслеживания значения последнего вычисленного выражения.

Если операция сложения (+) или вычитания (-), добавляем lastNumber к результату вместо того, чтобы помещать его в стек. Текущее значение currentNumber будет обновлено на lastNumber для следующей итерации.

Если операция умножения (*) или деления (/), вычисляем выражение lastNumber * currentNumber и обновляем lastNumber с результатом выражения. Это значение будет добавлено к результату после сканирования всей строки.

😎

Вакансии для этой задачи

Показаны активные вакансии с пересечением по тегам задачи.

Все вакансии
Активных вакансий пока нет.