zoukankan      html  css  js  c++  java
  • 经典dp 编辑距离

    给定两个字符串S和T,对于T我们可以进行三种操作

    (1)在任意位置增加字符

    (2)删除字符

    (3)替换字符

    问最少多少次能把T变成S?

    设f(i,j)是S的前i位和T的前j位对齐的最小花费

    接下来分析每一位

    (1)如果S[i]==T[j],就不用任何修改,那么最小花费是f(i-1,j-1)

    (2)如果S[i]!=T[j],那么最小花费是f(i-1,j-1)+1

    (3)如果S的前i位已经和T的前(j-1)位对齐了,那么最小花费是f(i,j-1)+1

    (4)如果S的前(i-1)位已经和T的前j位对齐了,那么最小花费是f(i-1,j)+1

    综上,递推式是f(i,j)=min(f(i,j)+cost,f(i-1,j)+1,f(i,j-1)+1)

    最后分析一下初值:

    f(i,0)=i

    f(0,j)=j

    这就相当与把S或T的前i或j位全部删除的样子(好残忍……)

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    int f[1005][1005];
    int main()
    {
        char a[1005],b[1005];
        int lena,lenb,i,j,cost,mincost;
        while(~scanf("%s%s",a,b))
        {
            lena=strlen(a);
            lenb=strlen(b);
            for(i=0; i<lena; i++)
                f[i][0]=i;
            for(i=0; i<lenb; i++)
                f[0][i]=i;
            for(i=1; i<=lena; i++)
                for(j=1; j<=lenb; j++)
                {
                    if(a[i-1]==b[j-1]) cost=0;
                    else cost=1;
                    mincost=min(f[i][j-1]+1,f[i-1][j]+1);
                    f[i][j]=min(mincost,f[i-1][j-1]+cost);
                }
            printf("%d
    ",f[lena][lenb]);
            memset(f,0,sizeof(f));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    java学习之实例变量初始化
    rip中的连续子网以及不连续子网
    扫描工具
    WScript.SendKeys()的sendkeys发送组合键以及特殊字符
    sql 查询包含字符的数量统计
    leetcode题1Two sum 练习
    vs 2015密钥
    前端 边界圆角
    前端 字体样式
    前端 高级选择器 伪类选择器
  • 原文地址:https://www.cnblogs.com/general10/p/5244139.html
Copyright © 2011-2022 走看看