Когда я увидел название этого закрытого вопроса , я подумал, что это похоже на интересную задачу по коду в гольф. Итак, позвольте мне представить это так:
Вызов:
Написать программу, выражение или подпрограмму , которая, учитывая арифметическое выражение в инфиксной записи , как 1 + 2
, выводит то же выражение в постфикса обозначений , то есть 1 2 +
.
(Примечание: аналогичная проблема была опубликована ранее в январе. Однако я чувствую, что эти две задачи достаточно подробно отличаются друг от друга, чтобы оправдать эту отдельную проблему. Кроме того, я заметил другую ветку только после того, как напечатал все ниже, и я бы предпочел не просто выбросить все это.)
Входные данные:
Ввод состоит из действительного инфиксного арифметического выражения , состоящее из чисел (неотрицательные целые числа представлены в виде последовательностей одного или более десятичных цифр), сбалансированные скобки , чтобы указать , сгруппированный подвыражению, и четыре инфиксных бинарных операторов +
, -
, *
и /
. Любой из них может быть отделен (и все выражение окружено) произвольным количеством пробелов, которые следует игнорировать. 1
Для тех, кто любит формальные грамматики, вот простая BNF-подобная грамматика, которая определяет допустимые входные данные. Для краткости и ясности грамматика не включает необязательные пробелы, которые могут встречаться между любыми двумя токенами (кроме цифр в числе):
expression := number | subexpression | expression operator expression
subexpression := "(" expression ")"
operator := "+" | "-" | "*" | "/"
number := digit | digit number
digit := "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
1 Единственный случай, когда наличие пробелов может повлиять на синтаксический анализ, - это когда они разделяют два последовательных числа; однако, поскольку два числа, не разделенные оператором, не могут присутствовать в действительном выражении инфикса, этот случай никогда не может произойти в допустимом вводе.
Выход:
Вывод должен быть выражением постфикса, эквивалентным вводу. Выражение выход должен состоять только из цифр и операторов, с одним пробелом между каждой парой смежных маркеров, как показано в следующей грамматике (который делает включать пробелы) 2 :
expression := number | expression sp expression sp operator
operator := "+" | "-" | "*" | "/"
number := digit | digit number
digit := "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
sp := " "
2 Опять же, для простоты, number
производство в этой грамматике допускает числа с ведущими нулями, даже если они запрещены в выходных данных правилами ниже.
Приоритет оператора:
При отсутствии скобок применяются следующие правила приоритета:
- Операторы
*
и/
имеют более высокий приоритет, чем+
и-
. - Операторы
*
и/
имеют равный приоритет друг перед другом. - Операторы
+
и-
имеют равный приоритет друг перед другом. - Все операторы левоассоциативны.
Например, следующие два выражения эквивалентны:
1 + 2 / 3 * 4 - 5 + 6 * 7
((1 + ((2 / 3) * 4)) - 5) + (6 * 7)
и они оба должны дать следующий результат:
1 2 3 / 4 * + 5 - 6 7 * +
(Это те же правила приоритета, что и в языке Си, и в большинстве языков, производных от него. Они, вероятно, напоминают правила, которым вас учили в начальной школе, за исключением, возможно, относительного приоритета *
и /
.)
Разные правила:
Если данное решение является выражением или подпрограммой, входные данные должны быть предоставлены, а выходные данные возвращены в виде одной строки. Если решение представляет собой законченную программу, оно должно прочитать строку, содержащую инфиксное выражение из стандартного ввода, и распечатать строку, содержащую постфиксную версию, в стандартный вывод.
Числа на входе могут включать начальные нули. Числа в выходных данных не должны иметь начальных нулей (за исключением числа 0, которое должно выводиться как
0
).Вы не должны оценивать или оптимизировать выражение каким-либо образом. В частности, не следует предполагать, что операторы обязательно удовлетворяют любым ассоциативным, коммутативным или другим алгебраическим тождествам. То есть вы не должны предполагать, что, например,
1 + 2
равно2 + 1
или что1 + (2 + 3)
равно(1 + 2) + 3
.Можно предположить, что числа на входе не превышают 2 31 - 1 = 2147483647.
Эти правила предназначены для того, чтобы гарантировать, что правильный вывод однозначно определяется входными данными.
Примеры:
Вот некоторые допустимые входные выражения и соответствующие выходные данные, представленные в форме "input" -> "output"
:
"1" -> "1"
"1 + 2" -> "1 2 +"
" 001 + 02 " -> "1 2 +"
"(((((1))) + (2)))" -> "1 2 +"
"1+2" -> "1 2 +"
"1 + 2 + 3" -> "1 2 + 3 +"
"1 + (2 + 3)" -> "1 2 3 + +"
"1 + 2 * 3" -> "1 2 3 * +"
"1 / 2 * 3" -> "1 2 / 3 *"
"0102 + 0000" -> "102 0 +"
"0-1+(2-3)*4-5*(6-(7+8)/9+10)" -> "0 1 - 2 3 - 4 * + 5 6 7 8 + 9 / - 10 + * -"
(По крайней мере, я надеюсь, что все это правильно; я сделал преобразование вручную, так что ошибки могли закрасться.)
Просто чтобы быть понятным, следующие входные данные являются недействительными; не имеет значения, что делает ваше решение, если оно ему дано (хотя, конечно, например, возвращение сообщения об ошибке лучше, чем, скажем, потребление бесконечного количества памяти):
""
"x"
"1 2"
"1 + + 2"
"-1"
"3.141592653589793"
"10,000,000,001"
"(1 + 2"
"(1 + 2)) * (3 / (4)"
1 2 3 4 + *
?
1 2 3 4 +
означает «1 + 2 + 3 + 4».