Я ищу структуру данных , которая хранит множество строк над набором символов , способных выполнять следующие операции. Обозначим через D ( S ) в качестве структуры данных , хранящей множество строк S .
Add-Prefix-Set
на : для некоторого множества T (возможно, пустых) строк, размер которых ограничен константой, а длины строк ограничены константой, вернуть D ( { t s | t ∈ T , s ∈ S } ) , Оба эти константы являются глобальными Ограничивающими: они одинаковы для всех входов Т .Get-Prefixes
на : возврат { a | a s ∈ S , a ∈ Σ } . Обратите внимание, что я действительно не против того, какая структура используется для этого набора, поскольку я могу перечислить его содержимое за O ( | Σ | ) время.Remove-Prefixes
на : вернуть D ( { s | a s ∈ S , a ∈ Σ } ) .Merge
: даны и D ( T ) , вернуть D ( S ∪ T ) .
Теперь я действительно хотел бы выполнить все эти операции за время , но я в порядке со структурой, которая выполняет все эти операции за время o ( n ) , где n - длина самой длинной строки в состав. В случае слияния, я хотел бы, чтобы o ( n 1 + n 2 ) выполнялось, где n 1 - это n для первой, а n 2 - для n для второй структуры.
Дополнительным требованием является то, что структура является неизменной или, по крайней мере, вышеуказанные операции возвращают «новые» структуры, так что указатели на старые по-прежнему функционируют, как и прежде.
Примечание об амортизации: это хорошо, но вы должны остерегаться настойчивости. Поскольку я все время использую старые структуры, у меня будут проблемы, если я столкнусь с наихудшим случаем с каким-то конкретным набором операций с той же структурой (игнорируя создаваемые им новые структуры).
Я хотел бы использовать такую структуру в алгоритме синтаксического анализа, над которым я работаю; Приведенная выше структура будет содержать запрос, необходимый мне для алгоритма.
источник
Add-Prefix-Set
или вы начинаете с произвольного набора строк?Add-Prefix-Set
ее)Ответы:
Я думал довольно долго, но не нашел проблемы с выполнением всех ваших операций самым глупым из возможных способов в структуре структуры DAG, похожей на три:
Надстройка Приставка-Set
Объединить
Объедините корни двух структур: сделайте все дочерние узлы второго корневого потомка первого узла. Теперь у вас может быть несколько ребер, помеченных одним и тем же символом, идущим от одного и того же узла.
Ленивое обновление рута
Get-префиксы
Ленивое обновление рута. Теперь найдите всех потомков корня и сообщите множество букв по краям, идущим к ним.
Remove-префиксы
Ленивое обновление рута. Объедините всех дочерних элементов корня и установите корневой указатель на результат этого объединения. Ленивое обновление нового рута.
Упорство
источник