題目描述:也就是給乙個源串和目標串,計算最少的運算元,使得源串進行下列操作之後等於目標串。
1、在給定的位置插入字元
2、將當前字元替換成任意字元
3、刪除任意字元
題目分析:
如果當前兩個字元相等,則結果就是src+1和pattern+1兩個字串的最小運算元。
如果不等,就分三種情況:
1、如果是在給定的位置插入字元,那要求的運算元就是src和pattern+1兩個字串的最小運算元
2、如果將當前字元替換,那要求的運算元就是src+1和pattern+1兩個字串的最小運算元3、如果是刪除src的當前字元,則要求的運算元就是src+1和pattern兩個字串的最小運算元
最終結果就是上面三種情況中最小的運算元+1.
遞迴解法:程式很容易就可以寫出來,遞迴的出口就是某乙個字串到達串尾,則距離就是沒有到達串尾的那個字串的長度。
非遞迴的解法:就是動態規劃,假設dp[i][j]表示src從第i個字元開始與pattern從第j個字元開始所求得的最小運算元,動態規劃遞推的式子如下:
if src[i] != pattern[j], dp[i][j] = min(dp[i][j + 1], dp[i + 1][j + 1], dp[i +1][j];
else, dp[i][j] = dp[i + 1][j + 1];
使用動態規劃需要注意的地方:
1、遞推式中只出現了後面的資料,所以遞推的時候應該是從後到前。
2、注意遞推時的邊界條件的處理。
核心參考**如下:
//遞迴解法
int calstr(const char* src, const char *pattern)
if(*pattern == '\0')
if(*src == *pattern)
int t1 = calstr(src, pattern + 1);//插入字元
int t2 = calstr(src + 1, pattern + 1);//替換字元
int t3 = calstr(src + 1, pattern);//刪除字元
return min(t1, t2, t3) + 1;
} //非遞迴解法,動態規劃
int calstrdp(const char *src, const char *pattern)
else
if(j + 1 >= nlen2)//設定邊界值
} dp[i][j] = min(dp[i][j + 1], dp[i + 1][j + 1], dp[i + 1][j]) + 1;
} }
} return dp[0][0];
}下面給出main函式和輔助函式:
#include
#include
#include
const int max_n = 100;
int dp[max_n][max_n];
inline int min(const int a, const int b, const int c)
int main()
return 0;
}
程式設計之美 計算字串的相似度
把兩個字串變成相同的基本操作定義如下 1.修改乙個字元 如把 a 變成 b 2.增加乙個字元 如 abed 變成 abedd 3.刪除乙個字元 如 jackbllog 變成 jackblog 針對於 jackbllog到jackblog 只需要刪除乙個或增加乙個 l 就可以把兩個字串變為相同。把這種...
程式設計之美3 3 計算字串的相似度
問題 1.計算兩個字串的最長公共子串行 lcs 且公共子串行在字串中不需要是連續的。2.計算兩個字串的距離,完全相同的字串距離為0,可以通過修改乙個字元 增加乙個字元或刪除乙個字元三種方式來使兩個字串相同,但這些方式會使得距離加1。1.解法 這兩個問題的解法基本相同,都是二維的動態規劃,都考慮字串的...
程式設計之美 3 3 計算字串的相似度
1.簡述 使用兩個字串之間的編輯距離計算它們的相似度,相似度 1 編輯距離 1 兩個字串的編輯距離 指通過下面三種操作可以將兩個字串變為相同的字串需要的次數。1 修改乙個字元 2 增加乙個字元 3 刪除乙個字元。對於 abcdefg 和 abcdef 兩個字串來說,我們認為可以通過增加 減少乙個 g...