动态规划-编辑距离

设A和B是2个字符串。要用最少的字符操作将字符串A转换为字符串B。这里所说的字符操作包括 (1)删除一个字符; (2)插入一个字符; (3)将一个字符改为另一个字符。 将字符串A变换为字符串B所用的最少字符操作数称为字符串A到 B的编辑距离,记为d(A,B)。 对于给定的字符串A和字符串B,计算其编辑距离 d(A,B)。

输入格式:

第一行是字符串A,文件的第二行是字符串B。

提示:字符串长度不超过2000个字符。

输出格式:

输出编辑距离d(A,B)

输入样例:

在这里给出一组输入。例如:

fxpimu
xwrs

输出样例:

在这里给出相应的输出。例如:

5

假设序列S和T的长度分别为m和n, 两者的编辑距离表示为dp[m][n]. 则对序列进行操作时存在以下几种情况:

a, 当S和T的末尾字符相等时, 对末尾字符不需要进行上述定义操作中(亦即"编辑")的任何一个, 也就是不需要增加计数. 则满足条件: dp[m][n] = dp[m - 1][n - 1].

b, 当S和T的末尾字符不相等时, 则需要对两者之一的末尾进行编辑, 相应的计数会增加1.

b1, 对S或T的末尾进行修改, 以使之与T或S相等, 则此时dp[m][n] = dp[m - 1][n - 1] + 1;

b2, 删除S末尾的元素, 使S与T相等, 则此时dp[m][n] = dp[m - 1][n] + 1;

b3, 删除T末尾的元素, 使T与S相等, 则此时dp[m][n] = dp[m][n - 1] + 1;

b4, 在S的末尾添加T的尾元素, 使S和T相等, 则此时S的长度变为m+1, 但是此时S和T的末尾元素已经相等, 只需要比较S的前m个元素与T的前n-1个元素, 所以满足dp[m][n] = dp[m][n - 1] + 1;

b5, 在T的末尾添加S的尾元素, 使T和S相等, 此时的情况跟b4相同, 满足dp[m][n] = dp[m - 1][n] + 1;

c, 比较特殊的情况是, 当S为空时, dp[0][n] = n; 而当T为空时, dp[m][0] = m; 这个很好理解, 例如对于序列""和"abc", 则两者的最少操作为3, 即序列""进行3次插入操作, 或者序列"abc"进行3次删除操作.

所以, 以上我们不难推出编辑距离的动态规划方程为:

 
#include<iostream>
using namespace std;
int d[2001][2001];
int main()
{
    int n,m,i,j,k;
    string a,b;
    while(cin>>a>>b)
    {
        n=a.length();
        m=b.length();
        for(i=0;i<=n;i++)
            d[i][0]=i;
        for(j=0;j<=m;j++)
            d[0][j]=j;
        for(i=1;i<=n;i++)
            for(j=1;j<=m;j++)
            {
                k=min(d[i-1][j]+1,d[i][j-1]+1);
                if(a[i-1]!=b[j-1])d[i][j]=min(k,d[i-1][j-1]+1);
                else d[i][j]=min(k,d[i-1][j-1]);
            }
        cout<<d[n][m]<<‘\n‘;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/MTstory/p/11715855.html

时间: 2024-10-29 03:37:04

动态规划-编辑距离的相关文章

动态规划--编辑距离算法

设A和B是2个字符串.要用最少的字符操作将字符串A转换为字符串B.这里所说的字符操作包括 (1)删除一个字符: (2)插入一个字符: (3)将一个字符改为另一个字符. 将字符串A变换为字符串B所用的最少字符操作数称为字符串A到 B的编辑距离,记为d(A,B). 对于给定的字符串A和字符串B,计算其编辑距离 d(A,B). 对于每一个对应字符有三种解决方法案: C++代码: #include <iostream> #include <string.h> using namespace

[题记-动态规划] 编辑距离 - leetcode

题目: 编辑距离 给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 . 你可以对一个单词进行如下三种操作: 插入一个字符删除一个字符替换一个字符 示例 1: 输入:word1 = "horse", word2 = "ros"输出:3解释:horse -> rorse (将 'h' 替换为 'r')rorse -> rose (删除 'r')rose -> ros (删除 'e')示例 2:

简单线性动态规划 —— 编辑距离

可用滚动数组压缩空间,略 if s[i] = t[j] then dp[i, j] := dp[i-1, j-1]          // no operation required else dp[i, j] := min( dp[i-1, j] + 1,     // a deletion dp[i, j-1] + 1,     // an insertion dp[i-1, j-1] + 1  // a substitution ) 加权的情况: dp[i][j] := min( dp[i

2017校招常考算法题归纳&amp;典型题目汇总

2017校招即将来临,我们为大家整理了2017校招的常考算法类型,以及对应的典型题目. 另附参考答案地址:http://www.jiuzhang.com/solution/ 数学 尾部的零 斐波纳契数列 x的平方根 x的平方根 2 大整数乘法 骰子求和 最多有多少个点在一条直线上 超级丑数 比特位操作 将整数A转换为B 更新二进制位 二进制表示 O(1)时间检测2的幂次 二进制中有多少个1 动态规划 编辑距离 正则表达式匹配 交叉字符串 乘积最大子序列 二叉树中的最大路径和 不同的路径 通配符匹

校招的常考算法类型以及对应的典型题目

数学 尾部的零斐波纳契数列x的平方根x的平方根2大整数乘法骰子求和最多有多少个点在一条直线上超级丑数 比特位操作 将整数A转换为B更新二进制位二进制表示O(1)时间检测2的幂次二进制中有多少个1 动态规划 编辑距离正则表达式匹配交叉字符串乘积最大子序列二叉树中的最大路径和不同的路径通配符匹配 堆 滑动窗口的中位数数据流中位数最高频的K个单词接雨水堆化排序矩阵中的从小到大第k个数 二叉树 二叉树中序遍历二叉树的序列化和反序列化子树最近公共祖先二叉树的层次遍历将二叉树拆成链表在二叉查找树中插入节点

动态规划:编辑距离和通配符匹配

编辑距离指通过修改,删除,添加.使得两个字符串能够相同所需要操作的次数. edit(i,j) if S1[i]==S2[j] temp=0; else temp=1; edit(i,j)=min(A[i-1][j-1]+temp,A[i-1][j]+1,A[i][j-1]+1); edit(i,j)=min(A[i-1][j-1]+temp,A[i-1][j]+1,A[i][j-1]+1);公式可以理解成, 如果由S1或者增加,删除,替换一次,同两个字符串的推前一个的编辑距离比较.最小值即编辑距

编辑距离 动态规划

动态规划经常被用来作为这个问题的解决手段之一. 整数 Levenshtein距离(字符串 str1[1..m], 字符串 str2[1..n]) //声明变量, d[i , j]用于记录str1[1...i]与str2[1..j]的Levenshtein距离 int d[0..m, 0..n] //初始化 for i from 0 to m d[i, 0] := i for j from 0 to n d[0, j] := j //用动态规划方法计算Levenshtein距离 for i fro

两个字符串的编辑距离-动态规划方法

两个字符串的编辑距离-动态规划方法[转载] 概念 字符串的编辑距离,又称为Levenshtein距离,由俄罗斯的数学家Vladimir Levenshtein在1965年提出.是指利用字符操作,把字符串A转换成字符串B所需要的最少操作数.其中,字符操作包括: 删除一个字符     a) Delete a character 插入一个字符     b) Insert a character 修改一个字符     c) Replace a character 例如对于字符串"if"和&qu

8.动态规划(1)——字符串的编辑距离

动态规划的算法题往往都是各大公司笔试题的常客.在不少算法类的微信公众号中,关于“动态规划”的文章屡见不鲜,都在试图用最浅显易懂的文字来描述讲解动态规划,甚至有的用漫画来解释,认真读每一篇公众号推送的文章实际上都能读得懂,都能对动态规划有一个大概了解. 什么是动态规划?通俗地理解来说,一个问题的解决办法一看就知道(穷举),但不能一个一个数啊,你得找到最优的解决办法,换句话说题目中就会出现类似“最多”.“最少”,“一共有多少种”等提法,这些题理论上都能使用动态规划的思想来求解.动态规划与分治方法类似