150. Evaluate Reverse Polish Notation

Вам дан массив строк под названием tokens, который представляет арифметическое выражение в обратной польской нотации.

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

Обратите внимание на следующие моменты:

Допустимые операторы: '+', '-', '*' и '/'.

Каждый операнд может быть целым числом или другим выражением.

Деление двух целых чисел всегда округляется к нулю.

Деление на ноль в выражении отсутствует.

Входные данные представляют собой действительное арифметическое выражение в обратной польской нотации.

Ответ и все промежуточные вычисления можно представить 32-битным целым числом.

Пример:

Input: tokens = ["2","1","+","3","*"]

Output: 9

Explanation: ((2 + 1) * 3) = 9

C# решение

сопоставлено/оригинал
public class Solution {
    private static Dictionary<string, Func<int, int, int>> OPERATIONS =
        new Dictionary<string, Func<int, int, int>>() {
            { "+", (int a, int b) => a + b },
            { "-", (int a, int b) => a - b },
            { "*", (int a, int b) => a * b },
            { "/", (int a, int b) => a / b }
        };
    public int EvalRPN(string[] tokens) {
        int currentPosition = 0;
        while (tokens.Length > 1) {
            while (!OPERATIONS.ContainsKey(tokens[currentPosition])) {
                currentPosition++;
            }
            string operation = tokens[currentPosition];
            int number1 = Int32.Parse(tokens[currentPosition - 2]);
            int number2 = Int32.Parse(tokens[currentPosition - 1]);
            Func<int, int, int> func = OPERATIONS[operation];
            int value = func(number1, number2);
            tokens[currentPosition] = value.ToString();
            List<string> tokenslist = tokens.ToList();
            tokenslist.RemoveRange(currentPosition - 2, 2);
            tokens = tokenslist.ToArray();
            currentPosition--;
        }
        return Int32.Parse(tokens[0]);
    }
}

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:
    private static unordered_map<string, Func<int, int, int>> OPERATIONS =
        new unordered_map<string, Func<int, int, int>>() {
            { "+", (int a, int b) => a + b },
            { "-", (int a, int b) => a - b },
            { "*", (int a, int b) => a * b },
            { "/", (int a, int b) => a / b }
        };
    public int EvalRPN(vector<string> tokens) {
        int currentPosition = 0;
        while (tokens.size() > 1) {
            while (!OPERATIONS.count(tokens[currentPosition])) {
                currentPosition++;
            }
            string operation = tokens[currentPosition];
            int number1 = Int32.Parse(tokens[currentPosition - 2]);
            int number2 = Int32.Parse(tokens[currentPosition - 1]);
            Func<int, int, int> func = OPERATIONS[operation];
            int value = func(number1, number2);
            tokens[currentPosition] = value.ToString();
            List<string> tokenslist = tokens.ToList();
            tokenslist.RemoveRange(currentPosition - 2, 2);
            tokens = tokenslist.ToArray();
            currentPosition--;
        }
        return Int32.Parse(tokens[0]);
    }
}

Java решение

сопоставлено/оригинал
class Solution {
    private static final Map<
        String,
        BiFunction<Integer, Integer, Integer>
    > OPERATIONS = new HashMap<>();

    static {
        OPERATIONS.put("+", (a, b) -> a + b);
        OPERATIONS.put("-", (a, b) -> a - b);
        OPERATIONS.put("*", (a, b) -> a * b);
        OPERATIONS.put("/", (a, b) -> a / b);
    }

    public int evalRPN(String[] tokens) {
        int currentPosition = 0;
        int length = tokens.length; // We need to keep track of this ourselves.

        while (length > 1) {

            while (!OPERATIONS.containsKey(tokens[currentPosition])) {
                currentPosition++;
            }

            String operation = tokens[currentPosition];
            int number1 = Integer.parseInt(tokens[currentPosition - 2]);
            int number2 = Integer.parseInt(tokens[currentPosition - 1]);

            BiFunction<Integer, Integer, Integer> operator = OPERATIONS.get(
                operation
            );
            int value = operator.apply(number1, number2);
            tokens[currentPosition] = Integer.toString(value);

            delete2AtIndex(tokens, currentPosition - 2, length);
            currentPosition--;
            length -= 2;
        }

        return Integer.parseInt(tokens[0]);
    }

    private void delete2AtIndex(String[] tokens, int d, int length) {
        for (int i = d; i < length - 2; i++) {
            tokens[i] = tokens[i + 2];
        }
    }
}

JavaScript решение

сопоставлено/оригинал
const OPERATORS = {
    "+": (a, b) => a + b,
    "-": (a, b) => a - b,
    "/": (a, b) => Math.trunc(a / b),
    "*": (a, b) => a * b,
};

var evalRPN = function (tokens) {
    let currentPosition = 0;

    while (tokens.length > 1) {

        while (!(tokens[currentPosition] in OPERATORS)) {
            currentPosition += 1;
        }

        const operator = tokens[currentPosition];
        const operation = OPERATORS[operator];
        const number1 = Number(tokens[currentPosition - 2]);
        const number2 = Number(tokens[currentPosition - 1]);

        tokens[currentPosition] = operation(number1, number2);

        tokens.splice(currentPosition - 2, 2);
        currentPosition -= 1;
    }

    return tokens[0];
};

Python решение

сопоставлено/оригинал
class Solution:
    def evalRPN(self, tokens: List[str]) -> int:
        operations = {
            "+": lambda a, b: a + b,
            "-": lambda a, b: a - b,
            "/": lambda a, b: int(a / b),
            "*": lambda a, b: a * b,
        }

        current_position = 0

        while len(tokens) > 1:
            while tokens[current_position] not in "+-*/":
                current_position += 1

            operator = tokens[current_position]
            number_1 = int(tokens[current_position - 2])
            number_2 = int(tokens[current_position - 1])

            operation = operations[operator]
            tokens[current_position] = operation(number_1, number_2)

            tokens.pop(current_position - 2)
            tokens.pop(current_position - 2)
            current_position -= 1

        return int(tokens[0])

Go решение

сопоставлено/оригинал
func evalRPN(tokens []string) int {
    OPERATIONS := map[string]func(int, int) int{
        "+": func(a, b int) int { return a + b },
        "-": func(a, b int) int { return a - b },
        "*": func(a, b int) int { return a * b },
        "/": func(a, b int) int { return a / b },
    }
    currentPosition := 0
    for len(tokens) > 1 {
        for _, exist := OPERATIONS[strings.TrimSpace(tokens[currentPosition])]; !exist; {
            currentPosition += 1
            _, exist = OPERATIONS[strings.TrimSpace(tokens[currentPosition])]
        }
        operator := strings.TrimSpace(tokens[currentPosition])
        operation, _ := OPERATIONS[operator]
        number1, _ := strconv.Atoi(tokens[currentPosition-2])
        number2, _ := strconv.Atoi(tokens[currentPosition-1])
        tokens[currentPosition] = fmt.Sprintf("%d", operation(number1, number2))
        tokens = append(tokens[:currentPosition-2], tokens[currentPosition:]...)
        currentPosition -= 1
    }
    result, _ := strconv.Atoi(tokens[0])
    return result
}

Algorithm

1️⃣

Обработка входных массивов:

Для языков, таких как Java, где входные данные представлены фиксированным массивом, необходимо определить собственные методы для манипулирования массивом (например, удаление элементов). Это может включать сдвиг элементов для заполнения пробелов после удаления элемента. В качестве альтернативы, копирование массива в ArrayList могло бы упростить удаление, но за счет увеличения сложности по памяти с O(1) до O(n).

2️⃣

Обработка типов и деление в Python:

Необходимо быть внимательным при обработке типов в Python во время обработки списка, поскольку числа могут быть представлены как строки или целые числа. Кроме того, стандартное деление в Python не округляет к нулю. Вместо этого использование int(a / b) достигает желаемого результата округления, что отличается от деления нацело int(a // b), которое является другим распространенным подходом.

.

3️⃣

Использование лямбда-функций:

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

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

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