如何从含重复值的两个数组中提取所有差异并避免误判?
原代码的核心逻辑缺陷
- 错误将「同一词汇在bluff遍历过程中重复出现」作为编辑内容判定条件。只要词汇在之前的遍历步骤中出现过,后续同文本词汇会被强制标记为bluff,完全忽略原句本身存在重复词汇的场景。示例中bluff第6位的"sun"、第7位的"is",因为和前面已出现的同文本词汇重复,被直接误判为编辑内容。
- 仅做集合层面的词汇存在性判断,未考虑文本的顺序对应关系。文本编辑是连续顺序序列的差异,单个词是否在原句全量集合中出现过,不代表当前位置的内容没有被修改。
- 附带分词偏差:示例中原句的"clear.the"因为缺少句号后的空格,被识别为单个词汇,原句中本该存在的第二个小写"the"没有被正确拆分,进一步触发了存在性判断的误判。
最优实现方案
核心采用单词粒度的最长公共子序列(LCS)算法,匹配原句和编辑后句子中顺序对应、文本完全一致的部分。算法天然兼容重复词汇的匹配场景,不会出现乱配对重复词、重复出现的词一律标记为编辑内容的问题。
实现逻辑:
- 分别对原句和编辑后句子做空格分词,过滤空字符串,保留和原逻辑一致的分词规则(即标点和相邻词汇绑定为整体)。
- 基于两个分词数组生成LCS动态规划表,回溯得到两个数组中互相匹配的位置对。
- 遍历编辑后句子的每个词汇位置:如果该位置在匹配的位置对集合中,标记为非bluff(未修改),否则标记为bluff(修改内容)。
代码实现
// 修正原句的分词偏差,在clear.后补充书面语默认的空格分隔 let original = "The sun is clear. the sun is yellow".split(" ").filter(w => w.length > 0); let bluff = "The sun is very bad. the sun is white".split(" ").filter(w => w.length > 0); // 生成LCS动态规划表 const dp = Array(original.length + 1).fill(0).map(() => Array(bluff.length + 1).fill(0)); for (let i = 1; i <= original.length; i++) { for (let j = 1; j <= bluff.length; j++) { if (original[i-1] === bluff[j-1]) { dp[i][j] = dp[i-1][j-1] + 1; } else { dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]); } } } // 回溯得到所有匹配上的bluff位置 const matchedPositions = new Set(); let i = original.length, j = bluff.length; while (i > 0 && j > 0) { if (original[i-1] === bluff[j-1]) { matchedPositions.add(j-1); i--; j--; } else if (dp[i-1][j] > dp[i][j-1]) { i--; } else { j--; } } // 生成最终的标记结果 const words = bluff.map((word, index) => ({ text: word, index, isBluff: !matchedPositions.has(index) }));
输出结果(和预期完全一致)
[ {text: "The", index: 0, isBluff: false}, {text: "sun", index: 1, isBluff: false}, {text: "is", index: 2, isBluff: false}, {text: "very", index: 3, isBluff: true}, {text: "bad.", index: 4, isBluff: true}, {text: "the", index: 5, isBluff: false}, {text: "sun", index: 6, isBluff: false}, {text: "is", index: 7, isBluff: false}, {text: "white", index: 8, isBluff: true} ]
可扩展调整说明
- 如需忽略大小写匹配,可在词汇比较环节统一转为小写/大写再判断,默认保持精确匹配更符合真实编辑场景(用户刻意调整大小写本身属于独立编辑内容)。
- 如需支持更复杂的分词规则(比如标点单独拆分、连写标点的拆分),只需要替换分词环节的逻辑,后续LCS匹配流程无需改动。
- 该方案的匹配规则完全基于文本的顺序对应关系,哪怕同一词汇在句子中出现十次,只要顺序上能和原句的词汇一一对应,就不会被误判为修改内容,完全兼容重复词汇的场景。
内容的提问来源于stack exchange,提问作者EmilTayeb
相关产品推荐
相关产品推荐

