<template>
<div class="compare-container">
<div class="input-area">
<el-input
type="textarea"
v-model="text1"
placeholder="请输入第一段文本"
:autosize="{ minRows: 10, maxRows: 10 }"
></el-input>
<el-input
type="textarea"
v-model="text2"
placeholder="请输入第二段文本"
:autosize="{ minRows: 10, maxRows: 10 }"
></el-input>
</div>
<div class="button-area">
<el-button type="primary" @click="compare" size="small"
>比较文本</el-button
>
<el-button @click="reset" size="small">重置</el-button>
</div>
<div class="input-area">
<div
v-html="diffResult1"
class="text-display"
v-if="diffResult1"
></div>
<div
v-html="diffResult2"
class="text-display"
v-if="diffResult2"
></div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
text1: "",
text2: "",
diffResult1: "",
diffResult2: "",
};
},
methods: {
compare() {
if (!this.text1 || !this.text2) {
this.$message.warning("请输入需要比较的文本");
return;
}
const text1Arr = this.text1.split("");
const text2Arr = this.text2.split("");
let result1 = "";
let result2 = "";
// 使用动态规划找到最长公共子序列
// 调用findLCS方法计算两段文本的最长公共子序列(Longest Common Subsequence)
// 这个方法会返回两段文本中相同的字符序列
// 例如 text1="ABCD", text2="ACBD", 最长公共子序列为"ABD"
const lcs = this.findLCS(this.text1, this.text2);
// 根据最长公共子序列标记差异
let lcsIndex = 0;
let i = 0,
j = 0;
while (i < text1Arr.length || j < text2Arr.length) {
if (
i < text1Arr.length &&
j < text2Arr.length &&
lcsIndex < lcs.length &&
text1Arr[i] === lcs[lcsIndex] &&
text2Arr[j] === lcs[lcsIndex]
) {
// 相同字符
result1 += text1Arr[i];
result2 += text2Arr[j];
i++;
j++;
lcsIndex++;
} else {
// 差异字符
if (
i < text1Arr.length &&
(lcsIndex >= lcs.length ||
text1Arr[i] !== lcs[lcsIndex])
) {
result1 += `<span style="background-color: #ffd700">${text1Arr[i]}</span>`;
i++;
}
if (
j < text2Arr.length &&
(lcsIndex >= lcs.length ||
text2Arr[j] !== lcs[lcsIndex])
) {
result2 += `<span style="background-color: #ffd700">${text2Arr[j]}</span>`;
j++;
}
}
}
this.diffResult1 = result1;
this.diffResult2 = result2;
},
// 计算最长公共子序列
findLCS(text1, text2) {
const m = text1.length;
const n = text2.length;
const dp = Array(m + 1)
.fill()
.map(() => Array(n + 1).fill(""));
for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
if (text1[i - 1] === text2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + text1[i - 1];
} else {
dp[i][j] =
dp[i - 1][j].length > dp[i][j - 1].length
? dp[i - 1][j]
: dp[i][j - 1];
}
}
}
return dp[m][n];
},
reset() {
this.text1 = "";
this.text2 = "";
this.diffResult1 = "";
this.diffResult2 = "";
},
},
};
</script>
<style scoped>
.compare-container {
padding: 20px;
}
.input-area {
display: flex;
gap: 20px;
margin-bottom: 20px;
}
.button-area {
margin-bottom: 20px;
text-align: center;
}
.result-area {
padding: 10px;
border: 1px solid #dcdfe6;
border-radius: 4px;
min-height: 100px;
line-height: 1.5;
}
.text-display {
width: 100%;
min-height: 100px;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 5px 15px;
line-height: 1.5;
white-space: pre-wrap;
color: #606266;
font-size: 14px;
font-family: monospace;
}
</style>