编辑距离算法(Edit Distance)

转载

编辑距离算法(Edit Distance)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/Grace_0642/article/details/53944188

写在前面的话

今年是2016年的最后一天,外公,超级想你,我都没有想过你会不能继续再走到2017.我过得很好,每天都超级幸福,我现在在学校有一堆好朋友。哈哈,我总是能处在宇宙中心的那种人,没办法,您这么优秀才能教出这么好的孙女,好吧。

我会好好学习的,我是第一女王嘛,永远都会是的。是吧,要做就做最好,要么就不做,我永远都要做你的骄傲。对了,我又有很多新朋友了,我们就像家人一样,就是每天都过得超级幸福,哈哈,就是有种魔力,能让我遇到的人都把像家人一样对待。我又变美了,好吧,简直是全院最美的,好吧。现在有一堆人在照顾我,保护我,给我开心,带我给无穷无尽的快乐,我从来都没有这么开心过。生命真的很奇特,不是么。

啊,对了,隆达罗西复出了,我们等了好久,你在天国要记得看知道么。还有啊,要照顾好自己。我爱你哟,你知道超级爱~

好像这个月写的都是传说中的"情感"博客,看不下去了,出来写篇非情感博客。

好像我的技术博客情感博客变成了主线,技术博客变成了背景衬托,哈哈哈,心疼的抱抱订阅我博客的小伙伴们。

感觉最近打字真的很顺溜啊。哟西,速度真的是杠杠滴

终于可以不正紧的写一篇技术博客了,画风突然有点奇特,嘎嘎嘎~



概念

编辑距离的作用主要是用来比较两个字符串的相似度的

基本的定义如下所示:

编辑距离,又称Levenshtein距离(莱文斯坦距离也叫做Edit Distance),是指两个字串之间,由一个转成另一个所需的最少编辑操作次数,如果它们的距离越大,说明它们越是不同。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。

这个概念是由俄罗斯科学家Vladimir Levenshtein在1965年提出来的,所以也叫 Levenshtein 距离。它可以用来做DNA分析,拼字检测,抄袭识别等等。总是比较相似的,或多或少我们可以考虑编辑距离。

在概念中,我们可以看出一些重点那就是,编辑操作只有三种。插入,删除,替换这三种操作,我们有两个字符串,将其中一个字符串经过上面的这三种操作之后,得到两个完全相同的字符串付出的代价是什么就是我们要讨论和计算的。

例如:
我们有两个字符串: kitten 和 sitting:
现在我们要将kitten转换成sitting
我们可以做如下的一些操作;

k i t t e n --> s i t t e n 将K替换成S

sitten --> sittin 将 e 替换成i

sittin --> sitting 添加g

在这里我们设置每经过一次编辑,也就是变化(插入,删除,替换)我们花费的代价都是1。

例如:

  • 如果str1=“ivan”,str2=“ivan”,那么经过计算后等于 0。没有经过转换。相似度=1-0/Math.Max(str1.length,str2.length)=1
  • 如果str1=“ivan1”,str2=“ivan2”,那么经过计算后等于1。str1的"1"转换"2",转换了一个字符,所以距离是1,相似度=1-1/Math.Max(str1.length,str2.length)=0.8


#算法过程

1.str1或str2的长度为0返回另一个字符串的长度。 if(str1.length0) return str2.length; if(str2.length0) return str1.length;

2.初始化(n+1)(m+1)的矩阵d,并让第一行和列的值从0开始增长。扫描两字符串(nm级的),如果:str1[i] == str2[j],用temp记录它,为0。否则temp记为1。然后在矩阵d[i,j]赋于d[i-1,j]+1 、d[i,j-1]+1、d[i-1,j-1]+temp三者的最小值。

3.扫描完后,返回矩阵的最后一个值d[n][m]即是它们的距离。

计算相似度公式:1-它们的距离/两个字符串长度的最大值。


其实这个算法并不难实现
我们用字符串“ivan1”和“ivan2”举例来看看矩阵中值的状况:

1、第一行和第一列的值从0开始增长
这里写图片描述
图一

首先我们先创建一个矩阵,或者说是我们的二维数列,假设有两个字符串,我们的字符串的长度分别是m和n,那么,我们矩阵的维度就应该是(m+1)*(n+1).

注意,我们先给数列的第一行第一列赋值,从0开始递增赋值。我们就得到了图一的这个样子

之后我们计算第一列,第二列,依次类推,算完整个矩阵。

我们的计算规则就是:
d[i,j]=min(d[i-1,j]+1 、d[i,j-1]+1、d[i-1,j-1]+temp) 这三个当中的最小值。

其中:str1[i] == str2[j],用temp记录它,为0。否则temp记为1

我们用d[i-1,j]+1表示增加操作
d[i,j-1]+1 表示我们的删除操作
d[i-1,j-1]+temp表示我们的替换操作

2、举证元素的产生 Matrix[i - 1, j] + 1 ; Matrix[i, j - 1] + 1 ; Matrix[i - 1, j - 1] + t 三者当中的最小值
这里写图片描述

3.依次类推直到矩阵全部生成
这里写图片描述

这里写图片描述

这个就得到了我们的整个完整的矩阵。

下面我们来看下代码,我最擅长的就是Python,下面我们来看实现:

#!/usr/bin/env python
# coding=utf-8
# function   : calculate the minEditDistance of two strings
# author     : Chicho
# date       : 2016-12-31

def minEditDist(sm,sn):
m,n = len(sm)+1,len(sn)+1

# create a matrix (m*n)

matrix = [[0]*n for i in range(m)]

matrix[0][0]=0
for i in range(1,m):
    matrix[i][0] = matrix[i-1][0] + 1

for j in range(1,n):
    matrix[0][j] = matrix[0][j-1]+1


for i in range(m):
    print matrix[i]


print "********************"

cost = 0

for i in range(1,m):
    for j in range(1,n):
        if sm[i-1]==sn[j-1]:
            cost = 0
        else:
            cost = 1
        
        matrix[i][j]=min(matrix[i-1][j]+1,matrix[i][j-1]+1,matrix[i-1][j-1]+cost)


for i in range(m):
    print matrix[i]

return matrix[m-1][n-1]

mindist=minEditDist(“ivan1”,“ivan2”)
print mindist

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

我们来看下最后得到的运行结果:
这里写图片描述
上面是一个初始化的矩阵

这里写图片描述
最后得到的结果,距离就是最后右下角的那个值1

下面我们在根据计算出两个字符串的相似度:

最后得到它们的距离=1

相似度:1-1/Math.Max(“ivan1”.length,“ivan2”.length) =0.8





参考文献:

http://www.cnblogs.com/ivanyb/archive/2011/11/25/2263356.html

写在后面的话

无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程 https://www.cbedai.net/chichoxian

在这里插入图片描述

外公,爱你,给你一个敲大的么么哒

这里写图片描述

希望生命可以产生所有奇妙的化学反应

                                </div>
            <link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-095d4a0b23.css" rel="stylesheet">
                </div>
</article>
<div class="postTime">
            <div class="article-bar-bottom">
        <div class="reward-user-box">
            <span class="reward-word">有 <span class="num">0</span> 个人打赏</span>
                        </div>
    </div>
            <span class="time">
        文章最后发布于: 2016-12-31 21:31:35        </span>
</div>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值