В программе мне нужно эффективно отвечать на запросы следующей формы:
Учитывая набор строк
A
и строку запросаq
вернуть всеs ∈ A
таким образом, что q является subsequence ofs
Например, данные A = {"abcdef", "aaaaaa", "ddca"}
и q = "acd"
должны быть возвращены точно "abcdef"
.
Ниже приведено то, что я рассмотрел до сих пор:
-
Для каждого возможного символа создайте отсортированный список всех строк/мест, где он появляется. Для запросов чередуйте списки задействованных символов и просматривайте их, ища совпадения в границах строк.
Это, вероятно, будет более эффективным для слов вместо символов, так как ограниченное количество разных символов сделает списки возврата очень плотными.
-
Для каждого n-префикса
q
может быть сохранен список всех соответствующих строк.n
может реально приблизиться к 3. Для строк запроса дольше, чем мы, перетаскиваем исходный список.Это может немного ускорить работу, но можно легко представить, что некоторые n-подпоследовательности присутствуют рядом со всеми строками в
A
, что означает, что худший случай - это то же самое, что просто грубый форсинг всего набора.
Знаете ли вы о каких-либо структурах данных, алгоритмах или методах предварительной обработки, которые могут быть полезны для эффективного выполнения вышеуказанной задачи для больших A
s? (My s
будет около 100 символов)
Обновление:. Некоторые люди предложили использовать LCS, чтобы проверить, является ли q
подпоследовательность s
. Я просто хочу напомнить, что это можно сделать с помощью простой функции, такой как:
def isSub(q,s):
i, j = 0, 0
while i != len(q) and j != len(s):
if q[i] == s[j]:
i += 1
j += 1
else:
j += 1
return i == len(q)
Обновление 2:. Мне было предложено дать более подробную информацию о характере q
, A
и его элементов. Хотя я бы предпочел что-то, что работает как можно лучше, я полагаю, что A
будет иметь длину около 10 ^ 6 и потребуется поддержка вставки. Элементы s
будут короче со средней длиной 64. Запросы q
будут только от 1 до 20 символов и использоваться для прямого поиска, поэтому запрос "ab" будет отправлен непосредственно перед запросом "abc". Опять же, я бы предпочел решение использовать приведенное выше как можно меньше.
Обновление 3: Мне пришло в голову, что структура данных с поиском O(n^{1-epsilon})
позволит вам решить OVP/опровергнуть гипотезу SETH. Вероятно, это причина наших страданий. Единственные варианты - это затем опровергнуть гипотезу, использовать аппроксимацию или воспользоваться набором данных. Я полагаю, что четырехдверки и попытки будут делать последнее в разных настройках.