zoukankan      html  css  js  c++  java
  • 算法作业14——字符串编辑距离(期末大作业)

    1. 

    给定一个源串和目标串,能够对源串进行如下操作:

    1在任意位置上插入一个字符;

    2替换任意字符;

    3删除任意字符。

     

    例如:kitten > sitting

    操作

    源串

    目标串

    替换:k > s

    kitten

    sitten

    替换:e > i

    sitten

    sittin

    插入:g

    sittin

    sitting

    写一个程序,实现返回最小操作次数,使得对源串进行上述这些操作后等于目标串(源串和目标串的长度都小于2000)。

    2. 解析

    本题我选择的求解思路是动态规划。

    设s1,s2是两个字符串,其中s1是源串,s2是目标串,s1字符串长度是len1,s2字符串的长度是len2;

    dp[i][j]是s1[1,2,...,i]通过插入、替换、删除得到s2[1,2,...,j]的最少操作次数,最后的dp[len1][len2]就是从s1字符串变换到s2字符串的最小操作次数。dp[i][j]的值满足以下等式:

    实例:aacag > aatat

    a

    a

    t

    a

    t

    0

    1

    2

    3

    4

    5

    a

    1

    0

    1

    2

    3

    4

    a

    2

    1

    0

    1

    2

    3

    c

    3

    2

    1

    1

    2

    3

    a

    4

    3

    2

    2

    1

    2

    g

    5

    4

    3

    3

    2

    2

                                      dp

     

    (1)初始化:dp[0][j=0,...,s1.length]=j;

    dp[i=0,...,s2.length][0]=i;

    (2)i=1

    s1[1]=s2[1] => dp[1][1]=dp[0][0]=0

    s1[1]=s2[2] => dp[1][2]=dp[0][1]=1 插入a

    s1[1]<>s2[3] => dp[1][3]=min{dp[0][2],dp[1][2],dp[0][3]}+1=2 插入a,t

    s1[1]=s2[4] => dp[1][4]=dp[0][3]=3 插入a,t,a

    s1[1]<>s2[5] => dp[1][5]=min{dp[0][4],dp[1][4],dp[0][5]}+1=4 插入a,t,a,t

    (3)i=2

    s1[2]=s2[1] => dp[2][1]=dp[1][0]=1 删除a 

    s1[2]=s2[2] => dp[2][2]=dp[1][1]=0 

    s1[2]<>s2[3] => dp[2][3]=min{dp[1][2],dp[1][3],dp[2][2]}+1=1 插入t

    s1[2]=s2[4] => dp[2][4]=dp[1][3]=2  插入t,a

    s1[2]<>s2[5] => dp[2][5]=min{dp[1][4],dp[1][5],dp[2][4]}+1=3 插入t,a,t

    (4)i=3 

    s1[3]<>s2[1] => dp[3][1]=min{dp[2][0],dp[3][0],dp[2][1]}+1=2 删除a,c 

    s1[3]<>s2[2] => dp[3][2]=min{dp[2][1],dp[3][1],dp[2][2]}+1=1 删除c 

    s1[3]<>s2[3] => dp[3][3]=min{dp[2][2],dp[3][2],dp[2][3]}+1=1 替换c —> t

    s1[3]<>s2[4] => dp[3][4]=min{dp[2][3],dp[3][3],dp[2][4]}+1=2 替换c —> t,插入a 

    s1[3]<>s2[5] => dp[3][5]=min{dp[2][4],dp[3][4],dp[2][5]}+1=3 替换c —> t,插入a,t

    (5)i=4 

    s1[4]=s2[1] => dp[4][1]=dp[3][0]=3 删除a,a,c 

    s1[4]=s2[2] => dp[4][2]=dp[3][1]=2 删除a,c

    s1[4]<>s2[3]=>dp[4][3]=min{dp[3][2],dp[4][2],dp[3][3]}+1=2 删除a,替换c—>t或删除c,替换a—>t

    s1[4]=s2[4] => dp[4][4]=dp[3][3]=1 替换c—> t

    s1[4]<>s2[5] => dp[4][5]=min{dp[3][4],dp[4][4],dp[3][5]}+1=2 替换c—> t,插入t

    (6)i=5 

    s1[5]<>s2[1] => dp[5][1]=min{dp[4][0],dp[5][0],dp[4][1]}+1=4 删除a,c,a,g 

    s1[5]<>s2[2] => dp[5][2]=min{dp[4][1],dp[5][1],dp[4][2]}+1=3 删除c,a,g

    s1[5]<>s2[3] => dp[5][3]=min{dp[4][2],dp[5][2],dp[4][3]}+1=3 替换c—> t,删除a,g或替换a—> t,删除c,g或替换g —> t,删除a,c 

    s1[5]<>s2[4] => dp[5][4]=min{dp[4][3],dp[5][3],dp[4][4]}+1=2 替换c—> t,删除g或替换g—> t,删除c 

    s1[5]<>s2[5] => dp[5][5]=min{dp[4][4],dp[5][4],dp[4][5]}+1=2 替换c —> t,替换g —> t  

     

    所以从源串aacag变换到目标串aatat的最小操作次数是dp[5][5]=2

    3. 设计

    (1)输入源串s1,目标串s2

    (2)len1=s1.length(),len2=s2.length()

    (3) oper()

    dp[i=0,1, ... , len1][0]=i;//初始化

    dp[0][j=0,1, ... ,len2]=j;//初始化

    For i = 1 to len1

    For j = 1 to len2

    //字符相同,不操作

    If s1[i-1]=s2[j-1] then dp[i][j]=dp[i-1][j-1]

    //字符不同,在原有的最小操作数的基础上+1

    Else dp[i][j]=min{dp[i-1][j-1],dp[i-1][j],dp[i][j-1]}+1;

    Return dp[len1][len2]

    (4)输出dp[len1][len2]

    4.分析

    如上设计,两层for循环即可解题,所以

    设源串字符串长度为m,目标串长度为n,则时间复杂度=O(m*n)

    5.源码

    https://github.com/2579081436/algorithm.github.io

  • 相关阅读:
    第11组 Beta版本演示
    第11组 Beta冲刺(5/5)
    第11组 Beta冲刺(4/5)
    第11组 Beta冲刺(3/5)
    第11组 Beta冲刺(2/5)
    第11组 Beta冲刺(1/5)
    第11组 Alpha冲刺(2/6)
    第11组 Alpha冲刺(1/6)
    第11组 团队Git现场编程实战
    团队项目-需求分析报告
  • 原文地址:https://www.cnblogs.com/-happy-/p/14857120.html
Copyright © 2011-2022 走看看