Конечно, есть лучшие способы, чем использование двух циклов: D Это даст вам O (n^2) время исполнения. Что-то очень полезное для поиска подстрок называется rolling hash. Это способ использовать предыдущую информацию, чтобы ускорить поиск подстрок. Это выглядит примерно так:
Скажем, у меня есть строка, f1 = "cat"
и длинная строка f2 = "There once was a cat named felix"
. То, что вы делаете, - это определение «хэш» на основе букв вашей строки f1. Специфика этого может быть найдена в Интернете в разных источниках, но в этом примере позволяет упростить вещи и сказать, что буквы присваиваются числам, начинающимся с 0, до 25, и мы умножим значение каждой буквы, чтобы сформировать десятичное число с числом цифры, равные длине строки:
hash("cat") = 10^2 * 2 + 10^1 * 0 + 10^0 * 19
= some value (in python the "hash" values of letters
are not 0 through 25 but given by using the ord cast:
ord("a") will give you 97)
Теперь эта следующая часть супер крутая. Мы обозначаем окна размера нашей строки f1, поэтому размер 3 и хэш строку f2 так же, как и с f1. Вы начинаете с первых трех букв. Хэш не соответствует, поэтому мы движемся дальше. Если хэш согласован, мы убеждаемся, что это одна и та же строка (иногда хэши одинаковы, но не являются одной и той же строкой из-за того, как мы назначаем хэши, но это нормально).
COOL PART ** Вместо того, чтобы просто сдвигать окно и переписывать буквы от 2 до 4 букв f2, мы «свертываем» окно и не пересчитываем весь хеш (который, если f1 действительно длинный, будет пустой тратой время), так как единственные буквы меняются первыми и последними! Трюк состоит в том, чтобы вычесть первое значение хэша (в нашем примере будет ord ("t") * 10^2), затем умножьте все число, оставшееся на десять (потому что мы переместили все влево) и добавим новый хеш буква, ord («r») * 10^0. Проверьте снова матч и перейдите. Если мы сопоставим, вернем индекс.
Почему мы это делаем: если у вас достаточно длинная строка f1, вы сокращаете время выполнения до O (n * len (n)), так что асимптотически линейны!
Теперь фактическая реализация требует времени и может стать беспорядочной, но для такого ответа есть много источников в Интернете. My algorithms class имеет отличные примечания к курсу в Интернете, которые помогают понять теорию немного лучше, и есть тонны ссылок с реализациями python. Надеюсь это поможет!
Обходным путем является использование надлежащей базы данных. – sashkello
Вы можете читать в 1000 строк (или больше) из f1 за раз и искать их в f2. – ooga
@ooga Я не совсем уверен, как реализовать это. Не могли бы вы разработать или, возможно, показать псевдокод? – ytrewq