一序
本文属于NLP学习笔记系列。
二 纠错case
1 不在词典
2 词没错,但是不适合上下文。
2.1编辑距离
关于文本纠错之编辑距离 这是我之前整理的,项目里面用的。
属于DP经典算法,可以用递归
https://leetcode-cn.com/problems/edit-distance/
为了方便理解:网上找了两个图
初始化:
状态转移过程:
编辑距离的操作:增加字符、删除字符、替换字符。
我们定义一个dp[word1.length() + 1][word2.length() + 1],其中dp[i][j]表示的意思就是,word1前i个字符变成word2前j个字符需要的步数。
那么上面的操作:
假设word1的前i个字符到word2的前j - 1个字符已经处理(也就是说dp[i][j - 1]已经被计算出来了),我们只需要再增加一个word2[j]字符就行,dp[i][j] = dp[i][j - 1] + 1。
以此类推:dp[i ][j] = dp[i - 1][j] + 1,直接删除第i个字符就行了。
而当word1[i] != word2[j]时,当前的dp[i][j] = dp[i - 1][j - 1] + 1,因为我们需要替换当前的字符。相等时跳过。
结果
/**
* dp: dp[i][j]含义 word1 的前i个字符转换到 word2 的前j个字符所需要的步骤
* dp初始化:第一行和第一列对应的值为字符串的长度(默认前面有个空串)
* 状态转移方程:
*/
public static int minDistance(String word1, String word2) {
int m = word1.length();int n = word2.length();
//数组
int[][] dp = new int[m+1][n+1];
//初始化第一列,word2 为空
for(int i=0;i<=m;i++ ){
dp[i][0] = i;
}
//初始化第一行:word1为空
for(int i=0;i<=n;i++ ){
dp[0][i] = i;
}
//状态转移
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
//相同跳过
if(word1.charAt(i-1)== word2.charAt(j-1)){
dp[i][j] = dp[i-1][j-1];
}
else{//分表对应:替换,插入,删除
dp[i][j] = Math.min( dp[i-1][j-1], Math.min(dp[i][j-1] , dp[i-1][j]))+1;
}
}
}
return dp[m][n] ;
}