Алгоритм сортировочной станции

Алгоритм преобразования синтаксиса с инфиксной нотацией в постфиксную
Алгоритм сортировочной станции
СортРазбор
Структура данныхКуча
Худший вариант производительности О ( н ) {\displaystyle O(n)}
Наихудшая сложность пространства О ( н ) {\displaystyle O(n)}

В информатике алгоритм сортировочной станции — это метод разбора арифметических или логических выражений или их комбинации, указанных в инфиксной нотации . Он может создавать либо строку постфиксной нотации, также известную как обратная польская нотация ( RPN), либо абстрактное синтаксическое дерево (AST). [1] Алгоритм был изобретен Эдсгером Дейкстрой , впервые опубликован в ноябре 1961 года [2] и назван алгоритмом «сортировочной станции», поскольку его работа напоминает работу сортировочной станции на железной дороге .

Как и оценка RPN, алгоритм сортировочной станции основан на стеке . Инфиксные выражения — это форма математической записи, к которой привыкло большинство людей, например, «3 + 4» или «3 + 4 × (2 − 1)» . Для преобразования есть две текстовые переменные ( строки ), входная и выходная. Также есть стек , который хранит операторы, еще не добавленные в выходную очередь. Для преобразования программа считывает каждый символ по порядку и делает что-то на основе этого символа. Результатом для приведенных выше примеров будет (в обратной польской нотации ) «3 4 +» и «3 4 2 1 − × +» соответственно.

Алгоритм сортировочной станции правильно проанализирует все допустимые инфиксные выражения, но не отклонит все недопустимые выражения. Например, "1 2 +" не является допустимым инфиксным выражением, но будет проанализировано как "1 + 2" . Однако алгоритм может отклонить выражения с непарными скобками.

Алгоритм сортировочной станции позднее был обобщен до анализа приоритета операторов .

Простое преобразование

  1. Вход: 3 + 4
  2. Поместить 3 в очередь вывода (всякий раз, когда число считывается, оно помещается в очередь вывода)
  3. Вставьте + (или его идентификатор) в стек операторов.
  4. Поместить 4 в очередь вывода
  5. После прочтения выражения извлеките операторы из стека и добавьте их к выводу.
    В данном случае есть только один знак «+».
  6. Выход: 3 4 +

Это уже демонстрирует несколько правил:

  • Все числа при считывании выводятся на выход.
  • В конце чтения выражения извлеките все операторы из стека и поместите их на выход.

Графическая иллюстрация

Графическая иллюстрация алгоритма с использованием трехстороннего железнодорожного узла . Входные данные обрабатываются по одному символу за раз: если найдена переменная или число, они копируются непосредственно на выход a), c), e), h). Если символ является оператором, он помещается в стек операторов b), d), f). Если приоритет оператора ниже, чем у операторов наверху стека, или приоритеты равны, и оператор слева ассоциативен, то этот оператор извлекается из стека и добавляется к выходу g). Наконец, все оставшиеся операторы извлекаются из стека и добавляются к выходу i).

Алгоритм в деталях

/* Функции, упомянутые в этом алгоритме, являются простыми функциями с одним аргументом, такими как синус, обратная функция или факториал. */ /* Эта реализация не реализует составные функции, функции с переменным числом аргументов или унарные операторы. */в то время как есть жетоны, которые нужно прочитать: прочитать токен если токен: - число : поместить его в очередь вывода - функция : поместить его в стек оператора - оператор  o 1 : while (наверху стека операторов находится оператор o 2 , который не является левой скобкой, и ( o 2 имеет больший приоритет, чем o 1  или ( o 1 и o 2 имеют одинаковый приоритет , а  o 1 является левоассоциативным)) ): вытолкнуть o 2 из стека операторов в выходную очередь вставьте o 1 в стек оператора - "," : пока оператор наверху стека операторов не является левой скобкой: вытащить оператор из стека операторов в выходную очередь - левая скобка (т.е. "("): поместить его в стек оператора - правая скобка (т.е. ")"): в то время как оператор наверху стека операторов не является левой скобкой: { утверждать, что стек операторов не пуст} /* Если стек заканчивается, а левая скобка не найдена, значит, есть несовпадающие скобки. */ вытащить оператор из стека операторов в выходную очередь { утверждаем, что наверху стека операторов есть левая скобка} извлечь левую скобку из стека операторов и отбросить ее если наверху стека операторов находится токен функции, то : вытащить функцию из стека операторов в очередь вывода/* После цикла while выталкиваем оставшиеся элементы из стека операторов в выходную очередь. */ пока есть токены в стеке операторов: /* Если токен оператора наверху стека является скобкой, то есть несовпадающие скобки. */ { assert the Operator on the top of stack is not a (left) roundthesis} вытащить оператор из стека операторов в выходную очередь

Чтобы проанализировать сложность времени выполнения этого алгоритма, нужно только отметить, что каждый токен будет прочитан один раз, каждое число, функция или оператор будут выведены один раз, и каждая функция, оператор или скобка будут помещены в стек и извлечены из стека один раз — следовательно, существует не более постоянного числа операций, выполняемых на один токен, и время выполнения, таким образом, составляет O( n ) — линейно по размеру входных данных.

Алгоритм сортировочной станции также может быть применен для создания префиксной нотации (также известной как польская нотация ). Для этого нужно просто начать с конца строки токенов, которые нужно проанализировать, и двигаться в обратном направлении, перевернуть выходную очередь (тем самым сделав выходную очередь выходным стеком) и поменять местами поведение левой и правой скобок (помня, что поведение теперь левой скобки должно выскакивать, пока не найдется теперь правая скобка). И изменить условие ассоциативности на правое.

Подробные примеры

Вход: 3 + 4 × 2 ÷ ( 1 − 5 ) ^ 2 ^ 3

ОператорПриоритетАссоциативность
^4Верно
×3Левый
÷3Левый
+2Левый
2Левый

Символ ^ представляет оператор возведения в степень .

ТокенДействиеВыход
RPN )

Стек операторов
Примечания
3Добавить токен к выходу3
+Поместить токен в стек3+
4Добавить токен к выходу3 4+
×Поместить токен в стек3 4× +× имеет более высокий приоритет, чем +
2Добавить токен к выходу3 4 2× +
÷Извлечь стек для вывода3 4 2 ×+÷ и × имеют одинаковый приоритет
Поместить токен в стек3 4 2 ×÷ +÷ имеет более высокий приоритет, чем +
(Поместить токен в стек3 4 2 ×( ÷ +
1Добавить токен к выходу3 4 2 × 1( ÷ +
Поместить токен в стек3 4 2 × 1− ( ÷ +
5Добавить токен к выходу3 4 2 × 1 5− ( ÷ +
)Извлечь стек для вывода3 4 2 × 1 5 −( ÷ +Повторяется до тех пор, пока не будет найдено "("
Поп-стек3 4 2 × 1 5 −÷ +Удалить соответствующие скобки
^Поместить токен в стек3 4 2 × 1 5 −^ ÷ +^ имеет более высокий приоритет, чем ÷
2Добавить токен к выходу3 4 2 × 1 5 − 2^ ÷ +
^Поместить токен в стек3 4 2 × 1 5 − 2^ ^ ÷ +^ вычисляется справа налево
3Добавить токен к выходу3 4 2 × 1 5 − 2 3^ ^ ÷ +
конецИзвлечь весь стек для вывода3 4 2 × 1 5 − 2 3 ^ ^ ÷ +

Ввод: sin (max (2, 3) ÷ 3 × π )

ТокенДействиеВыход
RPN )

Стек операторов
Примечания
грехПоместить токен в стекгрех
(Поместить токен в стек( грех
максПоместить токен в стекмакс ( грех
(Поместить токен в стек( макс ( грех
2Добавить токен к выходу2( макс ( грех
,Игнорировать2( макс ( грехОператор наверху стека — левая скобка.
3Добавить токен к выходу2 3( макс ( грех
)Извлечь стек для вывода2 3( макс ( грехПовторяется до тех пор, пока "(" не окажется наверху стека
Поп-стек2 3макс ( грехОтбрасывание парных скобок
Извлечь стек для вывода2 3 макс.( грехФункция на вершине стека
÷Поместить токен в стек2 3 макс.÷ ( грех
3Добавить токен к выходу2 3 макс 3÷ ( грех
×Извлечь стек для вывода2 3 макс 3 ÷( грех
Поместить токен в стек2 3 макс 3 ÷× ( грех
πДобавить токен к выходу2 3 макс 3 ÷ π× ( грех
)Извлечь стек для вывода2 3 макс 3 ÷ π ×( грехПовторяется до тех пор, пока "(" не окажется наверху стека
Поп-стек2 3 макс 3 ÷ π ×грехОтбрасывание парных скобок
Извлечь стек для вывода2 3 макс 3 ÷ π × синусФункция на вершине стека
конецИзвлечь весь стек для вывода2 3 макс 3 ÷ π × синус

Смотрите также

Ссылки

  1. ^ Теодор Норвелл (1999). «Анализ выражений методом рекурсивного спуска». www.engr.mun.ca . Получено 28.12.2020 .
  2. ^ Дейкстра, Эдсгер (1 ноября 1961). «Перевод Алгола 60: Транслятор Алгола 60 для X1 и создание переводчика для Алгола 60». Stichting Mathematich Centrum .
  • Оригинальное описание алгоритма сортировочной станции Дейкстрой
  • Реализация грамотных программ на языке C
  • Демонстрация алгоритма сортировочной станции в Rust
  • Java-апплет, демонстрирующий алгоритм сортировочной станции
  • Виджет Silverlight, демонстрирующий алгоритм сортировочной станции и оценку арифметических выражений
  • Анализ выражений методом рекурсивного спуска Теодор Норвелл © 1999–2001. Дата доступа 14 сентября 2006 г.
  • Код Matlab, оценка арифметических выражений с использованием алгоритма маневровой станции
Взято с "https://en.wikipedia.org/w/index.php?title=Алгоритм_сортировочной_станции&oldid=1255406784"