编辑距离算法

摘要:
Unix中的Diff和patch是使用编辑距离进行文本编辑比较的示例。一般的LCS问题(即任意数量的序列)属于NP难问题。int[][]dp=newint[len1+1][len2+1];对于(inti=1;=len2;j++){intsame=s1.charAt(i-1)==s2.charAt(j-1)?

2018-04-12 21:20:30

编辑距离是针对二个字符串(例如英文字)的差异程度的量化量测,量测方式是看至少需要多少次的处理才能将一个字符串变成另一个字符串。编辑距离可以用在自然语言处理中,例如拼写检查可以根据一个拼错的字和其他正确的字的编辑距离,判断哪一个(或哪几个)是比较可能的字。DNA也可以视为用A、C、G和T组成的字符串,因此编辑距离也用在生物信息学中,判断二个DNA的类似程度。Unix 下的 diff 及 patch 即是利用编辑距离来进行文本编辑对比的例子。

常用的编辑距离算法有:

  • Levenshtein距离,在莱文斯坦距离中,可以删除、加入、取代字符串中的任何一个字元,也是较常用的编辑距离定义,常常提到编辑距离时,指的就是莱文斯坦距离。
  • LCS(最长公共子序列)距离,只允许删除、加入字元。

一、最长公共子序列 LCS

最长公共子序列问题是很经典的动态规划问题,问题描述如下:

LCS是Longest Common Subsequence的缩写,即最长公共子序列。一个序列,如果是两个或多个已知序列的子序列,且是所有子序列中最长的,则为最长公共子序列。

子序列: 一个序列A = a1,a2,……an,中任意删除若干项,剩余的序列叫做A的一个子序列。也可以认为是从序列A按原顺序保留任意若干项得到的序列。

例如:对序列 1,3,5,4,2,6,8,7来说,序列3,4,8,7 是它的一个子序列。对于一个长度为n的序列,它一共有2^n 个子序列,有(2^n – 1)个非空子序列。

请注意:子序列不是子集,它和原始序列的元素顺序是相关的。

时间复杂度:对于一般性的LCS问题(即任意数量的序列)是属于NP-hard。但当序列的数量确定时,问题可以使用动态规划(Dynamic Programming)在多项式时间内解决。

编辑距离算法第1张

    public int LCS(String s1, String s2) {
        if (s1.length() == 0 || s2.length() == 0) return 0;
        int len1 = s1.length();
        int len2 = s2.length();
        int[][] dp = new int[len1 + 1][len2 + 1];
        for (int i = 0; i <= len2; i++) dp[0][i] = 0;
        for (int i = 0; i <= len1; i++) dp[i][0] = 0;
        for (int i = 1; i <= len1; i++) {
            for (int j = 1; j <= len2; j++) {
                int same = s1.charAt(i - 1) == s2.charAt(j - 1) ? 1 : 0;
                dp[i][j] = Math.max(Math.max(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1] + same);
            }
        }
        return dp[len1][len2];
    }

二、莱文斯坦距离 LevenshteinDistcance

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

例如将kitten一字转成sitting:

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

俄罗斯科学家弗拉基米尔·莱文斯坦在1965年提出这个概念。

为了进一步的度量两个字符串的相似程度,我们在得到最少的操作次数后,进行如下的计算:

1 - res / max(len1, len2)

和LCS几乎一样,依然是使用动态规划算法进行求解,以下分别是伪代码和Java实现:

int LevenshteinDistcance(string str1[1..lenStr1], string str2[1..lenStr2])
    int d[0..lenStr1, 0..lenStr2]
    int i, j, cost
 
    for i = 0 to lenStr1
       d[i, 0] := i
    for j = 0 to lenStr2
       d[0, j] := j
 
    for i = 1 to lenStr1
        for j = 1 to lenStr2
            if str1[i] = str2[j] 
                cost := 0
            else 
                cost := 1
            d[i, j] := min(
                                d[i-1, j  ] + 1,     // 删除
                                d[i  , j-1] + 1,     // 插入
                                d[i-1, j-1] + cost   // 替換
                            )
 
   return d[lenStr1, lenStr2]
    public double levenshteinDistcance(String s1, String s2) {
        if (s1.length() == 0) return s2.length();
        if (s2.length() == 0) return s1.length();
        int len1 = s1.length();
        int len2 = s2.length();
        int[][] d = new int[len1 + 1][len2 + 1];
        for (int i = 0; i <= len1; i++) d[i][0] = i;
        for (int i = 0; i <= len2; i++) d[0][i] = i;
        for (int i = 1; i <= len1; i++) {
            for (int j = 1; j <= len2; j++) {
                int same = s1.charAt(i - 1) == s2.charAt(j - 1) ? 0 : 1;
                d[i][j] = Math.min(Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1), d[i - 1][j - 1] + same);
            }
        }
        // 得到最少的操作次数后,计算公式为:
        // 1 - res / max(len1, len2)
        return 1 - d[len1][len2] * 1.0 / Math.max(len1, len2);
    }

免责声明:文章转载自《编辑距离算法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇CSS3去除手机浏览器button点击出现的高亮框分享一次大厂的辛酸面试经历下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

使用ffmpeg将GoPro长延时的jpg照片转换成视频文件(一条命令)

不像大疆的OSMO+ 可以直接拍摄长延时视频 ,gopro相机只能以jpg的格式保存照片,再由手动的方式转成视频,那如何将图片转换成视频文件呢? 还是有办法的,使用开源的ffmpeg一条命令就可以实现,具体如下: 1、将gopro中的长延时jpg文件复制到本地文件夹下。 2、安装ffmpeg。 3、在cmd模式下,先当前的路径切换到第1步复制的文件夹下(如...

数据库定时清理脚本配置

定时 数据库清理的两个脚本: 按天删除: #!/bin/bash ndate=3 datestr=`date -d "-$ndate day" +%Y-%m-%d` #生成ndate天前的日期,如: echo $datestr delSqlStr="DELETE FROM xxxx WHERE GeneDate = '$datestr'" #SQL语句...

生物数据库介绍——NCBI

NCBI(National Center for Biotechnology Information,美国国家生物技术信息中心)除了维护GenBank核酸序列数据库外,还提供数据分析和检索资源。NCBI资源包括Entrez、Entrez编程组件、MyNCBI、PubMed、PudMed Central、PubReader、Gene、the NCBI Tax...

Apache虚拟主机(vhost)配置教程

版本:Apache Version Apache/2.4.6 (Ubuntu) 系统: ubuntn12.04 在/etc/apache2/sites-enabled/ sudo cp 000-defaut.conf sv1.conf sudo vim sv1.conf <VirtualHost *:80>  ServerName www.sv1...

懒加载——实现原理

本文主要通过以下几方面来说明懒加载技术的原理,个人前端小菜,有错误请多多指出 一、什么是图片滚动加载?   通俗的讲就是:当访问一个页面的时候,先把img元素或是其他元素的背景图片路径替换成一张大小为1*1px图片的路径(这样就只需请求一次),只有当图片出现在浏览器的可视区域内时,才设置图片正真的路径,让图片显示出来。这就是图片懒加载。 二、为什要使用这个...

bzoj:1072: [SCOI2007]排列perm

Description   给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0)。例如123434有90种排列能被2整除,其中末位为2的有30种,末位为4的有60种。 Input   输入第一行是一个整数T,表示测试数据的个数,以下每行一组s和d,中间用空格隔开。s保证只包含数字0, 1, 2, 3, 4, 5, 6, 7, 8,...