JavaScript: проверьте, является ли массив подпоследовательностью другого массива (напишите более быстрый наивный алгоритм поиска строки) - PullRequest
0 голосов
/ 12 февраля 2011
[5, 4, 4, 6].indexOfArray([4, 6]) // 2
['foo', 'bar', 'baz'].indexOfArray(['foo', 'baz']) // -1

Я придумал это:

Array.prototype.indexOfArray = function(array) {
    var m = array.length;
    var found;
    var index;
    var prevIndex = 0;
    while ((index = this.indexOf(array[0], prevIndex)) != -1) {
        found = true;
        for (var i = 1; i < m; i++) {
            if (this[index + i] != array[i]) {
                found = false;
            }
        }
        if (found) {
            return index;
        }
        prevIndex = index + 1
    }
    return index;
};

Позже я обнаружил, что Википедия называет это Наивным поиском строк :

В обычном случае нам нужно только взглянуть на один или два символа для каждой неправильной позиции, чтобы увидеть, что это неправильная позиция, поэтому в среднем случае требуется O (n + m) шагов, где n длина стога сена, а m - длина иглы; но в худшем случае, для поиска строки типа «aaaab» в строке типа «aaaaaaaaab» требуется O (нм) шагов.

Может кто-нибудь написать более быстрый метод indexOfArray в JavaScript?

Ответы [ 2 ]

5 голосов
/ 12 февраля 2011

Алгоритм, который вам нужен, это алгоритм KMP (http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm), используемый для поиска начального индекса подстроки в строке - вы можете сделать то же самое для массива.

Я не смог найти реализацию javascript, но вот реализации на других языках http://en.wikibooks.org/wiki/Algorithm_implementation/String_searching/Knuth-Morris-Pratt_pattern_matcher - не должно быть сложно преобразовать его в js.

1 голос
/ 12 февраля 2011

FWIW: я нашел эту статью хорошим чтением Эффективный поиск по подстроке В нем обсуждаются несколько вариантов Бойера-Мура, хотя его нет в JavaScript.Вариант Boyer-Moore-Horspool (от Timo Raita - см. Первую ссылку для ссылки) будет моим «предложением» для потенциального практического увеличения скорости (хотя не уменьшает big-O - большой-O - ​​это только верхний предел !).Обратите внимание на Заключение внизу статьи и тесты выше.

Я в основном пытаюсь противопоставить реализацию Кнута-Морриса-Пратта; -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...