編輯距離
Time Limit: 1000 MS Memory Limit: 65536 K
Total Submit: 937(198 users) Total Accepted: 373(190 users) Rating: Special Judge: No
Description
俄羅斯科學家Vladimir
Levenshtein在1965年提出了編輯距離概念。編輯距離,又稱Levenshtein距離,是指兩個字符串之間,由一個轉成另一個所需的最少編輯操作次數。許可的三種編輯操作包括插入一個字符、刪除一個字符、將一個字符替換成另一個字符。
至今,編輯距離一直在相似句子檢索的領域中發揮着不可忽視的作用。
我們不妨來設計一個程序,計算兩個字符串的編輯距離。
Input
輸入數據的第一行是一個正整數,表示一共有幾組數據。
每組數據有兩行,每行一個字符串。
- 每個字符串長度不超過1000
- 字符串中只含小寫英文字母
Output
對於每組數據,請輸出一個整數表示兩個字符串的編輯距離。
每個答案佔一行。
Sample Input
2
david
vivian
abc
aabbcc
Sample Output
4
3
思路: LCS最長公共子序列模板題,利用動態規劃,按順序對比字符,分三種情況,若a串當前字符與b串當前字符相等,那麼直接從前一個字符繼承修改次數,否則選擇刪去該字符或替換該字符,或增加該字符,刪除和增加是相對於a串或b串而言的,因此分別從兩串的上一狀態+1來繼承並延續修改次數,對於當前字符,選擇最小的一種修改方式賦值,用於構造最終最優解。
#include<stdio.h>///最長公共子序列
#include<string.h>
#include<algorithm>
using namespace std;
int dp[1008][1009],i,j,t;
int main()
{
char x[1005];
char y[1004];
scanf("%d",&t);
while(t--)
{
scanf("%s %s",x+1,y+1);//爲方便對數組中每個位置的元素計數,輸入字符串從首地址位置+1開始
int lx=strlen(x+1);
int ly=strlen(y+1);
for(i=1;i<=lx;i++)
dp[i][0]=i;//第幾個字符就是和0位相比,增添幾次,所以次數剛好是字符的位置編號
for(i=1;i<=ly;i++)
dp[0][i]=i;
dp[0][0]=0;//初始值都是爲0
for(i=1;i<=lx;i++)
{
for(int j=1;j<=ly;j++)//動態規劃,一個一個字符比較,若相同,則繼承之前的次數,不同,則從三種變換中篩選最優解
{
if(x[i]==y[j])//一直累加到最後是最終變化結果
dp[i][j]=dp[i-1][j-1];//繼承
else
dp[i][j]=dp[i-1][j-1]+1;//變換
dp[i][j]=min(dp[i-1][j]+1,min(dp[i][j],dp[i][j-1]+1));//三種情況,插入(增加)、刪減、變換,從中取最優解(改變次數最少的)
// dp[i][j]=min(dp[i][j-1]+1,dp[i][j]);
}
}
printf("%d\n",dp[lx][ly]);
}
return 0;
}
class Solution:
def minDistance(self, word1: str, word2: str) -> int:
str1=len(word1)
str2=len(word2)
dp = [[0 for i in range(str1+1)] for j in range(str2+1)]
for i in range(1,str1+1):
dp[0][i]=i
for i in range(1,str2+1):
dp[i][0]=i
dp[0][0]=0
for i in range(1,str2+1):
for j in range(1,str1+1):
dp[i][j] = dp[i-1][j-1] if word2[i-1]==word1[j-1] else dp[i-1][j-1]+1
dp[i][j] = min(dp[i-1][j]+1, min(dp[i][j],dp[i][j-1]+1))
return dp[str2][str1]