字串相似度之編輯距離演算法

2021-08-18 13:34:01 字數 3636 閱讀 7439

字串編輯距離:是一種字串之間相似度計算的方法。給定兩個字串s、t,將s轉換成t所需要的刪除,插入,替換操作的數量就叫做s到t的編輯路徑。而最短的編輯路徑就叫做字串s和t的編輯距離。

舉個例子:s=「eeba」   t="abac"   我們可以按照這樣的步驟轉變:(1) 將s中的第乙個e變成a;(2) 刪除s中的第二個e;(3)在s中最後新增乙個c; 那麼s到t的編輯路徑就等於3。當然,這種變換並不是唯一的,但如果3是所有變換中最小值的話。那麼我們就可以說s和t的編輯距離等於3了。 

動態規劃解決編輯距離

動態規劃(dynamic programming)是一種解決複雜問題最優解的策略。它的基本思路就是:將乙個複雜的最優解問題分解成一系列較為簡單的最優解問題,再將較為簡單的的最優解問題進一步分解,直到可以一眼看出最優解為止。

動態規劃演算法是解決複雜問題最優解的重要演算法。其演算法的難度並不在於演算法本身的遞迴難以實現,而主要是程式設計者對問題本身的認識是否符合動態規劃的思想。現在我們就來看看動態規劃是如何解決編輯距離的。

還是這個例子:s=「eeba」   t="abac" 。我們發現當s只有乙個字元e、t只有乙個字元a的時候,我們馬上就能得到s和t的編輯距離edit(0,0)=1(將e替換成a)。那麼如果s中有1個字元e、t中有兩個字元ab的時候,我們是不是可以這樣分解:edit(0,1)=edit(0,0)+1(將e替換成a後,在新增乙個b)。如果s中有兩個字元ee,t中有兩個字元ab的時候,我們是不是可以分解成:edit(1,1)=min(edit(0,1)+1, edit(1,0)+1, edit(0,0)+f(1,1)). 這樣我們可以得到這樣一些動態規劃公式:      

如果i=0且j=0        edit(0, 0)=1

如果i=0且j>0        edit(0, j )=edit(0, j-1)+1

如果i>0且j=0        edit( i, 0 )=edit(i-1, 0)+1

如果i>0且j>0        edit(i, j)=min(edit(i-1, j)+1, edit(i,j-1)+1, edit(i-1,j-1)+f(i , j) )

小注:edit(i,j)表示s中[0.... i]的子串 si 到t中[0....j]的子串t1的編輯距離。f(i,j)表示s中第i個字元s(i)轉換到t中第j個字元s(j)所需要的操作次數,如果s(i)==s(j),則不需要任何操作f(i, j)=0; 否則,需要替換操作,f(i, j)=1 。

這就是將長字串間的編輯距離問題一步一步轉換成短字串間的編輯距離問題,直至只有1個字元的串間編輯距離為1。

///c#**/

今天在群裡聊天,提及了 "編輯距離" 演算法。好久不用,重新練練手,免得日後用時亂找。

1. levenshtein distance

該演算法又稱之為 "編輯距離",用於計算兩個字串的相似程度。原理很簡單,就是返回將第乙個字串轉換(刪除、插入、替換)成第二個字串的編輯次數。次數越少,意味著字串相似度越高。

演算法原理:wikipedia - levenshtein distance

step1:

人 民 共 和 時 代

0, 0, 0, 0, 0, 0, 0

中 1, 0, 0, 0, 0, 0, 0

華 2, 0, 0, 0, 0, 0, 0

人 3, 0, 0, 0, 0, 0, 0

民 4, 0, 0, 0, 0, 0, 0

共 5, 0, 0, 0, 0, 0, 0

和 6, 0, 0, 0, 0, 0, 0

國 7, 0, 0, 0, 0, 0, 0

step2:

人 民 共 和 時 代

0, 1, 2, 3, 4, 5, 6

中 1, 0, 0, 0, 0, 0, 0

華 2, 0, 0, 0, 0, 0, 0

人 3, 0, 0, 0, 0, 0, 0

民 4, 0, 0, 0, 0, 0, 0

共 5, 0, 0, 0, 0, 0, 0

和 6, 0, 0, 0, 0, 0, 0

國 7, 0, 0, 0, 0, 0, 0

step3:

人 民 共 和 時 代

0, 1, 2, 3, 4, 5, 6

中 1, 1, 2, 3, 4, 5, 6

華 2, 2, 2, 3, 4, 5, 6

人 3, 2, 3, 3, 4, 5, 6

民 4, 3, 2, 3, 4, 5, 6

共 5, 4, 3, 2, 3, 4, 5

和 6, 5, 4, 3, 2, 3, 4

國 7, 6, 5, 4, 3, 3,4

演算法實現code:

public static int levenshteindistance(string s1, string s2)

}return d[m - 1, n - 1];

}

2. lcs

lcs (longest common subsequence) 演算法用於找出兩個字串最長公共子串。

演算法原理:

(1) 將兩個字串分別以行和列組成矩陣。

(2) 計算每個節點行列字元是否相同,如相同則為 1。

(3) 通過找出值為 1 的最長對角線即可得到最長公共子串。

人 民 共 和 時 代

中 0, 0, 0, 0, 0, 0

華 0, 0, 0, 0, 0, 0

1, 0, 0, 0, 0, 0

民 0,1, 0, 0, 0, 0

共 0, 0,1, 0, 0, 0

和 0, 0, 0,1, 0, 0

國 0, 0, 0, 0, 0, 0

為進一步提公升該演算法,我們可以將字元相同節點(1)的值加上左上角(d[i-1, j-1])的值,這樣即可獲得最大公用子串的長度。如此一來只需以行號和最大值為條件即可擷取最大子串。

人 民 共 和 時 代

中 0, 0, 0, 0, 0, 0

華 0, 0, 0, 0, 0, 0

1, 0, 0, 0, 0, 0

民 0,2, 0, 0, 0, 0

共 0, 0,3, 0, 0, 0

和 0, 0, 0,4, 0, 0

國 0, 0, 0, 0, 0, 0

演算法實現code:

public static string lcs(string s1, string s2)}}

return s1.substring(index - length + 1, length);

}

心得:

我所需要的是lcs(),可以通過修改方法適應需求,通過計算相同字元個數相比第乙個字元的佔比。即可計算出相似度*%

沒有準確的答案,有的只是把別人的東西轉化成你的東西。勸誡自己和學習的朋友

**摘自:

動態規劃 字串相似度 編輯距離問題 java

二 字串相似度 編輯距離 edit distance 對於序列s和t,它們之間距離定義為 對二者其一進行幾次以下的操作 1 刪去乙個字元 2 插入乙個字元 3 改變乙個字元 每進行一次操作,計數增加1。將s和t變為同乙個字串的最小計數即為它們的距離。給出相應演算法。問題分析 這個問題就不像硬幣找零問...

相似URL判定及字串相似度距離

edit distance缺點 基於結構來判斷url相似度,去掉數字。字串是否也需要去掉自身只保留結構,或者保留存在長度的結構,可以根據情況來靈活取捨。抽象一下特徵 1 站點特徵 如果兩個url站點一樣,則特徵取值1,否則取值0 2 目錄深度特徵 特徵取值分別是兩個url的目錄深度是否一致 3 一級...

51Nod 1183 編輯距離 (字串相似演算法)

編輯距離,又稱levenshtein距離 也叫做edit distance 是指兩個字串之間,由乙個轉成另乙個所需的最少編輯操作次數。許可的編輯操作包括將乙個字元替換成另乙個字元,插入乙個字元,刪除乙個字元。例如將kitten一字轉成sitting sitten k s sittin e i sit...