编辑距离——Edit Distance
编辑距离
在计算机科学中,编辑距离是一种量化两个字符串差异程度的方法,也就是计算从一个字符串转换成另外一个字符串所需要的最少操作步骤。不同的编辑距离中定义了不同操作的集合。比较常用的莱温斯坦距离(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)计算两个字符串的相似度
利用编辑距离(Edit Distance)计算两个字符串的相似度 编辑距离(Edit Distance),又称Levenshtein距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数.许可 ...
- 行编辑距离Edit Distance——动态规划
题目描写叙述: 给定一个源串和目标串.可以对源串进行例如以下操作: 1. 在给定位置上插入一个字符 2. 替换随意字符 3. 删除随意字符 写一个程序.返回最小操作数,使得对源串进行这些操作后等 ...
- [Swift]LeetCode72. 编辑距离 | Edit Distance
Given two words word1 and word2, find the minimum number of operations required to convert word1 to ...
- [Leetcode 72]编辑距离 Edit Distance
[题目] Given two words word1 and word2, find the minimum number of operations required to convert word ...
- 编辑距离Edit Distance 非常典型的DP类型题目
https://leetcode.com/problems/edit-distance/?tab=Description 真的非常好,也非常典型. https://discuss.leetcode.c ...
- [LeetCode] One Edit Distance 一个编辑距离
Given two strings S and T, determine if they are both one edit distance apart. 这道题是之前那道Edit Distance ...
- stanford NLP学习笔记3:最小编辑距离(Minimum Edit Distance)
I. 最小编辑距离的定义 最小编辑距离旨在定义两个字符串之间的相似度(word similarity).定义相似度可以用于拼写纠错,计算生物学上的序列比对,机器翻译,信息提取,语音识别等. 编辑距离就 ...
- Edit Distance编辑距离(NM tag)- sam/bam格式解读进阶
sam格式很精炼,几乎包含了比对的所有信息,我们平常用到的信息很少,但特殊情况下,我们会用到一些较为生僻的信息,关于这些信息sam官方文档的介绍比较精简,直接看估计很难看懂. 今天要介绍的是如何通过b ...
- Minimum edit distance(levenshtein distance)(最小编辑距离)初探
最小编辑距离的定义:编辑距离(Edit Distance),又称Levenshtein距离.是指两个字串之间,由一个转成还有一个所需的最少编辑操作次数.许可的编辑操作包含将一个字符替换成还有一个字符. ...
随机推荐
- GPS部标平台的架构设计(十)-基于Asp.NET MVC构建GPS部标平台
在当前很多的GPS平台当中,有很多是基于asp.NET+siverlight开发的遗留项目,代码混乱而又难以维护,各种耦合和关联,要命的是界面也没见到比Javascript做的控件有多好看,随着需求的 ...
- 寿司点餐系统Sprint1总结
为期十天的一个冲刺,说长不长,说短不短.从一开始的接收课程任务到第一次聚集讨论. 确定方案.实行方案,再到最后的决定结束第一个冲刺,都是大家一起讨论着加小小的默契一步步 向前.没有完美,但是总体完成的 ...
- Bloomberg面经准备: Josephus problem
Given a circular single linked list.Write a program that deletes every kth node until only one node ...
- UVALive 7143 Room Assignment(组合数学+DP)(2014 Asia Shanghai Regional Contest)
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=6 ...
- javascript中通过匿名函数进行事件绑定
- sublimeText jsformat 插件被当做病毒 virus
最近在个只可往他里面发邮件,不能往外上任何互联网的地方工作,用 sublimetext 要装个sublime 插件 jsformat 十分麻烦.用gmail邮箱发总是报病毒. 最后挨个尝试,发现是 j ...
- paper 121 :matlab中imresize函数
转自:http://www.cnblogs.com/rong86/p/3558344.html matlab中函数imresize简介: 函数功能:该函数用于对图像做缩放处理. 调用格式: B = i ...
- Android使用ndk-stack获取so奔溃堆栈
利用NDK做开发,因为各种原因的不小心,导致了闪退问题,没有stack的话,很难查到问题的所在.这时候ndk-stack出场了. 先看看如下DUMP信息: ********** Crash dump: ...
- 代码高亮美化插件-----SyntaxHighlighter
IT类文章博客,代码高亮美化插件-----SyntaxHighlighter 最近在做一个类似个人博客的网站,因为文章中会用到各种代码,主要是Javascript,CSS,PHP,XML等.这些代码如 ...
- [WCF]DomainServices客户端操作异常处理
作为个人备忘,不做排版.此扩展函数用于DomainServices的Load及SubmitChanges时处理Error信息,包括验证消息.实体冲突. public static string ToE ...