Я пытаюсь найти оптимальный набор строк для заданной строки.
Данная строка: "FEEJEEDAI"
Значения подстрок:
FE - 1
JE - 2
JEE - 3
AI - 4
DAI - 6
Возможные комбинации:
1) [FE-JE-DAI] - 1 + 2 + 6 = 9
2) [FE-JEE-DAI] - 1 + 3 + 6 = 10
3) [FE-JE-AI] - 1 + 3 + 4 = 8
ОПТИМАЛЬНАЯ КОМБИНАЦИЯ - 2) [FE-JEE-DAI] 10 баллов
Я думаю, что это должно произойти примерно так:
1) проверьте, содержит ли строка определенную подстроку:
var string = "FEEJEEDAI", substring = "JE"; string.indexOf(substring) !== -1;
2) Если true, найдите индекс
var subStringIndex = string.indexOf(substring)
3) Создайте новую tempString для построения комбинации и "обрезания" substring
из string
var tempString = string.slice(subStringIndex, substring.length)
4) Итерацию через string
и поиск оптимальной tempString
Я не знаю, как построить его в цикле и обрабатывать ситуацию. JE против JEE, AI против DAI
В принципе, вы можете использовать итеративный и рекурсивный подход для получения всех возможных подстрок строки.
Это решение разделено на 3 части
В начале все подстроки строки собираются в объекте indices
. Ключ - это индекс, а значение - это объект с лимитом, который является наименьшей длиной строк в массиве шаблонов. Массив шаблона содержит индекс и найденные подстроки, начинающиеся с этого индекса.
indices
объекта из первого примера{ 0: { limit: 2, pattern: [ { index: 0, string: "FE" } ] }, 3: { limit: 2, pattern: [ { index: 3, string: "JE" }, { index: 3, string: "JEE" } ] }, /* ... */ }
Основная идея - начать с нуля индекса с пустым массивом для сбора подстрок.
Чтобы проверить, какие части находятся вместе в группе, вам нужно получить первую подстроку с заданным индексом или ближайшим рядом, затем взять свойство limit, которое является длиной самой короткой подстроки, добавить индекс и принять его как максимальный индекс для поиска членов группы.
Из второго примера первая группа состоит из
'FE'
,'EE'
и'EEJ'
string comment ---------- ------------------------------------- 01 2345678 indices FE|EJEEDAI FE| matching pattern FE at position 0 E|E matching pattern EE at position 1 E|EJ matching pattern EEJ at position 1 ^^ all starting substrings are in the same group
С этой группой вызывается новая рекурсия с скорректированным индексом и подстрокой, объединенной с массивом деталей.
Если не найдено больше подстроки, детали объединяются, и счет рассчитывается и помещается в результирующий набор.
Интерпретация результата
[ { parts: "0|FE|3|JE|6|DAI", score: 9 }, /* ... */ ]
parts
представляют собой комбинацию индексов и соответствующих строк в позиции0|FE|3|JE|6|DAI ^ ^^ at index 0 found FE ^ ^^ at index 3 found JE ^ ^^^ at index 6 found DAI
score
рассчитывается с заданными весами подстрокsubstring weight --------- ------ FE 1 JE 2 DAI 6 --------- ------ score 9
В примере три возвращает 11 уникальных комбинаций.
function getParts(string, weights) {
function collectParts(index, parts) {
var group, limit;
while (index < string.length && !indices[index]) {
index++;
}
if (indices[index]) {
group = indices[index].pattern;
limit = index + indices[index].limit;
while (++index < limit) {
if (indices[index]) {
group = group.concat(indices[index].pattern);
}
}
group.forEach(function (o) {
collectParts(o.index + o.string.length, parts.concat(o.index, o.string));
});
return;
}
result.push({
parts: parts.join('|'),
score: parts.reduce(function (score, part) { return score + (weights[part] || 0); }, 0)
});
}
var indices = {},
pattern,
result = [];
Object.keys(weights).forEach(function (k) {
var p = string.indexOf(k);
while (p !== -1) {
pattern = { index: p, string: k };
if (indices[p]) {
indices[p].pattern.push(pattern);
if (indices[p].limit > k.length) {
indices[p].limit = k.length;
}
} else {
indices[p] = { limit: k.length, pattern: [pattern] };
}
p = string.indexOf(k, p + 1);
}
});
collectParts(0, []);
return result;
}
console.log(getParts("FEEJEEDAI", { FE: 1, JE: 2, JEE: 3, AI: 4, DAI: 6 }));
console.log(getParts("FEEJEEDAI", { FE: 1, JE: 2, JEE: 3, AI: 4, DAI: 6, EEJ: 5, EJE: 3, EE: 1 }));
console.log(getParts("EEEEEE", { EE: 2, EEE: 3 }));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Если вы вырезаете подстроку, когда найдете их, так как некоторые подстроки являются подстроками других подстрок, сначала найдите самые большие. Например, если вы не нашли DAI, и вы найдете AI, это не может быть частью DAI. Вы хотите протестировать каждую подстроку, чтобы вы могли поместить каждую подстроку в массив и петлю через массив.