Hrbust-1284 編輯距離【LCS最長公共子序列】 / leetcode 72.編輯距離

編輯距離
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]
                    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章