You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 13:05:17