admin / 28.04.2018

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

Алгоритм сортировочной станции — способ разбора математических выражений, представленных в инфиксной нотации. Может быть использован для получения вывода в виде обратной польской нотации или в виде абстрактного синтаксического дерева. Алгоритм изобретен Эдсгером Дейкстрой и назван им «алгоритм сортировочной станции», поскольку напоминает действие железнодорожнойсортировочной станции.

Так же, как и вычисление значений выражений в обратной польской записи, алгоритм работает при помощи стека. Инфиксная запись математических выражений чаще всего используется людьми, её примеры: 2+4 и 3+6*(3-2). Для преобразования в обратную польскую нотацию используется 2 строки: входная и выходная, и стек для хранения операторов, еще не добавленных в выходную очередь. При преобразовании алгоритм считывает 1 символ и производит действия, зависящие от данного символа.

Алгоритм[ | код]

  • Пока не все токены обработаны:
  • Прочитать токен.
  • Если токен — число, то добавить его в очередь вывода.
  • Если токен — функция, то поместить его в стек.
  • Если токен — разделитель аргументов функции (например запятая):
  • Пока токен на вершине стека не открывающая скобка, перекладывать операторы из стека в выходную очередь. Если в стеке не было открывающей скобки, то в выражении пропущен разделитель аргументов функции (запятая), либо пропущена открывающая скобка.
  • Если токен — оператор op1, то:
  • Пока присутствует на вершине стека токен оператор op2, и
Либо оператор op1 лево-ассоциативен и его приоритет меньше, чем у оператора op2 либо равен,
или оператор op1 право-ассоциативен и его приоритет меньше, чем у op2,
переложить op2 из стека в выходную очередь;
  • (Иначе, когда стек операторов пуст или содержит открывающую скобку)
  • Если токен — открывающая скобка, то положить его в стек.
  • Если токен — закрывающая скобка:
  • Пока токен на вершине стека не является открывающей скобкой, перекладывать операторы из стека в выходную очередь.
  • Выкинуть открывающую скобку из стека, но не добавлять в очередь вывода.
  • Если токен на вершине стека — функция, добавить её в выходную очередь.
  • Если стек закончился до того, как был встречен токен открывающая скобка, то в выражении пропущена скобка.
  • Если больше не осталось токенов на входе:
  • Пока есть токены операторы в стеке:
  • Если токен оператор на вершине стека — скобка, то в выражении присутствует незакрытая скобка.
  • Переложить оператор из стека в выходную очередь.

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

Ссылки[ | код]

Алгоритм сортировочной станции — способ разбора математических выражений, представленных в инфиксной нотации Может быть использован для получения вывода в виде обратной польской нотации или в виде абстрактного синтаксического дерева Алгоритм изобретен Эдсгером Дейкстрой и назван им «алгоритм сортировочной станции», поскольку напоминает действие железнодорожной сортировочной станции

Так же, как и вычисление значений выражений в обратной польской записи, алгоритм работает при помощи стека Инфиксная запись математических выражений чаще всего используется людьми, её примеры: 2+4 и 3+63-2 Для преобразования в обратную польскую нотацию используется 2 строки: входная и выходная, и стек для хранения операторов, еще не добавленных в выходную очередь При преобразовании алгоритм считывает 1 символ и производит действия, зависящие от данного символа

Алгоритмправить

  • Пока не все токены обработаны:
  • Прочитать токен
  • Если токен — число, то добавить его в очередь вывода
  • Если токен — функция, то поместить его в стек
  • Если токен — разделитель аргументов функции например запятая:
  • Пока токен на вершине стека не открывающая скобка, перекладывать операторы из стека в выходную очередь Если в стеке не было открывающей скобки, то в выражении пропущен разделитель аргументов функции запятая, либо пропущена открывающая скобка
  • Если токен — оператор op1, то:
  • Пока присутствует на вершине стека токен оператор op2, и

Либо оператор op1 лево-ассоциативен и его приоритет меньше, чем у оператора op2 либо равен, или оператор op1 право-ассоциативен и его приоритет меньше, чем у op2, переложить op2 из стека в выходную очередь;

  • Если токен — открывающая скобка, то положить его в стек
  • Если токен — закрывающая скобка:
  • Пока токен на вершине стека не является открывающей скобкой, перекладывать операторы из стека в выходную очередь
  • Выкинуть открывающую скобку из стека, но не добавлять в очередь вывода
  • Если токен на вершине стека — функция, добавить её в выходную очередь
  • Если стек закончился до того, как был встречен токен открывающая скобка, то в выражении пропущена скобка
  • Если больше не осталось токенов на входе:
  • Пока есть токены операторы в стеке:
  • Если токен оператор на вершине стека — скобка, то в выражении присутствует незакрытая скобка
  • Переложить оператор из стека в выходную очередь

Каждый токен-число, функция или оператор выводится только один раз, а также каждый токен-функция, оператор или круглая скобка будет добавлен и удален из стека по одному разу Постоянное количество операций на токен, линейная сложность алгоритма On

Ссылкиправить

Имеется викиучебник по теме
«Алгоритм сортировочной станции»

  • Java апплет, демонстрирующий работу алгоритма
  • Parsing Expressions by Recursive Descent Theodore Norvell © 1999—2001 Access date September 14, 2006
  • Алгоритм преобразования инфиксной записи в обратную польскую нотацию
  • Оригинальное описание алгоритма
  • Расширение алгоритма для использования произвольного количества аргументов функции


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


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

Алгоритм сортировочной станции Информация Видео


Алгоритм сортировочной станции Просмотр темы.

Алгоритм сортировочной станции что, Алгоритм сортировочной станции кто, Алгоритм сортировочной станции объяснение

There are excerpts from wikipedia on this article and video


Учитывая современное развитие Интернета, было бы кощунством не написать приложение, взаимодействующее со всемирной паутиной. Сегодня мы напишем простенький html-парсер на Python.

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

Наше приложение будет читать код указанной страницы сайта и сохранять все ссылки в ней в отдельный файл. Это приложение может помочь SEO-аналитикам и веб-разработчикам.

Писать будем на Python 3, в котором есть встроенный класс для html-парсера из модуля html.parser

from html.parser import HTMLParser

Так же нам понадобится функция urlopen из модуля urllib

from urllib.request import urlopen

Именно функция urlopen будет получать исходный код указанной странички.

Перегрузка класса HTMLParser

Наша задача таким образом перегрузить функционал существующего класса HTMLParser, чтобы он соответствовал нашей задаче.

class MyHTMLParser(HTMLParser): def __init__(self, site_name, *args, **kwargs): # список ссылок self.links = [] # имя сайта self.site_name = site_name # вызываем __init__ родителя super().__init__(*args, **kwargs) # при инициализации «скармливаем» парсеру содержимое страницы self.feed(self.read_site_content()) # записываем список ссылок в файл self.write_to_file()

Базовый класс HTMLParser имеет несколько методов, нас в данном случае интересуют метод handle_start_tag. Этот метод вызывается каждый раз, когда наш парсер встречает в тексте октрывающий html-тэг.

def handle_starttag(self, tag, attrs): # проверяем является ли тэг тэгом ссылки if tag == ‘a’: # находим аттрибут адреса ссылки for attr in attrs: if attr[0] == ‘href’: # проверяем эту ссылку методом validate() (мы его еще напишем) if not self.validate(attr[0]): # вставляем адрес в список ссылок self.links.append(attr[1])

Напишем вспомогательный метод validate:

def validate(self, link): «»» Функция проверяет стоит ли добавлять ссылку в список адресов. В список адресов стоит добавлять если ссылка: 1) Еще не в списке ссылок 2) Не вызывает javascript-код 3) Не ведет к какой-либо метке. (Не содержит #) «»» return link in self.links or ‘#’ in link or ‘javascript:’ in link

Создадим метод, который будет открывать указанную страницу и выдавать ее содержимое.

def read_site_content(self): return str(urlopen(self.site_name).read())

Осталось добавить возможность записи списка ссылок на диск в читабельном формате:

def write_to_file(self): # открываем файл f = open(‘links.txt’, ‘w’) # записываем отсортированный список ссылок, каждая с новой строки f.write(‘\n’.join(sorted(self.links))) # закрываем файл f.close()

Все готово, можем запускать парсер.

parser = MyHTMLParser(«http://python.org»)

После того как вы запустите данный скрипт в директории, где находится ваш файл появится текстовый документ links.txt, содержащий ссылки.

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

Резюме

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

Подробная версия

Я создаю приложение, в котором я хотел бы проанализировать списки аргументов из текстовой строки, которая затем будет преобразована в шаблон для перехода к реальному методу.

Реализации алгоритмов/Алгоритм сортировочной станции

Например, если моя текстовая строка:

проанализированный результат был бы чем-то сопоставимым с:

Мне известен модуль Python ast, но он, по-видимому, обеспечивает механизм анализа целых операторов. Я могу подделать это, создав выражение вокруг него, например

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

Есть ли способ разобрать только один известный тип node из Python AST, или есть более простой подход для получения этой функции?

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

Если существует существующий модуль для создания лексеров и парсеров в Python, я тоже хорошо разбираюсь в моем собственном AST, но, очевидно, я бы предпочел просто использовать уже существующие функциональные возможности и был протестирован правильно и т.д.

Примечание. Многие ответы сосредоточены на том, как хранить анализируемые результаты, но это не то, о чем я забочусь; это сам анализ, который я пытаюсь решить, в идеале, без написания всего синтаксического анализатора.

Кроме того, мое приложение уже использует Jinja, у которого есть парсер для выражений Python-ish в своем собственном синтаксисе шаблонов, хотя он мне не понятно, как использовать его для анализа только одного подвыражения, подобного этому. (Это, к сожалению, не что-то входит в шаблон, а в специальный фильтр Markdown, где я бы хотел, чтобы синтаксис соответствовал его подходящей функции шаблона Jinja как можно ближе.)

pythonparsing

задан fluffy 09 апр. '18 в 0:42

источникподелиться

FILED UNDER : IT

Submit a Comment

Must be required * marked fields.

:*
:*