2010-08-09 2 views
2

У меня есть строка, как это:Использование регулярного выражения для потенциального улучшения производительности синтаксического анализа строк?

// string1 
horse|cow|goat|zebra| 

и другую строку, как это:

// string2 
horse:a,pig:b,cow:z,monkey:g,goat:a, 

моя цель состоит в том, чтобы разделить строку1, а затем выбрать все вхождения его в строке2, чтобы построить гистограмму , В настоящее время я делаю это:

var histogram = {}; 

var animals = string1.split("|"); 
for (var i = 0; i < animals.length; i++) { 
    var animal = animals[i]; 
    var animalColon = animal + ":"; 

    var index = string2.indexOf(animalColon); 
    while (index != -1) { 
     var indexColon = index + animalColon.length; 
     var indexFinal = string2.indexOf(",", indexColon); 
     var letter = string2.substring(indexColon, indexFinal); 

     if (histogram[letter] == null) { 
      histogram[letter] = 1; 
     } 
     else { 
      histogram[letter] = histogram[letter] + 1; 
     } 
     index = string2.indexOf(animalColon, index + 1); 
    } 
} 

в конце концов, он может напечатать что-то вроде:

// histogram: 
a: 2 instances // from { horse, goat } 
z: 1 instance // from { cow } 

выше будет работать, но я должен дп animals.length проходит через строке2 проверить все.

Есть ли способ использовать регулярные выражения для этого синтаксического анализа - по существу, выполнять все тесты параллельно, а не выполнять несколько проходов? Поскольку string2 является const, кажется, что все проверки могут выполняться одновременно (не уверен, что регулярные выражения реализованы так).

я увеличил количество элементов в string1 и string2 порядка тысяч элементов, и это все еще работает довольно быстро, но я беспокоюсь о более медленных машинах, ремонтопригодности и тому подобное,

Благодаря

ответ

0

Я бы начал с предварительной обработки вашей строки2, которая, как вы говорите, является постоянной. Работа с объектом лучше, чем продолжать поиск в строке:

var s = "horse:a,pig:b,cow:z,monkey:g,goat:a"; 
var hash = {}; 
var tokens = s.split(','); 
for(var i=0;i<tokens.length;i++){ 
    var a = tokens[i].split(':'); 
    hash[a[0]] = a[1]; 
} 

Затем, когда вы получите строку, вам легче, глядя вверх письма (вы также можете проверить if(letter), если вы получаете новое животное в string1):

var histogram = {}; 
var string1 = "horse|cow|goat|zebra"; 
var animals = string1.split("|"); 
for(var i=0;i<animals.length;i++){ 
    var letter = hash[animals[i]]; 
    if (!histogram[letter]) 
     histogram[letter] = 0; 
    histogram[letter]++; 
} 

по вашему вопросу, вы, вероятно, злоупотребляют регулярное выражение для подсчета букв, но не параллельно, но линейный, в лучшем случае, и, вероятно, достаточно сложно не стоит.

0

Несколько советов, которые могут увеличить производительность:

  • Определить все переменные один раз в начале сценария
  • Вычислить длину строки один раз в начале цикла
  • Использование строгого оператора сравнения (= ==), когда это применимо
0

для записи, вы можете использовать регулярные выражения, чтобы получить гистограмму в 3-х утверждений:

var letters = "horse:a,pig:b,cow:z,monkey:g,goat:a"; 
var string1 = "horse|cow|goat|zebra"; 

var h = {}; 
var regex = new RegExp("\\b(?:" + string1 + "):(\\w+)", "ig"); 
letters.replace(regex, function(g0, g1){h[g1] = (h[g1] || 0) + 1;}); 

Это имеет много уровней злоупотребления, а именно, использование replace в качестве итератора (не обращая внимания на результат и имеющие побочные эффекты в обратный вызов), и отмечая, что string1 сортировки выглядит как регулярное выражение уже с | как разделители, и, похоже, не содержит других метасимволов регулярных выражений.

Смежные вопросы