题意整理。
- 输入两个字符串,求它们之间的编辑距离。
- Levenshtein 距离,又称编辑距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。
方法一(动态规划)
1.解题思路
- 状态定义:表示字符串A长度为i,字符串B长度为j时,对应的编辑距离。
- 状态初始化:其中一个字符串为空时,编辑距离为另一个字符串的长度。即。
- 状态转移:如果当前字符相等,直接等于前一个位置的情况。即。如果不相等,要么s1字符串插入s2中j位置对应字符即,要么s2字符串插入s1中i位置对应字符即,要么s1字符串i位置字符被s2字符串j位置字符替换,即。
图解展示:
2.代码实现
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
//输入字符串A
String s1=sc.next();
//输入字符串B
String s2=sc.next();
//计算字符串A和字符串B的距离
System.out.println(distance(s1,s2));
}
}
private static int distance(String s1,String s2){
int m=s1.length();
int n=s2.length();
//定义dp数组
int[][] dp=new int[m+1][n+1];
//状态初始化
for(int i=1;i<=m;i++){
dp[i][0]=i;
}
for(int j=1;j<=n;j++){
dp[0][j]=j;
}
//状态转移
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
//如果相等,直接等于前一个位置的情况
if(s1.charAt(i-1)==s2.charAt(j-1)){
dp[i][j]=dp[i-1][j-1];
}
/*
如果不相等,要么B字符串插入A中i位置对应字符即dp[i][j]=dp[i-1][j]+1
要么A字符串插入B中j位置对应字符即dp[i][j]=dp[i][j-1]+1,要么s1字符串
i位置字符被s2字符串j位置字符替换,即dp[i][j]=dp[i-1][j-1]+1
*/
else{
dp[i][j]=Math.min(Math.min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;
}
}
}
return dp[m][n];
}
}
3.复杂度分析
- 时间复杂度:两层循环,最多执行次,所以时间复杂度为。
- 空间复杂度:需要额外大小为的空间,所以空间复杂度为。
方法二(利用io操作)
1.解题思路
与方法一的思路基本一致,不过使用io操作来处理输入数据。
2.代码实现
import java.io.*;
public class Main{
public static void main(String[] args) throws IOException{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String s1,s2;
//输入字符串A和B
while((s1=br.readLine())!=null){
s2=br.readLine();
//计算字符串A和字符串B的距离
System.out.println(distance(s1,s2));
}
}
private static int distance(String s1,String s2){
int m=s1.length();
int n=s2.length();
//定义dp数组
int[][] dp=new int[m+1][n+1];
//状态初始化
for(int i=1;i<=m;i++){
dp[i][0]=i;
}
for(int j=1;j<=n;j++){
dp[0][j]=j;
}
//状态转移
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
//如果相等,直接等于前一个位置的情况
if(s1.charAt(i-1)==s2.charAt(j-1)){
dp[i][j]=dp[i-1][j-1];
}
/*
如果不相等,要么B字符串插入A中i位置对应字符即dp[i][j]=dp[i-1][j]+1
要么A字符串插入B中j位置对应字符即dp[i][j]=dp[i][j-1]+1,要么s1字符串
i位置字符被s2字符串j位置字符替换,即dp[i][j]=dp[i-1][j-1]+1
*/
else{
dp[i][j]=Math.min(Math.min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;
}
}
}
return dp[m][n];
}
}
3.复杂度分析
- 时间复杂度:两层循环,最多执行次,所以时间复杂度为。
- 空间复杂度:需要额外大小为的空间,所以空间复杂度为。