簡體   English   中英

查找給定字符串中的最佳子字符串集

[英]Find optimal set of substrings in given string

我試圖找到給定字符串的最佳字符串集。

給定的字符串:“ FEEJEEDAI”

子字符串值:

FE-1
JE-2
傑-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)如果為真找到它的索引

var subStringIndex = string.indexOf(substring)

3)創建新的tempString來構建組合並從string “切斷” substring string

var tempString = string.slice(subStringIndex, substring.length)

4)遍歷string並找到最佳的tempString

我不知道如何將其構建為循環並處理情況JE,JEE,AI與DAI

基本上,您可以使用迭代和遞歸的方法來獲取字符串的所有可能的子字符串。

此解決方案分為3部分

  1. 制備
  2. 收集零件
  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數組中。

計算分數並創建結果集

如果找不到更多的子字符串,則將零件合並,計算分數並將其推入結果集。

解釋結果

  [ { 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的一部分。 您要測試每個子字符串,因此可以將每個子字符串放入數組中並遍歷該數組。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM