修复了大量存在的问题,增加了假鸭子类型等等机制

This commit is contained in:
2026-06-25 14:49:46 +08:00
parent 19f2787db0
commit d88d11b646
827 changed files with 32617 additions and 18316 deletions

View File

@@ -1,3 +1,5 @@
from __future__ import annotations
def LevenshteinDistance(s1: str, s2: str) -> int:
"""
计算两个字符串的 Levenshtein 距离(编辑距离)
@@ -6,13 +8,17 @@ def LevenshteinDistance(s1: str, s2: str) -> int:
:return: 最少编辑操作次数(差异程度)
"""
# 创建二维动态规划表dp[i][j] 表示 s1[:i] 到 s2[:j] 的编辑距离
m: int
n: int
m, n = len(s1), len(s2)
dp = [[0] * (n + 1) for _ in range(m + 1)]
dp: list[list[int]] = [[0] * (n + 1) for _ in range(m + 1)]
# 初始化:空字符串到 s1[:i] 需要 i 次删除操作
i: int
for i in range(m + 1):
dp[i][0] = i
# 初始化:空字符串到 s2[:j] 需要 j 次插入操作
j: int
for j in range(n + 1):
dp[0][j] = j
@@ -39,11 +45,15 @@ def LongestCommonSubsequence(s1: str, s2: str) -> tuple[list[tuple[int, int]], s
:param s2: 目标字符串
:return: (LCS 位置列表 [(S1Idx, S2Idx)], LCS 字符串)
"""
m: int
n: int
m, n = len(s1), len(s2)
# dp[i][j] 表示 s1[:i] 和 s2[:j] 的 LCS 长度
dp = [[0] * (n + 1) for _ in range(m + 1)]
dp: list[list[int]] = [[0] * (n + 1) for _ in range(m + 1)]
# 填充 LCS 长度表
i: int
j: int
for i in range(1, m + 1):
for j in range(1, n + 1):
if s1[i-1] == s2[j-1]:
@@ -52,8 +62,8 @@ def LongestCommonSubsequence(s1: str, s2: str) -> tuple[list[tuple[int, int]], s
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
# 回溯找 LCS 的具体字符和位置
LcsChars = []
LcsPositions = []
LcsChars: list[str] = []
LcsPositions: list[tuple[int, int]] = []
i, j = m, n
while i > 0 and j > 0:
if s1[i-1] == s2[j-1]:
@@ -72,7 +82,7 @@ def LongestCommonSubsequence(s1: str, s2: str) -> tuple[list[tuple[int, int]], s
return LcsPositions, ''.join(LcsChars)
def GetStringDiff(s1: str, s2: str) -> dict:
def GetStringDiff(s1: str, s2: str) -> dict[str, int | float | str | dict[str, list[tuple[int, str] | tuple[int, str, str]]]]:
"""
完整对比两个字符串,返回差异详情
:param s1: 原始字符串
@@ -80,20 +90,24 @@ def GetStringDiff(s1: str, s2: str) -> dict:
:return: 差异字典包含编辑距离、LCS、差异位置/内容)
"""
# 1. 计算编辑距离(差异程度)
EditDist = LevenshteinDistance(s1, s2)
EditDist: int = LevenshteinDistance(s1, s2)
# 2. 计算 LCS公共部分
LcsPos: list[tuple[int, int]]
LcsStr: str
LcsPos, LcsStr = LongestCommonSubsequence(s1, s2)
# 3. 定位差异位置和内容
DiffDetails = {
DiffDetails: dict[str, list] = {
"delete": [], # s1 中需要删除的字符 (索引, 字符)
"insert": [], # s2 中需要插入的字符 (索引, 字符)
"replace": [] # s1 中需要替换的字符 (s1索引, 原字符, 目标字符)
}
# 生成 s1 和 s2 的差异标记
S1Idx = 0
S2Idx = 0
S1Idx: int = 0
S2Idx: int = 0
LcsS1Idx: int
LcsS2Idx: int
for (LcsS1Idx, LcsS2Idx) in LcsPos:
# 处理 s1 中需要删除的字符LCS 前的非公共部分)
while S1Idx < LcsS1Idx:
@@ -116,7 +130,13 @@ def GetStringDiff(s1: str, s2: str) -> dict:
S2Idx += 1
# 优化:将连续的删除+插入合并为替换(更符合直观)
ReplaceCandidates = list(zip(DiffDetails["delete"], DiffDetails["insert"]))
ReplaceCandidates: list[tuple[tuple[int, str], tuple[int, str]]] = list(zip(DiffDetails["delete"], DiffDetails["insert"]))
DelItem: tuple[int, str]
InsItem: tuple[int, str]
DelIdx: int
DelChar: str
InsIdx: int
InsChar: str
for (DelItem, InsItem) in ReplaceCandidates:
DelIdx, DelChar = DelItem
InsIdx, InsChar = InsItem
@@ -136,9 +156,9 @@ def GetStringDiff(s1: str, s2: str) -> dict:
# 测试用例
if __name__ == "__main__":
# 示例1轻微差异替换+插入)
s1 = "Hello World!"
s2 = "Hello Python!"
DiffResult = GetStringDiff(s1, s2)
s1: str = "Hello World!"
s2: str = "Hello Python!"
DiffResult: dict = GetStringDiff(s1, s2)
print("=== 示例1轻微差异 ===")
print(f"编辑距离:{DiffResult['EditDistance']}")
print(f"相似度:{DiffResult['similarity']:.2f}")
@@ -146,9 +166,9 @@ if __name__ == "__main__":
print(f"差异详情:{DiffResult['DiffDetails']}")
# 示例2完全不同
s3 = "abc123"
s4 = "xyz789"
DiffResult2 = GetStringDiff(s3, s4)
s3: str = "abc123"
s4: str = "xyz789"
DiffResult2: dict = GetStringDiff(s3, s4)
print("\n=== 示例2完全不同 ===")
print(f"编辑距离:{DiffResult2['EditDistance']}")
print(f"相似度:{DiffResult2['similarity']:.2f}")
@@ -156,9 +176,9 @@ if __name__ == "__main__":
print(f"差异详情:{DiffResult2['DiffDetails']}")
# 示例3内容一致
s5 = "TestString"
s6 = "TestString"
DiffResult3 = GetStringDiff(s5, s6)
s5: str = "TestString"
s6: str = "TestString"
DiffResult3: dict = GetStringDiff(s5, s6)
print("\n=== 示例3内容一致 ===")
print(f"编辑距离:{DiffResult3['EditDistance']}")
print(f"相似度:{DiffResult3['similarity']:.2f}")