编辑距离

在计算机科学中,编辑距离是一种量化两个字符串差异程度的方法,也就是计算从一个字符串转换成另外一个字符串所需要的最少操作步骤。不同的编辑距离中定义了不同操作的集合。比较常用的莱温斯坦距离(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. Java实现冒泡排序

    冒泡排序思想就是将数列的相邻两个数比较,较大的数往后保存,小的数往前. package Sort; import java.util.Arrays; public class BubbleSort { ...

  2. .html(),.text()和.val()的差异总结:

    .html(),.text()和.val()的差异总结: 1.html(),.text(),.val()三种方法都是用来读取选定元素的内容:只不过.html()是用来读取元素的html内容(包括htm ...

  3. Java网络编程之流——readline()方法的bug

    readline()方法有一个隐含的bug,它不一定会把一个回车看作行的结束.相反,readline()只识别换行或回车/换行对.当在流中检测到回车时,readline()会在继续之前等待,查看下一个 ...

  4. PhpStorm 4.0 & 5.0 部署本地Web应用 (转)

    1.创建新的项目(project),创建完成之后单击工具栏的应用运行/调试(Select Run/Debug Configuration)的下拉菜单弹出 Edit Cofigurations选项,单击 ...

  5. C/C++ 结构体 数组 函数传递

    #include <stdio.h> #include <stdlib.h> struct student{ int num; ]; double dec; }; void s ...

  6. Rational Rose2007下载安装教程以及问题处理

    Rational Rose2007详细安装步骤 学习了UML,那么Rational rose画图软件当然就是必不可少的了.我的电脑是win7 64位的系统.下面的链接是安装软件以及破解方法.该软件是B ...

  7. 报错:Failed to instantiate the default view controller for UIMainStoryboardFile 'MainStoryboard' - perhaps the designated entry point is not set?

    原因分析:在StoryBoard中没有一个view controller设置了Initial Scene. 解决方案:在Storyboard中,选择一个view conroller作为story bo ...

  8. iOS开发:http中的get和post请求

    什么是 HTTP ? 超文本传输协议(HTTP)的设计目的是保证客户端与服务器之间的通信. HTTP 的工作方式是客户端与服务器之间的请求-应答协议. web 浏览器可能是客户端,而计算机上的网络应用 ...

  9. java关键字 super 和 this

    简单粗暴的说就是: super: 是指父类,想要在子类方法中调用父类的实例变量或方法可以通过super 来访问 this:是指当前类,想要访问当前类的实例变量和方法可以使用this,同时可以省略

  10. .NET开发者必备的工具箱

    本文作者Spencer是一名专注于ASP.NET和C#的程序员,他列举了平时工作.在家所使用的大部分开发工具,其中大部分工具都是集中于开发,当然也有一些其它用途的,比如图片处理.文件压缩等. 如果你是 ...