编辑距离

在计算机科学中,编辑距离是一种量化两个字符串差异程度的方法,也就是计算从一个字符串转换成另外一个字符串所需要的最少操作步骤。不同的编辑距离中定义了不同操作的集合。比较常用的莱温斯坦距离(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. Could not find class 'android.support.v4.view.ViewPager', referenced from me

    http://www.ithao123.cn/content-8236579.html 按照上面链接说的来做,弄完Clean一下项目,就可以运行.

  2. xshell 语句

    使用命令 cd 切换到tomcat的bin目录,如:cd /root/Test_APP_Project_CRM/bin   使用命令 [ ./startup.sh ]启动tomcat服务../star ...

  3. centos7 tomcat service 自启动

    第一步: vim /lib/systemd/system/tomcat.service 第二步:复制以下代码保存退出,注意修改你的tomcat路径 [Unit] Description=tomcat ...

  4. android selector 开始自定义样式

    Selector的结构描述: <?xml version="1.0" encoding="utf-8"?> <selector xmlns:a ...

  5. 关于DoesObjectExist

    目录: 我们可以看到这个文件夹目录是存在的 文件: 然后,我们运行测试一下: 文件存在检测成功(正常) 文件夹存在,但检测失败! ??? 明明存在的,为什么检测不到……

  6. Android -- 常见控件的小效果

    1,EditText控件 ① 修改光标颜色 自定义drawable 创建cursor.xml文件 <?xml version="1.0" encoding="utf ...

  7. WebSQL 查询工具

    最近在写 WebSQL ,每次都在浏览器控制台执行 SQL 太费劲了,并且脑子不好使,总是忘记上次初始化的数据库是什么,所以写了一个特别简单的 WebSQL 可视化工具,说工具有点大了,就是为了方便, ...

  8. app加固

    为什么要加固APP? 答:因为黑客通过反编译APK得到源码后,会在应用中插入代码,获取利益,比如添加广告,盗取用户账号.密码,后台定制活动等.   反编译的方法? 反编译是指apk文件通过反编译工具( ...

  9. HBase完全分布模式安装

    假设Hadoop已经成功安装. 实验环境如下: centos 6.4 hadoop-0.20.2 hbase-0.90.5       用户名root hadoop安装目录:/root/bin/had ...

  10. 手机sdk 开发

    题记:很多做游戏开发的人,估计都或多或少地接过渠道SDK,什么UC,当乐,91,小米,360......据统计国内市场当前不下于100家渠道,还包括一些没有SDK的小渠道.每个渠道SDK接入的方法呢, ...