编辑距离

在计算机科学中,编辑距离是一种量化两个字符串差异程度的方法,也就是计算从一个字符串转换成另外一个字符串所需要的最少操作步骤。不同的编辑距离中定义了不同操作的集合。比较常用的莱温斯坦距离(Levenshtein distance)中定义了:删除、插入、替换操作。

算法描述

定义edit(i, j),表示第一个字符串的长度为i的子串到第二个字符串长度为j的子串的编辑距离。

  • 如果用递归的算法,自顶向下依次简化问题:

if (i < 0 && j < 0), edit(i, j) = 0;

if (i < 0 && j >= 0), edit(i, j) = j;

if (i >= 0 && j < 0), edit(i, j) = i;

if (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)}, 如果第一个字符串的第i个字符等于第二个字符串的第j个字符,那么f(i, j) = 1;否则,f(i, j) = 0。

因为字符串的开始坐标是从0开始的,然后利用递归的时候判断条件应该和0比较。

  • 如果用动态规划的思想,自底向上依次计算,保留已经计算的结果:

table[i][j]表示第一个字符串的长度为i的子串与第二个字符串长度为j的子串的距离。

if (j == 0), table[0][j] = j;

if (i == 0), table[i][0] = i;

if (i >= 1 && j >= 1), table[i][j] = min({table[i - 1][j] + 1, table[i][j - 1] + 1, table[i - 1][j - 1] + (s1[i - 1] == s2[j - 1] ? 0 : 1)});

具体实现

#include <iostream>

using namespace std;

class EditDistance {

public:
int edit(string s1, string s2, int len1, int len2);
int dp_edit_distance(string s1, string s2, int len1, int len2); }; // 递归
int EditDistance::edit(string s1, string s2, int len1, int len2) {
if (len1 < 0 && len2 < 0)
return 0;
if (len1 < 0 && len2 >= 0)
return len2 + 1;
if (len1 >= 0 && len2 < 0)
return len1 + 1;
if (len1 >= 0 && len2 >= 0) {
return min(min(edit(s1, s2, len1 - 1, len2) + 1, edit(s1, s2, len1, len2 - 1) + 1),
edit(s1, s2, len1 - 1, len2 - 1) + (s1[len1] == s2[len2] ? 0 : 1) );
}
} // 动态规划
int EditDistance::dp_edit_distance(string s1, string s2, int len1, int len2) {
int max1 = s1.size();
int max2 = s2.size();
int** table = new int* [max1 + 1];
for (int i = 0; i < max1 + 1; i++) {
table[i] = new int[max2 + 1];
} for (int i = 0; i < max1 + 1; i++) {
table[i][0] = i;
}
for (int j = 0; j < max2 + 1; j++) {
table[0][j] = j;
} for (int i = 1; i < max1 + 1; i++) {
for (int j = 1; j < max2 + 1; j++) {
table[i][j] = min(min(table[i - 1][j] + 1, table[i][j - 1] + 1), table[i - 1][j - 1] + (s1[i - 1] == s2[j - 1] ? 0 : 1)); //注意s1[i - 1]不是s1[i]
}
} int result = table[max1][max2]; // 释放内存
for(int i = 0; i < max1 + 1; i++)
{
delete[] table[i];
table[i] = NULL;
}
delete[] table;
table = NULL; return result;
} int main() {
string str1 = "failingppp";
string str2 = "sailnbbb";
EditDistance* editDistance = new EditDistance();
clock_t start, end;
start = clock(); for (int i = 0; i < 1000000; i++) {
//int result = editDistance->edit(str1, str2, str1.size() - 1, str2.size() - 1);
int result = editDistance->dp_edit_distance(str1, str2, str1.size() - 1, str2.size() - 1);
//cout << "edit distance of " << str1 << " and " << str2 << " is : " << result << endl;
}
end = clock();
cout << "time1: " << (end - start) / 1000000.0 << endl; start = clock();
for (int i = 0; i < 100; i++) {
int result = editDistance->edit(str1, str2, str1.size() - 1, str2.size() - 1);
//int result = editDistance->dp_edit_distance(str1, str2, str1.size() - 1, str2.size() - 1);
//cout << "edit distance of " << str1 << " and " << str2 << " is : " << result << endl;
}
end = clock();
cout << "time2: " << (end - start) / 1000000.0 << endl; return 0;

说明:通过上面程序对比,可以发现动态规划明显快于递归的,因为递归需要反复的程序进入与返回操作,而动态保留了之前计算的结果。

参考文献

编辑距离及编辑距离算法

Edit distance

编辑距离——Edit Distance的更多相关文章

  1. 利用编辑距离(Edit Distance)计算两个字符串的相似度

    利用编辑距离(Edit Distance)计算两个字符串的相似度 编辑距离(Edit Distance),又称Levenshtein距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数.许可 ...

  2. 行编辑距离Edit Distance——动态规划

    题目描写叙述: 给定一个源串和目标串.可以对源串进行例如以下操作:  1. 在给定位置上插入一个字符  2. 替换随意字符  3. 删除随意字符 写一个程序.返回最小操作数,使得对源串进行这些操作后等 ...

  3. [Swift]LeetCode72. 编辑距离 | Edit Distance

    Given two words word1 and word2, find the minimum number of operations required to convert word1 to  ...

  4. [Leetcode 72]编辑距离 Edit Distance

    [题目] Given two words word1 and word2, find the minimum number of operations required to convert word ...

  5. 编辑距离Edit Distance 非常典型的DP类型题目

    https://leetcode.com/problems/edit-distance/?tab=Description 真的非常好,也非常典型. https://discuss.leetcode.c ...

  6. [LeetCode] One Edit Distance 一个编辑距离

    Given two strings S and T, determine if they are both one edit distance apart. 这道题是之前那道Edit Distance ...

  7. stanford NLP学习笔记3:最小编辑距离(Minimum Edit Distance)

    I. 最小编辑距离的定义 最小编辑距离旨在定义两个字符串之间的相似度(word similarity).定义相似度可以用于拼写纠错,计算生物学上的序列比对,机器翻译,信息提取,语音识别等. 编辑距离就 ...

  8. Edit Distance编辑距离(NM tag)- sam/bam格式解读进阶

    sam格式很精炼,几乎包含了比对的所有信息,我们平常用到的信息很少,但特殊情况下,我们会用到一些较为生僻的信息,关于这些信息sam官方文档的介绍比较精简,直接看估计很难看懂. 今天要介绍的是如何通过b ...

  9. Minimum edit distance(levenshtein distance)(最小编辑距离)初探

    最小编辑距离的定义:编辑距离(Edit Distance),又称Levenshtein距离.是指两个字串之间,由一个转成还有一个所需的最少编辑操作次数.许可的编辑操作包含将一个字符替换成还有一个字符. ...

随机推荐

  1. 同步github上fork出来的分支

    1,clone自己的账号里fork库的分支到本地 git clone 地址_branch 2,增加远程原始分支 git remote add upstream 地址_master 3,fetch原始源 ...

  2. [转] vim自定义配置 和 在ubnetu中安装vim

    Ubuntu 12.04安装vim和配置   问题: ubuntu默认没有安装vim,出现: jyg@ubuntu:~$ vim test.cThe program 'vim' can be foun ...

  3. ubuntu 15.04 安装配置 JDK1.8

    1.到oracle的官网下载 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 选 ...

  4. UVALive 7147 World Cup(数学+贪心)(2014 Asia Shanghai Regional Contest)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=6 ...

  5. 在Ubuntu 12.04下采用apt-get的方法安装Qt4

    在Ubuntu 12.04下采用apt-get的方法安装Qt4 注:之前发表的一篇博客是采用编译源码的方式安装Qt4,这是很有用的方式,因为源码安装对于所有系统都是通用的,其次,在使用交叉编译器的时候 ...

  6. Android studio 中的配置编译错误总结

    1.编译Andorid 工程的时候,有时候出现gradle 报下面的错误. Error:(1, 0) Cause: com/android/build/gradle/LibraryPlugin : U ...

  7. 中文乱码~Windows 7

    1.安装匹配的中文语言包 2.安装中文字体

  8. 批量下载网站图片的Python实用小工具

    定位 本文适合于熟悉Python编程且对互联网高清图片饶有兴趣的筒鞋.读完本文后,将学会如何使用Python库批量并发地抓取网页和下载图片资源.只要懂得如何安装Python库以及运行Python程序, ...

  9. java连接mysql步骤

    转自:http://www.cnblogs.com/hongten/archive/2011/03/29/1998311.html JDBC连接mysql数据库   •创建一个以JDBC连接数据库的程 ...

  10. 一个section刷新 一个cell刷新

    一个section刷新   一个cell刷新 //一个section刷新 NSIndexSet *indexSet=[[NSIndexSet alloc]initWithIndex:2]; [tabl ...