Алгоритм преобразования инфикса в постфикс с помощью Python

Я пытаюсь написать на Python следующий алгоритм (представленный на обычном английском языке) для преобразования простых математических выражений из инфиксной формы в постфиксную форму:

Create a new empty list, 'operators'
Create a new empty list 'postfix'

For each token in the infix expression
  If the token is an integer then
    Append the token to 'postfix'
  If the token is an operator then
    While 'operators' is not empty and the last item in 'operators' is not an open parenthesis
    and precedence(token) < precedence(last item in 'operators') do
        Remove the last item from 'operators' and append it to 'postfix'
      Append the token to 'operators'
  If the token is an open parenthesis then
    Append the token to 'operators'
  If the token is a close parenthesis then
    While the last item in 'operators' is not an open parenthesis do
        Remove the last item from 'operators' and append it to 'postfix'
      Remove the open parenthesis from 'operators'

While 'operators' is not the empty list do
  Remove the last item from 'operators' and append it to 'postfix'

Return 'postfix' as the result of the algorithm

Однако меня немного озадачивает строка «Удалить открывающую скобку из operators». Я видел случаи, когда в operators одновременно было более одной открывающей скобки. В каком случае какой из них следует удалить?

@KarlKnechtel "вы не объяснили, какую проблему предполагается решить с помощью кода" - А? Вы не видели название? Там написано "преобразование инфикса в постфикс". А еще в тексте написано «преобразование простых математических выражений из инфиксной формы в постфиксную».

no comment 22.03.2024 20:40

NB. Это алгоритм сортировочной станции Дейкстры. Поищи это.

user207421 22.03.2024 22:52

@user207421 user207421 Пожалуйста, исправьте сломанный отступ.

no comment 24.03.2024 07:35
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
3
122
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Разумеется, тот, который вы только что нашли. Не забывайте контекст:

    **While** the last item in *operators* is not an open parenthesis **do**
        Remove the last item from *operators* and append it to *postfix*
      Remove the open parenthesis from *operators*

Цикл while удаляет элементы до тех пор, пока последний элемент в операторах не станет открывающей скобкой, а затем вы удалите ее.

Я хотел увидеть алгоритм в менее многословном и более удобном для чтения формате, поэтому я просто написал упрощенную версию Python.

for infix in '3+4*5', '(3+4)*5':

    precedence = '+-*/'.index
    operators = []
    postfix = []
    for token in infix:
        if token.isdigit():
            postfix.append(token)
        if token in '+-*/':
            while operators and operators[-1] != '(' and precedence(token) < precedence(operators[-1]):
                postfix.append(operators.pop())
            operators.append(token)
        if token == '(':
            operators.append(token)
        if token == ')':
            while operators[-1] != '(':
                postfix.append(operators.pop())
            operators.pop()
    while operators:
        postfix.append(operators.pop())

    print(*postfix)

Попробуйте это онлайн!):

3 4 5 * +
3 4 + 5 *
Ответ принят как подходящий

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

    **While** the last item in *operators* is not an open parenthesis **do**
        Remove the last item from *operators* and append it to *postfix*
     Remove the open parenthesis from *operators*

В начале третьей строки не должно быть лишнего пробела. Вместо этого должно быть так:

    While the last item in *operators* is not an open parenthesis do
        Remove the last item from *operators* and append it to *postfix*
    Remove the open parenthesis from *operators*

Поскольку инструкция Remove идет сразу после окончания цикла While, а условие цикла While — «последний элемент в операторах не является открывающей скобкой», это означает, что когда цикл While заканчивается, последний элемент в операторах должен быть открывающей скобкой.

Это единственная открывающая скобка, которую вы можете увидеть и удалить на данном этапе.

Важно отметить, что операторы представляют собой стек, также называемый структурой «последним пришел — первым вышел»: вы можете видеть, получать доступ и удалять только его последний (или «верхний») элемент. Итак, эта открывающая скобка — единственная, которую вы можете видеть на данный момент, и единственная, которую вы можете удалить.

Обратите внимание, что эти три строки кода работают корректно только в том случае, если в инфиксном выражении правильно сопоставляются круглые скобки. Если вы запустите этот алгоритм точно так, как написано для выражения типа 3+4), которое содержит несовпадающую закрывающую скобку, цикл While «Пока последний элемент не является открывающей скобкой, удалите последний элемент» удалит все элементы, и тогда стек будет пусто, и программа выйдет из строя, поскольку вы попытаетесь удалить элемент из пустого стека.

Другие вопросы по теме