эффективный поиск по php итератору - PullRequest
4 голосов
/ 24 декабря 2010

У меня есть пользовательский итератор (точнее TokenIterator, который итерирует, ну, в общем, токенизированный код php). Элементы - это простые объекты («пакеты свойств» с добавлением некоторых методов нормализации)

Я должен реализовать функцию поиска, которая должна найти, если 1. один итератор содержит другой или 2. два (или более) итератора перекрываются (с некоторой параметризацией).

В настоящее время я использую наивный подход к (1) - O (NxM) двойному циклу поиска, а (2) еще не реализован.

Прежде чем начать переопределять действительно умные алгоритмы поиска строк, я хотел бы знать, существует ли какая-либо эффективная реализация этого? Может быть, что-то похоронено глубоко в какой-то структуре или универсальной библиотеке для повторного использования? И какой алгоритм здесь будет наиболее подходящим?

Ответы [ 2 ]

3 голосов
/ 27 декабря 2010

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

Я не знаю, существует ли какое-либо существующее решение для вашей проблемы, но в качестве общего решения я бы использовал хеш-таблицы. Например, создайте хеш-таблицу, используя токены первого набора (с этого момента я буду называть ее набором, так как я считаю, что Iterator - не лучшее слово), и вы можете сделать это в Theta (N), а затем попытаться вставьте другой набор в ту же хеш-таблицу. Когда вы столкнетесь в первый раз, вы поймете, что есть совпадение. Конечно, это хорошо работает, если хеш-пространство велико, а хеш-функция гарантирует незначительное количество коллизий, однако всегда можно закодировать какой-то обходной путь.

Учитывая, что в PHP есть ассоциативные массивы (которые являются формой хеш-таблиц), вы также можете создать массив с токенами в качестве ключей, что снова можно сделать в Theta (N), а затем использовать array_key_exists. Вполне возможно, что array_key_exists - это не что иное, как линейное сканирование списка ключей, так как я не знаком с внутренностями PHP, но я совершенно уверен, что если ассоциативные массивы реализованы в виде хеш-таблиц, они должны быть реализованы гораздо чаще. эффективнее, чем линейное сканирование.

1 голос
/ 24 декабря 2010

Если ваши итераторы могут быть преобразованы в массивы, вы можете использовать array_diff и array_intersect.В противном случае вы должны реализовать то, что эти функции делают под капотом - пройтись по вашим структурам и сравнить.Поскольку данные, которые вы повторяете, не отсортированы, и вы ничего не знаете об этом, у вас нет другого выбора.

...