乙個快速 高效的Levenshtein演算法實現

2022-03-15 09:56:36 字數 2267 閱讀 4971

levenshtein演算法,用於計算兩個字串之間的levenshtein距離。而levenshtein距離又稱為編輯距離,是指兩個字串之間,由乙個轉換成另乙個所需的最少編輯操作次數。許可的編輯操作包括將乙個字元替換成另乙個字元,插入乙個字元,刪除乙個字元。

levenshtein距離用來描述兩個字串之間的差異。我在乙個網路爬蟲程式裡面使用這個演算法來比較兩個網頁之間的版本,如果網頁的內容有足夠多的變動,我便將它更新到我的資料庫。

原來的演算法是建立乙個大小為strlen1*strlen2的矩陣。如果所有字串加起來是1000個字元那麼長的話,那麼這個矩陣就會是1m;如果字串是10000個字元,那麼矩陣就是100m。如果元素都是整數(這裡是指數字,int32)的話,那麼矩陣就會是4*100m == 400mb這麼大,唉……

現在的演算法版本只使用2*strlen個元素,這使得後面給出的例子成為2*10,000*4 = 80 kb。其結果是,不但記憶體占用更少,而且速度也變快了!因為這使得記憶體分配只需要很少的時間來完成。當兩個字串的長度都是1k左右時,新演算法的效率是舊演算法的兩倍!

原來的版本將會建立乙個矩陣[6+1, 5+1],而我的新演算法將會建立兩個向量[6+1](黃色元素)。在這兩個演算法版本中,字串的順序是無關緊要、無所謂的,也就是說,它也可以是矩陣[5+1, 6+1]和兩個向量[5+1]。

步驟說明

1設定n為字串s的長度。("gumbo")

設定m為字串t的長度。("gambol")

如果n等於0,返回m並退出。

如果m等於0,返回n並退出。

構造兩個向量v0[m+1] 和v1[m+1],串聯0..m之間所有的元素。

2初始化 v0 to 0..m。

3檢查 s (i from 1 to n) 中的每個字元。

4檢查 t (j from 1 to m) 中的每個字元

5如果 s[i] 等於 t[j],則編輯代價為 0;

如果 s[i] 不等於 t[j],則編輯代價為1。

6設定單元v1[j]為下面的最小值之一:

a、緊鄰該單元上方+1:v1[j-1] + 1

b、緊鄰該單元左側+1:v0[j] + 1

c、該單元對角線上方和左側+cost:v0[j-1] + cost

7在完成迭代 (3, 4, 5, 6) 之後,v1[m]便是編輯距離的值。

本小節將演示如何計算"gumbo"和"gambol"兩個字串的levenshtein距離。

步驟1、2

v0v1gu

mbo0

1234

5g1a

2m3b

4o5l

6步驟3-6,當 i = 1

v0v1gu

mbo0

1234

5g10

a21m

32b4

3o54

l65步驟3-6,當 i = 2

v0v1gu

mbo0

1234

5g10

1a21

1m32

2b43

3o54

4l65

5步驟3-6,當 i = 3

v0v1gu

mbo0

1234

5g10

12a2

112m

3221

b433

2o54

43l6

554步驟3-6,當 i = 4

v0v1gu

mbo0

1234

5g10

123a

2112

3m32

212b

4332

1o54

432l

6554

3步驟3-6,當 i = 5

v0v1gu

mbo0

1234

5g10

1234

a211

234m

3221

23b4

3321

2o54

4321

l655

432步驟7

編輯距離就是矩陣右下角的值,v1[m] == 2。由"gumbo"變換為"gambol"的過程對於我來說是很只管的,即通過將"a"替換為"u",並在末尾追加"l"這樣子(實際上替換的過程是由移除和插入兩個操作組合而成的)。

如果您確信你的字串永遠不會超過2^16(65536)個字元,那麼你可以使用ushort來表示而不是int,如果字串少於2^8個,還可以使用byte。我覺得這個演算法用非託管**實現的話可能會更快,但我沒有試過。

配置乙個高效快速的Git環境

可以直接修改 gitconfig檔案,也可以用命令配置乙個可以實際使用的高效的git環境。這兩項是必須的。git config global user.name gituser git config global user.email email git.comor user name gituse...

乙個高效反射類

1.專案中有需要用到反射的地方,仔細研究了下反射,其效率並不高 還好微軟提供了il的程式設計方法,自己實現了乙個高效反射類 下面舉些常用例子 我們反射出.netframework中的乙個未公開的類 sessionstateutility 並呼叫其私有方法 deserialize 注意 由於dynam...

乙個高效的分頁儲存過程

最近在做乙個幾百萬條資料的分頁查詢,研究了各種方案,在本機上用專案的實際資料庫做測試,測試過程 is very 痛苦,不堪回首ing。現在廢話不多說,直接上結果,相信這也是大多數搜尋答案的人最願意看的方式。以下是儲存過程的 1 create procedure dbo p gridviewpager...