JavaScript:检查数组是否是另一个数组的子序列(写一个更快的天真字符串搜索算法)

时间:2011-02-12 19:32:06

标签: javascript algorithm search

[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;
};

后来我找到wikipedia calls it Naïve string search

  

在正常情况下,我们只需要查看每个错误位置的一个或两个字符,看它是一个错误的位置,所以在一般情况下,这需要O(n + m)步,其中n是干草堆的长度和m是针的长度;但在最坏的情况下,在像“aaaaaaaaab”这样的字符串中搜索像“aaaab”这样的字符串,需要O(nm)步。

有人可以在JavaScript中编写更快的indexOfArray方法吗?

2 个答案:

答案 0 :(得分:5)

您想要的算法是用于查找字符串中子字符串的起始索引的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 :(得分:1)

FWIW:我发现这篇文章很好阅读Efficient substring searching它讨论了Boyer-Moore的几种变体,尽管它不是用JavaScript。 Boyer-Moore-Horspool变体(由Timo Raita撰写 - 请参阅链接的第一个链接)将成为我对潜在实际速度增益的“建议”(虽然不会减少大O) - 大O是仅限上限!)。请注意本文底部的结论和上面的基准。

我主要试图反对Knuth-Morris-Pratt的实施; - )