2016-05-12 6 views
2

описание проблемы. Предположим, у вас есть набор строк (до 10 миллиардов строк, каждая строка длиной до 10 тыс. Символов, из которых может быть построено 1000 уникальных символов). Как я могу найти шаблоны длиной от 2 до длины N (скажем, 10 для простоты). Также я хотел бы видеть только те шаблоны, которые встречаются по крайней мере в 1% от всей строки (некоторый порог).Как найти неизвестные повторяющиеся шаблоны в наборе строк?

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

Спасибо Индекс

ответ

1

все ваши строки в дерево суффиксов (link). Это может быть O (количество символов), и вам нужно сделать это только один раз, прежде чем вы начнете.

Дерево суффиксов позволяет быстро (O (длина шаблона)) указать, появляется ли шаблон в любой из проиндексированных строк и сколько раз.

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

Теперь 10 миллиардов строк длиной 10k с 2 байтовыми символами (чтобы соответствовать 1000 уникальным символам) довольно велики (18TB, если моя математика правильная), которая не подходит в баране. Таким образом, вам придется либо подождать какое-то время, либо получить больше компьютеров и настроить распределенное решение. Вы можете применить решение выше к партиям строк, чтобы они вписывались в вашу доступную память, но поиск в структуре нужно умножать на количество партий, которые вы делаете.

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

+0

Если вы просто подсчитаете количество листьев ниже узла, вы будете подсчитывать общее количество появлений паттерна (* включая * множественные появления в пределах одной строки), а не то, что запросил ОП (а именно, общее количество строк, в пределах которых появляется шаблон). Но ваш путь выполняется быстро, и для вычисления TTBOMK последнего требуется хранить в каждом узле * набор строк, расположенных ниже него, и вычислять союзы во время DFS, что умножает сложность времени и пространства, поэтому, возможно, это достаточно хорошо , –

+0

Я думаю, что у меня не было представления о дозировании. Предположим, я разделил свой вклад на разумные партии размера, которые мой компьютер/кластер может обрабатывать сразу - не следует ли мне объединить все эти партии в конце, чтобы получить правильный ответ? Я ошибаюсь? –

+0

Вы правы, вам нужно объединить результаты в конце, чтобы получить правильный ответ. Я предположил, что эта часть очевидна. – Sorin