字符串编辑距离问题

  1 /*
  2 字符串编辑问题,给定一个源字符串和目的字符串,源字符串可以insert,delete,replace,求最少操作使其变成目标字符串,有两种方法,方法一采用
  3 动态规划方法,f[i][j]=min{f[i-1][j]+1,f[i+1][j]+1,f[i-1][j-1]+(s[i]==t[j]?0:1)}.方法二采用递归实现(这个是求相似度,意思是一样的),没有动态规划好
  4 两个子串一个到另一的距离和另一个到它的距离是一样的。
  5 */
  6
  7 #include <iostream>
  8 using namespace std;
  9 #include <string>
 10
 11 //动态规划方法,f[i][j]表示从【0--i】和【0---j】的最小操作数,
 12 /*
 13 f[i][j]=min{f[i-1][j]+1(此为删除s[i]操作),f[i][j-1]+1(此为增加d[j]操作,f[i-1][j-1]+(s[i]==d[j]?0:1)(此为,如果s[i]==d[j],则说明相等,不用操作,否则替换操作)
 14 f[0][0]=0;
 15 f[0][j]={0,1,2,3,4,5,6,....j};   //都为插入
 16 f[i][0]={0,1,2,3,.....i};         //都为删除
 17 */
 18
 19 int minoperation(const string & sour,const string & dest)
 20 {
 21     int row=sour.size();
 22     int colom=dest.size();
 23     if(row==0)               //直接插入或删除
 24         return colom;
 25     if(colom==0)
 26         return row;
 27     int ** result=new int * [row+1];
 28     if(result==NULL)
 29     {
 30         cout<<"wrong"<<endl;
 31         exit(1);
 32     }
 33     for(int i=0;i<=row;i++)
 34     {
 35         result[i]=new int[colom+1];
 36         if(result[i]==NULL)
 37         {
 38             cout<<"wrong"<<endl;
 39             exit(1);
 40         }
 41     }
 42     for(int i=0;i<=row;i++)
 43         result[i][0]=i;
 44     for(int j=1;j<=colom;j++)
 45         result[0][j]=j;
 46     for(int i=1;i<=row;i++)
 47         for(int j=1;j<=colom;j++)
 48         {
 49             result[i][j]=min(min(result[i-1][j]+1,result[i][j-1]+1),result[i-1][j-1]+(sour[i-1]==dest[j-1]?0:1));  //注意sour[i-1]是因为sour是从0开始,而result多了开始的0.
 50         }
 51     int tmp=result[row][colom];
 52     for(int i=0;i<=row;i++)
 53         delete[] result[i];
 54     delete[] result;
 55     return tmp;
 56 }
 57
 58 /*
 59 方法二,采用递归的方法
 60 s="ACAATCC"
 61 D="AGCATGC"
 62 两个指针分别指向两个序列,sbegin,dbegin.
 63 */
 64 int minoperation2(const string & sour,const string & dest,int sbegin,int send,int dbegin,int dend)
 65 {
 66     if(sbegin>send)
 67     {
 68         if(dbegin<dend)                //最后没有了,只能全删除或全添加上才能一样
 69         {
 70             return dend-dbegin+1;
 71         }
 72         else
 73             return 0;
 74     }
 75     if(dbegin>dend)
 76     {
 77         if(sbegin<send)           //最后没有了,只能全删除或全添加上才能一样
 78         {
 79             return send-sbegin+1;
 80         }
 81         else
 82             return 0;
 83     }
 84     if(sour[sbegin]==dest[dbegin])
 85     {
 86         return minoperation2(sour,dest,sbegin+1,send,dbegin+1,dend);
 87     }
 88     else
 89     {
 90         int t1=minoperation2(sour,dest,sbegin+1,send,dbegin+1,dend);
 91         int t2=minoperation2(sour,dest,sbegin,send,dbegin+1,dend);
 92         int t3=minoperation2(sour,dest,sbegin+1,send,dbegin,dend);
 93         return min(min(t1,t2),t3)+1;
 94     }
 95 }
 96 int main()
 97 {
 98     string source="ACAATCC";
 99     string dest="AGCATGC";
100     //cout<<minoperation(source,dest)<<endl;
101     cout<<minoperation2(source,dest,0,source.size(),0,dest.size())<<endl;
102     system("pause");
103 }

字符串编辑距离问题,布布扣,bubuko.com

时间: 2024-10-02 20:38:12

字符串编辑距离问题的相关文章

利用Trie树求多个字符串编辑距离的进一步优化

1.引言 题目的意思应该是:在一个给定的字典中,求与给定的字符串的编辑距离不大于2的所有的单词.原先写过两片关于此问题的文章,那两片篇章文章给出两种解决思路:其一是暴力求解法,这种方法最容易想到.就是将词典中的词一一与给定的字符串计算编辑距离,不大于2的输出,大于2的舍弃,这种方法思路简单但是很费时间.其二根据词典中这些词之间的编辑距离建立一个以单词为节点的Trie树,遍历的时候,通过计算根节点与给定字符串的编辑距离就可以排除掉一部分分支了,然后继续计算该字符串与剩余的分支的根的编辑距离,继续排

最长递增子序列 &amp;&amp; 最大子序列、最长递增子序列、最长公共子串、最长公共子序列、字符串编辑距离

http://www.cppblog.com/mysileng/archive/2012/11/30/195841.html 最长递增子序列问题:在一列数中寻找一些数,这些数满足:任意两个数a[i]和a[j],若i<j,必有a[i]<a[j],这样最长的子序列称为最长递增子序列. 设dp[i]表示以i为结尾的最长递增子序列的长度,则状态转移方程为: dp[i] = max{dp[j]+1}, 1<=j<i,a[j]<a[i]. 这样简单的复杂度为O(n^2),其实还有更好的方

【转】字符串编辑距离

原文:http://m.blog.csdn.net/blog/cqs_2012/17849877 题目 有两个字符串A和B,对A可以进行如下的操作:插入一个字符,删除一个字符,替换一个字符.问A可以通过最少多少次操作变为B?我们定义这个结果为字符串的最小编辑距离. 思路(借鉴九章算法的,感觉挺好,所以实现,共同学习) 字符串编辑距离归为DP题目,所以还是超好的 1 for(int i = 0;i<int(b.size()+1);i++) 2 dp[i] = new int[a.size()+1]

[算法]字符串编辑距离

来自编程之美的一题 许多程序会大量使用字符串.对于不同的字符串,我们希望能够有办法判断其相似程序.我们定义一套操作方法来把两个不相同的字符串变得相同,具体的操作方法为: 1.修改一个字符(如把“a”替换为“b”); 2.增加一个字符(如把“abdd”变为“aebdd”); 3.删除一个字符(如把“travelling”变为“traveling”); 比如,对于“abcdefg”和“abcdef”两个字符串来说,我们认为可以通过增加/减少一个“g”的方式来达到目的.上面的两种方案,都仅需要一 次

九章算法面试题15 字符串编辑距离

九章算法官网-原文网址 http://www.jiuzhang.com/problem/15/ 题目 有两个字符串A和B,对A可以进行如下的操作:插入一个字符,删除一个字符,替换一个字符.问A可以通过最少多少次操作变为B?我们定义这个结果为字符串的最小编辑距离. 解答 动态规划.设f[i][j]代表A的i个字符与B的前j个字符完美匹配上时,需要的最小操作次数.有状态转移方程如下: f[i][j] = max{f[i-1][j] + 1, f[i][j-1] + 1, f[i-1][j-1] +

计算字符串编辑距离

计算字符串编辑距离 题目描述:给定两个字符串,要求二者之间的编辑距离. 分析:字符串的编辑主要有三种方式:增加.删除和修改.这道题目按照递归的方式,逐个判断每个字符.具体而言,如果str1和str2的第一个字符相等,则往后移,编辑的距离为后续的字符串:如果第一个不等,则我们可以增加.删除和修改str1,也可以增加.删除和修改str2,还可以同时增加.删除和修改str1和str2.不管以何种方式修改哪一个字符串,这个编辑距离都+1. 代码如下: #include<iostream> #inclu

算法学习(十二)最大连续乘积子串、字符串编辑距离

最大连续乘积子串 题目描述:给一个浮点数序列,取最大乘积连续子串的值,例如-2.5,4,0,3,0.5,8,-1,则取出的最大乘积子串为3,0.5,8.也就是说,上述数组中,3,0.5,8这3个数的乘积3*0.5*8 = 12是最大的,而且是连续的. 分析: 注意子串和字序列的区别. 子串:是串的连续的部分. 子序列:是串中不改变顺序,但是是去掉个别元素的到新的序列. 1,连续数的乘积,最简单的就是穷举法,就是区间[i-j]之间的数的乘积,和最大值max比较,最后输出max.但是时间复杂度很大几

POJ 3356 AGTC(DP求字符串编辑距离)

给出两个长度小于1000的字符串,有三种操作,插入一个字符,删除一个字符,替换一个字符. 问A变成B所需的最少操作数(即编辑距离) 考虑DP,可以用反证法证明依次从头到尾对A,B进行匹配是不会影响答案的 令dp[i][j]表示A[i]~[lenA]变成B[j]~[lenB]的最优解. 如果把B[j]插入到A[i]前,dp[i][j]=dp[i][j+1]+1 如果删除A[i],dp[i][j]=dp[i+1][j]+1. 如果A[i]==B[j], dp[i][j]=dp[i+1][j+1].

Leetcode:Edit Distance 字符串编辑距离

原题戳我 Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.) You have the following 3 operations permitted on a word: a) Insert a character b) Delete a character c)