数据结构与算法专题——第四题 字符串相似度
這篇我們看看?最長公共子序列?的另一個版本,求字符串相似度(編輯距離),我也說過了,這是一個非常實用的算法,在DNA對比,網頁聚類等方面都有用武之地。
一:概念
對于兩個字符串 A 和 B,通過基本的增刪改將字符串 A 改成 B,或者將 B 改成 A,在改變的過程中使用的最少步驟稱之為:?編輯距離。比如如下的字符串:我們通過種種操作,痙攣之后編輯距離為3,不知道你看出來了沒有?
二:解析
可能大家覺得有點復雜,不好理解,我試著把這個大問題拆分掉,將?字符串 vs 字符串,分解成?字符 vs 字符串,再分解成字符 vs 字符。
1. 字符 vs 字符
這種情況是最簡單的了,比如 A 與 B 的編輯距離很顯然是1。
2. 字符 vs 字符串
A 改成 AB 的編輯距離為1,A 與 ABA 的編輯距離為2。
3. 字符串 vs 字符串
ABA 和 BBA 的編輯距離為1,仔細發現可以得出如下結論,ABA 是由2^3個子序列與 BBA 字符串求的的編輯距離集合中取出的最小編輯距離,也就是說在這種情況下我們出現了重復計算的情況,我在求子序列 AB 和 BBA 的編輯距離時,我是由子序列 A 和 BBA 與 B 和 BBA 之間的編輯距離中選出一個最小值,然而序列A和序列B早之前我已經計算過了,這種重復計算的問題有點像?斐波那契,正好滿足動態規劃中的最優子結構和重疊子問題,所以我決定采用動態規劃來解決。
三:公式
跟最長公共子序列一樣,可以采用一個二維數組來保存字符串 X 和 Y 當前的位置的最小編輯距離。現有兩個序列X={x1,x2,x3,...xi},Y={y1,y2,y3,....,yi}。
設一個C[i,j]: 保存Xi與Yj的當前最小的LD。
1. 當 Xi = Yi 時,則C[i,j]=C[i-1,j-1];
2. 當 Xi != Yi 時, 則C[i,j]=Min{C[i-1,j-1],C[i-1,j],C[i,j-1]};
最終我們的C[i,j]一直保存著最小的LD。
四:代碼
using System;namespace ConsoleApplication2 {public class Program{static int[,] martix;static string str1 = string.Empty;static string str2 = string.Empty;static void Main(string[] args){while (true){str1 = Console.ReadLine();str2 = Console.ReadLine();martix = new int[str1.Length + 1, str2.Length + 1];Console.WriteLine("字符串 {0} 和 {1} 的編輯距離為:{2}\n", str1, str2, LD());}}/// <summary>/// 計算字符串的編輯距離/// </summary>/// <returns></returns>public static int LD(){//初始化邊界值(忽略計算時的邊界情況)for (int i = 0; i <= str1.Length; i++){martix[i, 0] = i;}for (int j = 0; j <= str2.Length; j++){martix[0, j] = j;}//矩陣的 X 坐標for (int i = 1; i <= str1.Length; i++){//矩陣的 Y 坐標for (int j = 1; j <= str2.Length; j++){//相等情況if (str1[i - 1] == str2[j - 1]){martix[i, j] = martix[i - 1, j - 1];}else{//取“左前方”,“上方”,“左方“的最小值var temp1 = Math.Min(martix[i - 1, j], martix[i, j - 1]);//獲取最小值var min = Math.Min(temp1, martix[i - 1, j - 1]);martix[i, j] = min + 1;}}}//返回字符串的編輯距離return martix[str1.Length, str2.Length];}} }總結
以上是生活随笔為你收集整理的数据结构与算法专题——第四题 字符串相似度的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: BeetleX.FastHttpApi之
- 下一篇: 三分钟学会.NET Core Jwt 策