基于LCS算法高亮差异单词失效求助:下划线无法显示
问题:LCS算法实现差异单词下划线失效排查
我正在学习HTML、CSS、JavaScript,尝试使用LCS(最长公共子序列)算法为变量X与Y之间的差异单词添加下划线,但无法正常显示下划线效果。以下是我的核心JS代码,对应的HTML和CSS代码可按需提供,恳请各位帮忙排查问题。
const leftText = document.getElementById("text-input"); const gearButton = document.querySelector("#gear-button"); gearButton.addEventListener("click", function() { let X = leftText.value; let Y = "Die Deutsche Sprache"; displayDifferences(X, Y) }); // The LCS (Longest Common Subsequence) Algorithm function lcs(a, b) { return lcs; } // Function to display the differences function displayDifferences(left, right) { const leftParagraphs = left.split(" "); const rightParagraphs = right.split(" "); leftParagraphs.forEach((leftParagraph, index) => { const rightParagraph = rightParagraphs[index]; const leftWords = leftParagraph.split(" "); const rightWords = rightParagraph.split(" "); const common = lcs(leftWords, rightWords); let leftIndex = 0; let rightIndex = 0; for (let i = 0; i < common.length; i++) { while (leftWords[leftIndex] !== common[i]) { leftText.innerHTML += `<span class="underlined">${leftWords[leftIndex]} </span>`; leftIndex++; } while (rightWords[rightIndex] !== common[i]) { rightIndex++; } leftText.innerHTML += `<span class="unchanged">${leftWords[leftIndex]} </span>`; leftIndex++; rightIndex++; } while (leftIndex < leftWords.length) { leftText.innerHTML += `<span class="underlined">${leftWords[leftIndex]} </span>`; leftIndex++; } while (rightIndex < rightWords.length) { rightIndex++; } leftText.innerHTML += "<br />"; }); }
问题排查与修复方案
1. LCS函数未实现(核心问题)
你的lcs函数直接返回自身,没有实际计算最长公共子序列。这会导致common变量是函数对象而非数组,后续循环无法执行,自然不会生成带下划线的元素。
修复:实现正确的LCS动态规划算法
function lcs(a, b) { const m = a.length; const n = b.length; // 创建DP表,存储子问题的解 const dp = Array(m + 1).fill().map(() => Array(n + 1).fill(0)); // 填充DP表 for (let i = 1; i <= m; i++) { for (let j = 1; j <= n; j++) { if (a[i - 1] === b[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]); } } } // 回溯获取LCS结果 let i = m, j = n; const result = []; while (i > 0 && j > 0) { if (a[i - 1] === b[j - 1]) { result.unshift(a[i - 1]); i--; j--; } else if (dp[i - 1][j] > dp[i][j - 1]) { i--; } else { j--; } } return result; }
2. 其他潜在问题修复
- 清空原有内容:每次点击按钮时,先清空
leftText的innerHTML,避免重复追加内容 - 正确分割换行:原代码中
split(" ")是无效的,改为split("\n")来按换行符分割段落 - 处理空白字符:单词分割用
split(/\s+/)并过滤空字符串,避免连续空格生成空单词 - 检查CSS样式:确保
.underlined类正确设置下划线样式,比如:
.underlined { text-decoration: underline red; /* 可自定义颜色和样式 */ } .unchanged { text-decoration: none; }
修复后的完整displayDifferences函数
function displayDifferences(left, right) { // 先清空原有内容 leftText.innerHTML = ""; const leftParagraphs = left.split("\n"); const rightParagraphs = right.split("\n"); leftParagraphs.forEach((leftParagraph, index) => { const rightParagraph = rightParagraphs[index] || ""; // 分割单词并过滤空字符串 const leftWords = leftParagraph.split(/\s+/).filter(word => word); const rightWords = rightParagraph.split(/\s+/).filter(word => word); const common = lcs(leftWords, rightWords); let leftIndex = 0; let rightIndex = 0; for (let i = 0; i < common.length; i++) { // 标记左侧差异单词 while (leftIndex < leftWords.length && leftWords[leftIndex] !== common[i]) { leftText.innerHTML += `<span class="underlined">${leftWords[leftIndex]} </span>`; leftIndex++; } // 跳过右侧差异单词 while (rightIndex < rightWords.length && rightWords[rightIndex] !== common[i]) { rightIndex++; } // 标记相同单词 if (leftIndex < leftWords.length) { leftText.innerHTML += `<span class="unchanged">${leftWords[leftIndex]} </span>`; leftIndex++; rightIndex++; } } // 处理左侧剩余的差异单词 while (leftIndex < leftWords.length) { leftText.innerHTML += `<span class="underlined">${leftWords[leftIndex]} </span>`; leftIndex++; } leftText.innerHTML += "<br />"; }); }
内容的提问来源于stack exchange,提问作者Dexter
相关产品推荐
相关产品推荐

