Я некоторое время борется с этой проблемой, я пытаюсь реализовать программу java-калькулятора, которая будет оценивать математические выражения с консоли. Трудность заключается в том, что эта программа также должна принимать пользовательские переменные из консоли с ключевым словом: "define", а затем также оценивать их.
Например, пользовательский тип
"(определите я = 3) + 4 * 2"
в консоль программа распознает ключевое слово "define" и оценивает выражение как
3 + 4 * 2 = 11.
Основная проблема заключается в том, что я не знаю, как подойти к этой проблеме, поскольку иерархия может стать очень сложной, особенно если у вас есть что-то вроде этого:
"(определите я = (определите j = (define k = 5) +7) + 3) -k".
В этом случае k = 5, j = k +7 = 12, я = j + 3 = 15, поэтому result = я -k = 10 (калькулятор возвращает это значение).
Вы также можете определить/переопределить одну и ту же переменную в одном выражении, например:
(определите я = (определите я = 1) +1) - (определите я = 1)
Здесь я сначала будет = 1, тогда я = я + 1 = 2, тогда я будет переопределено до 1, поэтому все выражение оценивается как 1 +1 -1 = 1.
Любые несбалансированные круглые скобки, переменные без оператора define будут распознаваться как ошибка.
Мой подход:
Сначала преобразуйте выражение в регулярное математическое выражение, то есть, заменив все определяемые пользователем переменные соответствующими значениями, затем оцените все выражение. Но даже это трудно, если у вас есть определение гнезда. Чтобы завершить этот "процесс замены", я пробовал следующее:
Шаг 1. Используйте regex для соответствия выражению типа "let [a-zA-z] + = [0-9] +", который соответствует "переменной, которая имеет фактическое значение вместо ссылки", поэтому, если у меня есть "(определите я = (определите j = (define k = 5) +7) + 3) -k", моя программа попытается найти "k = 5".
Шаг 2. Затем сохраните k = 5 в hashmap, затем замените все "k" на значение 5, поэтому выражение теперь будет выглядеть как "(define я = (define j = (5) +7) + 3) -5". Таким образом, рекурсивно, я надеюсь избавиться от всех букв, чтобы выражение могло быть оценено.
Как вы можете сказать, мой подход не работает, когда пользователь переопределяет определенную переменную и не проверяет наличие каких-либо несбалансированных круглых скобок.
Поэтому мне интересно, действительно ли мой подход является жизнеспособным или есть лучший способ? Любая помощь будет принята с благодарностью.
Поскольку проблема довольно сложная, подход, который я предлагаю, заключается в том, чтобы сначала обрабатывать скобки. Фактически, цель состоит в том, чтобы обрабатывать информацию в согласованном порядке. В начальной школе мы узнали о PEMDAS (круглые скобки, показатели, умножение/деление, сложение/вычитание).
Вы добавили новый (унарный) оператор, называемый define. Начиная с его кода, вы должны выбрать его важность в рамках операции heirarchy. Возможно, это всегда в скобках? Кроме того, обратите внимание, что вы также придаете значение слева и справа.
В любом случае было бы проще разобрать математическое выражение, если бы каждый оператор был двоичным. Таким образом, вы можете подделать его.
Сначала проанализируйте выражение в массиве. Например, выражение
(define i = (define j = ( define k = 5) + 7) + 3) -k
станет
[ ( , 0 , define i, (, 0, define j, (, 0, define k, 5, ), +, 7, ), -, k ]
Затем вы пройдете и оцените.
Подумайте о том, чтобы выполнить эту актуальную проблему у LeetCode Online Judge: https://oj.leetcode.com/problems/evaluate-reverse-polish-notation/