Очевидно, что слово во входной строке может потребовать объединения двух или более элементов массива, чтобы считаться совпадающими.Это, вероятно, самая сложная часть требования.
Во-вторых, кажется, что как только слово соответствует (или сочетается) со значением (ями) массива, эти элементы массива больше не должны использоваться дляеще один матч.
Я бы предложил использовать простой объект для хранения значений массива в качестве свойств.Это позволит быстро найти, и удаление (для удовлетворения второго пункта выше) также может быть сделано довольно эффективно.Для реализации первого требования я бы придерживался подхода грубой силы.В качестве альтернативы вы можете построить дерево суффиксов , но вам потребуется огромный вклад, прежде чем вы получите от него выгоду, поэтому я не буду предлагать это.
Вы можете использовать рекурсию, чтобы найтирешение для небольшой задачи после того, как вы нашли потенциальное совпадение для (части) слова.
Вот решение EcmaScript 3, которое реализует эти идеи:
function match(str, arr) {
var words = str.toLowerCase().split(/\s+/);
var keys = {};
for (var i = 0; i < arr.length; i++) keys[arr[i].toLowerCase()] = 1;
function recur(i) {
if (i >= words.length) return true;
var word = words[i];
if (keys[word]) { // Try full match first - relatively fast operation
keys[word] = 0;
if (recur(i+1)) return true;
keys[word] = 1; // backtrack: restore key
} else { // Try partial match - relatively slow operation
for (var key in keys) {
if (!keys[key] || word.slice(0, key.length) !== key) continue;
keys[word] = 0;
words[i] = word.slice(key.length);
if (recur(i)) return true;
words[i] = word; // backtrack: restore word
keys[word] = 1; // backtrack: restore key
}
}
return false;
}
return recur(0);
}
var str = "application Name";
var arr = ['nam', 'me', 'applica', 'app', 'lication', 'na'];
console.log(match(str, arr));