查找字符串(javascript)中多个字符索引的最有效算法是什么?

时间:2010-10-21 05:18:25

标签: javascript algorithm

我正在寻找可用于搜索多个字符索引的文本正文的最快方法。

例如:

searchString = 'abcdefabcdef'; 
searchChars  = ['a','b'];
// returns {'a':[0,6], 'b':[1,7]}

3 个答案:

答案 0 :(得分:2)

您应该能够使用正则表达式查找每个字符的所有出现。类似的东西:

function findIndexes(find, str) {
  var output = {};
  for (var i = 0; i < find.length; i++) {
    var m = [];
    var r = new RegExp('.*?' + find[i], 'g');
    var ofs = -1;
    while ((x = r.exec(str)) != null) {
      ofs += x[0].length;
      m.push(ofs);
    }
    output[find[i]] = m;
  }
  return output;
}

编辑:

做了一些改变,现在它有效。 :)但是,由于Javascript没有匹配方法来同时获取所有匹配,所以它实际上并没有使用indexOf ...:P

编辑2:

但是,您可以使用正则表达式查找任何字符,因此您只需要为每个字符循环一次而不是一次。 :)

function findIndexes(find, str) {
  var output = {};
  for (var i = 0; i < find.length; i++) output[find[i]] = [];
  var r = new RegExp('.*?[' + find.join('') + ']', 'g');
  var ofs = -1;
  while ((x = r.exec(str)) != null) {
    ofs += x[0].length;
    output[x[0].substr(x[0].length-1,1)].push(ofs);
  }
  return output;
}

答案 1 :(得分:0)

假设搜索的字母很少而且要搜索的字母很多(即字母数量很少,长字符串),后者是最有效的,因为你只需要经过一次字符串,然后测试每个字母。

另一个经过字符串的次数与要搜索的字母一样多次。

答案 2 :(得分:0)

在计时几个单程算法和Guffa的正则表达式后,我最终得到了这个:

function findIndexesMultiPass(str,find) {
  var x, output = {};

  for (var i = 0; i < find.length; i++) {
    output[find[i]] = [];
    x = 0;
    while ((x = str.indexOf(find[i], x)) > -1) {
      output[find[i]].push(x++);
    }
  }

  return output;
}

var searchString = "abcd abcd abcd";
var searchChars  = ['a', 'b'];
var result = findIndexesMultiPass(searchString, searchChars);
// {'a':[0,5,10], 'b':[1,6,11]}

结果很慢:

function findIndexesOnePass(str,find) {
  var output = {};

  for (var i = 0; i < find.length; i++) {
    output[find[i]] = [];
  }

  for (var i = 0; i < str.length; i++) {
    var currentChar = str.charAt(i);
    if (output[currentChar] !== undefined) {
      output[currentChar].push(i);
    }
  }

  return output;
}

var searchString = "abcd abcd abcd";
var searchChars  = ['a', 'b'];
var result = findIndexesOnePass(searchString, searchChars);
// {'a':[0,5,10], 'b':[1,6,11]}

粗略时间(3个字符的索引)

Google Chrome (Mac)
findIndexesMultiPass: 44ms
findIndexesOnePass: 799ms
findIndexesRegEx: 95ms

Safari
findIndexesMultiPass: 48ms
findIndexesOnePass: 325ms
findIndexesRegEx: 293ms

Firefox
findIndexesMultiPass: 56ms
findIndexesOnePass: 369ms
findIndexesRegEx: 786ms