ETJava Beta | Java    注册   登录
  • 莱文斯坦编辑距离算法

    发表于 2025-12-15 21:06:21     阅读(50)     博客类别:J2SE

    莱文斯坦编辑距离算法(Levenshtein distance)

     

    在做在线考试系统时 遇到了填空与简述题的系统评分问题,使用传统的包含(constant)已经无法满足需求,可以借助Levenshtein distance算法实现简单的匹配

     

    下面是关于Levenshtein distance的简单理解

     

    莱文斯坦编辑距离算法
    举个生活中的例子 🌟
    想象你正在手抄一份文件,但是抄的时候会犯一些小错误。编辑距离就是衡量你需要修改多少次才能让抄错的文本变回原版。
    
    比如原句是:"今天天气真好"
    你抄成了:"今天天气真好啊"
    
    怎么修改?
    
    在"好"后面添加一个"啊"(或者反过来,删除"啊")
    
    编辑距离 = 1(只需要1次操作)
    
    三种基本操作 ✏️
    莱文斯坦距离只允许三种最简单的修改:
    
    插入一个字(多写了一个字)
    
    原句:猫 → 修改后:猫咪(插入了"咪")
    
    删除一个字(少写了一个字)
    
    原句:苹果 → 修改后:苹(删除了"果")
    
    替换一个字(写错了字)
    
    原句:太阳 → 修改后:大阳("太"替换成了"大")
    
    算法怎么"思考"的? 🧠
    算法像一个聪明的校对员,它会把两个文本一个字一个字地对比:
    
    对比 "小猫" 和 "小狗"
    
    text
    步骤1:比较第一个字
    "小" vs "小" → 相同!不需要操作 ✅
    
    步骤2:比较第二个字  
    "猫" vs "狗" → 不同!需要替换 ✏️
    (把"猫"替换成"狗")
    
    总共操作:1次替换
    编辑距离 = 1
    复杂一点的例子 📝
    原句: "我喜欢编程"
    抄错的: "我喜爱写代码"
    
    算法会这样计算:
    
    "我" vs "我" → 相同 ✅
    
    "喜" vs "喜" → 相同 ✅
    
    "欢" vs "爱" → 不同!替换(欢→爱)✏️
    
    "编" vs "写" → 不同!替换(编→写)✏️
    
    "程" vs "代" → 不同!替换(程→代)✏️
    
    (原句结束)vs "码" → 不同!删除"码"(或者说是原句需要插入"码")✏️
    
    编辑距离 = 4(3次替换 + 1次删除/插入)
    
    算法如何选择最佳方案? 🎯
    有时候有多种修改方法,算法会选择操作次数最少的那一种。
    
    比如:
    
    原句:"abcdef"
    
    错句:"azcdef"
    
    两种改法:
    
    替换法:把第二个字'b'替换成'z'(1次操作)
    
    删除+插入法:删除'b',再插入'z'(2次操作)
    
    算法选择第1种,因为只需要1次操作!
    
    在你们系统中的应用 🎯
    用户答案: "Spark需要搭建集群"
    正确答案: "Spark 需要搭建集群"(数据库里有空格)
    
    算法处理:
    
    先去掉所有空格(你们代码里的 removeAllFormatting)
    
    用户答案 → "spark需要搭建集群"
    
    正确答案 → "spark需要搭建集群"
    
    现在两个字串完全一样!
    
    编辑距离 = 0
    
    相似度 = 100%
    
    即使有拼写错误:
    
    用户写:"spakr集群"(拼错了)
    
    正确答案:"spark集群"
    
    编辑距离 = 2(需要:插入'r'、替换'k'为'c')
    相似度 = 1 - 2/10 = 80% → 刚好达到阈值,判为正确!
    
    为什么用80%作为阈值? 📊
    考虑实际情况:
    
    70%太松:"苹果手机" vs "华为手机"(50%相似)可能会误判
    
    90%太严:"Spark集群" vs "Spark 集群"(多一个空格)可能判错
    
    80%刚刚好:允许一些小错误(打错1-2个字),但核心内容要对
    
    就像老师批改简答题:
    
    要点都答到了(相似度>80%)→ ✓ 正确
    
    只答对一半(相似度50%)→ ✗ 错误
    
    完全跑题(相似度<30%)→ ✗ 错误
    
    简单总结 🎁
    莱文斯坦距离 = 把A改成B的最少修改次数
    
    你的系统是这样工作的:
    
    去掉格式(空格、换行都删掉)→ 避免"形式错误"
    
    计算编辑距离 → 看看差了多少字
    
    算相似度 → (1 - 距离/总长度)
    
    判断 → 大于80%就判对
    
    就像一个体贴的助教:
    
    不扣格式分(忽略空格换行)
    
    允许小笔误(错1-2个字没关系)
    
    但核心内容要对(80%以上正确)
    
    这样既严格(保证学习效果)又人性化(不给学生太大压力)!