[随笔]初步了解 Levenshtein Distance (Edit Distance) 编辑距离,字符相似度算法

前几天在CSDN的论坛看到一个需要判断两个字符串之间相差多少个字符的帖子,之前有了解过有相应的算法来计算这个差异,但是没有深入的去了解.刚好趁这个时机了解了一下: Levenshtein Distance (Edit Distance) 编辑距离,字符相似度算法

 

对于该算法,详细说明可参考wiki: 

 

摘自维基:

"编辑距离,又称Levenshtein距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。

 

例如将kitten一字转成sitting:

  1. sitten (k→s)
  2. sittin (e→i)
  3. sitting (→g)

 

俄罗斯科学家Vladimir Levenshtein1965年提出这个概念。"

 

中文: http://zh.wikipedia.org/wiki/%E7%B7%A8%E8%BC%AF%E8%B7%9D%E9%9B%A2

英文: http://en.wikipedia.org/wiki/Levenshtein_distance 

 

然后写了一个Demo来加深了解

 

这里是维基给的伪代码:

 

"

动态规划经常被用来作为这个问题的解决手段之一。

整數 Levenshtein距離(字符 str1[1..lenStr1], 字符 str2[1..lenStr2])

   宣告 int d[0..lenStr1, 0..lenStr2]

   宣告 int i, j, cost

 

   對於 i 等於 由 0 至 lenStr1

       d[i, 0] := i

   對於 j 等於 由 0 至 lenStr2

       d[0, j] := j

   對於 i 等於 由 1 至 lenStr1

       對於 j 等於 由 1 至 lenStr2

           若 str1[i] = str2[j] 則 cost := 0

                                否則 cost := 1

           d[i, j] := 最小值(

                                d[i-1, j  ] + 1,     // 刪除

                                d[i  , j-1] + 1,     // 插入

                                d[i-1, j-1] + cost   // 替換

                            )

 

   返回 d[lenStr1, lenStr2]

"

 

Demo如下:

 

[散分][随笔]初步了解 Levenshtein Distance (Edit Distance) 编辑距离,字符相似度算法

05-31

博客地址: [url=http://blog.csdn.net/Lost_Painting/archive/2011/05/31/6457334.aspx][/url] rn rn 前几天在论坛看到一个需要判断两个字符串之间相差多少个字符的帖子,之前有了解过有相应的算法来计算这个差异,但是没有深入的去了解.刚好趁这个时机了解了一下: Levenshtein Distance (Edit Distance) 编辑距离,字符相似度算法rnrn对于该算法,详细说明可参考wiki: rn中文: http://zh.wikipedia.org/wiki/%E7%B7%A8%E8%BC%AF%E8%B7%9D%E9%9B%A2rnrn英文: http://en.wikipedia.org/wiki/Levenshtein_distance rnrn摘自维基:rnrn"编辑距离,又称Levenshtein距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。rnrn例如将kitten一字转成sitting:rnrnsitten (k→s)rnsittin (e→i)rnsitting (→g)rn俄罗斯科学家Vladimir Levenshtein在1965年提出这个概念。"rnrnrn这里是维基给的伪代码:rnrn"rnrn动态规划经常被用来作为这个问题的解决手段之一。rnrn整數 Levenshtein距離(字符 str1[1..lenStr1], 字符 str2[1..lenStr2])rnrn 宣告 int d[0..lenStr1, 0..lenStr2]rnrn 宣告 int i, j, costrnrn 對於 i 等於 由 0 至 lenStr1rnrn d[i, 0] := irnrn 對於 j 等於 由 0 至 lenStr2rnrn d[0, j] := jrnrn 對於 i 等於 由 1 至 lenStr1rnrn 對於 j 等於 由 1 至 lenStr2rnrn 若 str1[i] = str2[j] 則 cost := 0rnrn 否則 cost := 1rnrn d[i, j] := 最小值(rnrn d[i-1, j ] + 1, // 刪除rnrn d[i , j-1] + 1, // 插入rnrn d[i-1, j-1] + cost // 替換rnrn )rnrn 返回 d[lenStr1, lenStr2]rnrn"rnrn写了一个Demo来加深了解,Demo如下:rnrn[code=C#]rnusing System; rnusing System.Collections.Generic; rnusing System.ComponentModel; rnusing System.Data; rnusing System.Drawing; rnusing System.Linq; rnusing System.Text; rnusing System.Windows.Forms; rnnamespace WindowsFormsApplication1 rn rn public partial class Form1 : Form rn rn public Form1() rn rn InitializeComponent(); rn rn private void button1_Click(object sender, EventArgs e) rn rn rn char[] c1 = richTextBox1.Text.Trim().ToCharArray(); rn char[] c2 = richTextBox2.Text.Trim().ToCharArray(); rn int[,] result = Calculate(c1, c2); rn rn DataTable dt = new DataTable(); rn for (int i = 0; i < c1.Length + 2; i++) rn rn dt.Columns.Add(i.ToString()); rn rn for (int i = 0; i < c2.Length + 2; i++) rn rn DataRow row = dt.NewRow(); rn dt.Rows.Add(row); rn rn for (int i = 0; i < c2.Length + 2; i++) rn rn if (i < 2) rn rn dt.Rows[i][0] = string.Empty; rn rn else rn rn dt.Rows[i][0] = c2[i - 2]; rn rn rn for (int i = 0; i < c1.Length + 2; i++) rn rn if (i < 2) rn rn dt.Rows[0][i] = string.Empty; rn rn else rn rn dt.Rows[0][i] = c1[i - 2]; rn rn rn for (int i = 0; i < result.GetLength(0); i++) rn rn for (int j = 0; j < result.GetLength(1); j++) rn rn dt.Rows[j + 1][i + 1] = result[i, j]; rn rn rn if (checkBox1.Checked == true) rn rn dataGridView1.DataSource = dt; rn dataGridView1.ColumnHeadersVisible = false; rn dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells; rn rn label1.Text = string.Format("字符相似度:0" rn , dt.Rows[result.GetLength(1)][result.GetLength(0)].ToString()); rn rn public static int[,] Calculate(char[] First, char[] Second) rn rn int lenFirst = First.Length + 1; rn int lenSecond = Second.Length + 1; rn int[,] matrixResult = new int[lenFirst, lenSecond]; rn for (int i = 0; i < lenFirst; i++) matrixResult[i, 0] = i; rn for (int j = 0; j < lenSecond; j++) matrixResult[0, j] = j; rn for (int i = 1; i < lenFirst; i++) rn rn for (int j = 1; j < lenSecond; j++) rn rn if (First[i - 1] == Second[j - 1]) rn rn matrixResult[i, j] = matrixResult[i - 1, j - 1]; rn rn else rn rn matrixResult[i, j] = new int[] matrixResult[i - 1, j] + 1 rn , matrixResult[i , j-1] + 1 rn , matrixResult[i - 1, j-1] + 1 rn .Min(); rn rn rn rn return matrixResult; rn rn rn rn [/code]

没有更多推荐了,返回首页