Pull to refresh
288
0
Александр Полозов @Skiminok

User

Send message
Кормен же.
Седжвик ещё.
E-maxx, разумеется.
Тысячи их.
Огромное количество эффективных алгоритмов на строках и структур данных для быстрых операций с ними (в том числе бор) были разработаны, когда биологам потребовалось анализировать цепочки ДНК колоссальной длины.
Спасибо :)
Эта статья, в свою очередь, тоже замечательна.

Стоит упомянуть здесь одну из лучших книг по строковым алгоритмам и структурам данных, связанным с ними:
Дэн Гасфилд, «Строки, деревья и последовательности в алгоритмах. Информатика и вычислительная биология»
Делать Delphi не стал, но приличное количество идей позаимствовал.
Браво. Отличная статья, спасибо, прочитал без отрыва.
Редко сейчас встретишь в «Алгоритмах» настолько качественный материал.
Если уж сортировать «тьюринговые трясины» по важности, то надо начинать с основных — математических, на которых всё строилось, а потом уж добавлять в список новомодную эзотерику вроде Brainfuck.
В таком случае это будут:
  • машина Тьюринга (машину Поста знаю, конечно, но популярности она не приобрела);
  • лямбда-исчисление Черча;
  • рекурсивные функции Черча;
  • нормальные алгоритмы Маркова.

Во «второй эшелон» попадут-таки машина Поста, блок-схема Поста, комбинаторное исчисление Шейнфинкеля, и, если уж добавлять современные «эзотерические языки программирования» в список — Brainfuck со товарищи.

И, будьте добры, не называйте «тьюринговы трясины» эзотерическими системами. Это сейчас BF и ему подобные — эзотерические языки программирования на фоне современных высокоуровневых, а машина Тьюринга и эквивалентные ей создавались не чувство юмора программиста потешить, а математически понятие вычислимости и алгоритмистики исследовать, это совершенно разные вещи.

Как-то так.
Как по мне, у Kees van Dijkhuizen Cinema 2009 и Cinema 2008 были лучше.
В перле внутрь регулярок можно куски перлового кода совать, так они Тьюринг-«полными» получаются :)
Боюсь даже подумать, чтобы мне когда-нибудь пришлось разбирать творение какого-нибудь оголтелого фаната регулярок с использованием таких наворотов.
Демоненок, очень приятно.
Реализовать разбор на регулярных выражениях сделать нельзя, так как языки программирования не являются регулярными

Теоретически — вы правы.
На практике синтаксические возможности современных регулярных выражений намного превышают класс регулярных языков. Например, с помощью backreferences можно построить выражение, которое опишет язык, не относящийся ни к регулярным, ни даже к контекстно-свободным (большинство языков программирования, тем не менее, контекстно-свободные — описываются BNF). Вообще, движок регулярок давно уже никто не реализовывает с помощью ДКА, там давно перебор. Я и не припомню сейчас движок «чистых» регулярок, с ДКА внутри. В Tcl/Tk такое осталось, кажется, но не уверен.
Хочу себе машину времени. На худой конец согласен на молодильные яблоки.
Могу протестить на 108. Все равно не думаю, что результаты будут сильно отличаться.
Ну это в комментах обсуждалось. Для рандомизированной версии вообще трудно указать оценку сложности, можно ориентироваться только на практические тесты. А они хорошие.
Вот именно!
Это два разных варианта реализации одной и той же функции Unite.
В одной нам нужно хранить массив Rank — мы пользуемся им при принятии решения о переподвешивании.
В другой мы принимаем это решение случайным образом, а значит, массив Rank в ней нам не нужен.

Я привел обе реализации, потому что первая является классической, для неё доказана оценка скорости O(α(N)), а вторую проще писать, а на практике она работает почти так же быстро.
Никакую, они в такой реализации вообще не нужны, их можно не считать и не хранить.
В принципе там есть исходник, однако я не против объяснить и здесь.

У вас есть два элемента, X и Y. Вы стандартными операциями Find нашли корни их деревьев: пускай это RX и RY. Чтобы слить два дерева, достаточно один из корней подвесить к другому непосредственным сыном, то есть сделать просто либо P[RX] = Y, либо P[RY] = X. Встает вопрос, какой из двух вариантов выбирать?

В стандартной реализации для этого используется массив рангов, и мы выбираем вариант из принципа «дерево меньшей высоты подвешивать к дереву большей высоты». Однако можно обойтись и без этого. Просто принимаем решение случайно: каждый раз генерируем местным rand() случайное целое число от 0 до 1. Если это 0, подвешиваем RY к RX, если же 1 — то RX к RY.

Время работы такой реализации в среднем оценить достаточно проблемно. Однако если её действительно написать и протестировать на многих разнообразных данных, окажется, что она почти не уступает варианту с рангами.
Нет, просто именно такой способ обеспечивает наилучшую скорость работы. Можно хранить списками, можно настоящими множествами (set<T>), но тогда в любом случае какая-нибудь из операций окажется O(log2 N), O(N) и т.д. — слишком медленно.
Сорри. Походу, топики надо дописывать в более выспавшемся состоянии :) Исправил.

Information

Rating
Does not participate
Location
Seattle, Washington, США
Works in
Date of birth
Registered
Activity