编辑距离问题

Posted lineaar

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编辑距离问题相关的知识,希望对你有一定的参考价值。

编辑距离问题: 
      编辑距离,又称Levenshtein距离,是一种字符串之间相似度计算的方法,指两个字符串之间,由一个转换成另一个所需的最少编辑次数。有效的编辑操作为单个字符的替换、插入和删除。对给定两个字符串S、T,将S转换成T所需要的删除,插入,替换操作的数量就叫做S到T的编辑路径。而最短的编辑路径就叫做字符串S和T的编辑距离。举个例子:S=“eeba”   T="abac"   我们可以按照这样的步骤转变:(1) 将S中的第一个e变成a;(2) 删除S中的第二个e;(3)在S中最后添加一个c; 那么S到T的编辑路径就等于3。当然,这种变换并不是唯一的,但如果3是所有变换中最小值的话。那么我们就可以说S和T的编辑距离等于3了。

解决思路:

      还是这个例子:S=“eeba”   T="abac" 。我们发现当S只有一个字符e、T只有一个字符a的时候,我们马上就能得到S和T的编辑距离edit(0,0)=1(将e替换成a)。那么如果S中有1个字符e、T中有两个字符ab的时候,我们是不是可以这样分解:edit(0,1)=edit(0,0)+1(将e替换成a后,在添加一个b)。如果S中有两个字符ee,T中有两个字符ab的时候,我们是不是可以分解成:edit(1,1)=min(edit(0,1)+1, edit(1,0)+1, edit(0,0)+f(1,1)),即将长字符串间的编辑距离问题一步一步转换成短字符串间的编辑距离问题,直至只有1个字符的串间编辑距离为1。 

       用EDIT(i,j)表示长度为i的字符串转换成长度为j的字符串的编辑距离,f(i,j)表示第一个字符串的第i个字符和第二个字符串的第j个字符是否相同,若相同则f(i,j)=0,否则f(i,j)=1,则:

EDIT(i,j)=i; j==0;

EDIT(i,j)=j; i==0;

EDIT(i,j)=min(EDIT(i-1,j)+1,EDIT(i,j-1)+1,EDIT(i-1,j-1)+f(i,j)); i>0且j>0;

参考出处:http://hxraid.iteye.com/blog/615469

// bianjiwenti.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
#include<string>
using namespace std;

int min(int a, int b)
{
	return a < b ? a : b;
}

int edit(string str1, string str2)
{
	int max1 = str1.length();
	int max2 = str2.length();

	int **ptr = new int*[max1 + 1];              //动态申请二维数组空间
	for (int i = 0; i < max1 + 1; i++)
		ptr[i] = new int[max2 + 1];

	for (int i = 0; i < max1 + 1; i++)          //连续删除i个
		ptr[i][0] = i;
	for (int i = 1; i < max2 + 1; i++)       //连续插入i个
		ptr[0][i] = i;
	for(int i=1;i<max1+1;i++)
		for (int j = 1; j < max2 + 1; j++)
		{
			int d;
			int temp = min(ptr[i - 1][j] + 1, ptr[i][j - 1] + 1);
			if (str1[i - 1] == str2[j - 1])   //即第i个元素不用操作
				d = 0;
			else
				d = 1;
			ptr[i][j] = min(ptr[i - 1][j - 1] + d, temp);
		}

	cout << "--------------------------------------------------------------" << endl;
	for (int i = 0; i < max1 + 1; i++)
	{
		for (int j = 0; j < max2 + 1; j++)
			cout << ptr[i][j]<<\'\\t\';
		cout << endl;
	}
	cout << "--------------------------------------------------------------" << endl;
	int num = ptr[max1][max2];

	for (int i = 0; i < max1 + 1; i++)
	{
		delete[] ptr[i];
		ptr[i] = NULL;
	}

	delete[] ptr;
	ptr = NULL;

	return num;			
}


int main()
{
	string str1 = "study";
	string str2 = "tostudy";
	int num = edit(str1, str2);
	cout << num;
	while (1);
    return 0;
}

 

以上是关于编辑距离问题的主要内容,如果未能解决你的问题,请参考以下文章

如何减少两行浏览片段之间的距离

VsCode编辑器如何自定义代码片段

编辑距离leetcode

如何在 Django Summernote 中显示编程片段的代码块?

简单的方法来分享/讨论/协作的代码片段?

C#通过编辑距离计算两个字符串的相似度的代码