Совсем нет; посмотри снова. Достигнув 5-го элемента, вы уже знаете, что элементы 2, 3, 4 являются , а не первым элементом, поэтому вы просто переключаетесь, чтобы начать заново с несоответствующего элемента.
Это хорошо известная проблема в грамматиках, которую можно решить с помощью конечного автомата.
Сначала не беспокойтесь о содержимом ваших строк; все, что имеет значение, это то, что у вас есть последовательность символов для поиска Каждая строка «число» - это отдельный символ. Для удобства сопоставим следующее:
'818181' => a
'747473' => b
'747474' => c
etc.
Таким образом, массив может быть уменьшен до чего-то подобного:
'818181' '747473' '747474' '636363' '767676' '737373' '727373' '373838'
a b c d e f g h
'697070' '686869' '115115115' '737474' '757575' '777777' '818181' '747473'
i j k l m n a b
'747474' '636363' '767676' '737373' '727373' '757575' '696969']
c d e f g m o
Или как последовательность из одной строки:
abcdefghijklmnabcdefgmo
В случае, если вы отметили несоответствие на b
, нам не нужно возвращаться к положению b
ввода и начинать заново; мы уже определили, что bcd
соответствует, а они не a
, поэтому мы не копируем: мы просто начинаем снова, сравнивая a
с элементом, который не матч.
Как это случается, мы никогда не должны выполнять резервное копирование. В худшем случае мы возобновим проверку в том месте, где совпадение не удалось, но не в начале нашей целевой строки. Есть один хитрый случай, с которым нам нужно разобраться: совпадение в середине строки.
Рассмотрим, что происходит, когда мы имеем несовпадение во втором m
, ближе к концу целевой последовательности. В этом случае мы знаем, что мы только что сопоставили abcdefg
, но текущий символ не m
... но если может быть h
. Чтобы избежать резервного копирования, мы используем частичное совпадение и возобновляем проверку с помощью h
.
Для обработки этого алгоритма вам необходимо выполнить некоторую предварительную обработку целевой строки. Создайте второй массив, содержащий индекс перезапуска для каждой позиции в целевой строке. Вы делаете это с простой проверкой того, где он отклоняется от самого себя. Для вашего примера это просто: o
- единственное место, где основная строка и сдвинутая строка соответствуют нескольким символам, но отличаются в этом месте.
abcdefghijklmnabcdefgmo
11111111111111111111181
Это заставляет вас двигаться?