最长公共字串和最长连续公共字串 以及最小编辑距离

最长公共字串+后缀数组(一篇文章)

注意事项:局部变量数组最多保存1M空间,而全局变量和静态变量可以保存更大

实现,很有很多变形

#include <iostream>

#include <stdio.h>

  1. #include <fstream>
  2. #include <string.h>
  3. #include <algorithm>
  4. using namespace std; 
  5. int comp(const void * a1,const void *a2){
  6. return strcmp(*(char **)a1,*(char **)a2);
  7. }
  8. int com_len(const char * a1,const char *a2){
  9. int len = 0;
  10. int i = 0;
  11. while(a1[i]!='\0' && a2[i]!='\0'){
  12. if(a1[i]==a2[i]) {
  13. i++;
  14. len++;
  15. } else {
  16. break;
  17. }
  18. }
  19. return len;
  20. }
  21. int main(){
  22. static char a[10000000];
  23. static char* b[10000000];
  24. ifstream in("kjv.txt");
  25. int l=0;
  26. while(!in.eof()){
  27. a[l++]=in.get();
  28. b[l-1] = (char *)&a[l-1];
  29. if(l==9999999) break;  //避免溢出
  30. }
  31. a[l]='\0';
  32. //sort(b,b+l,comp);//字符数组无法用sort排序
  33. qsort(b,l,sizeof(char *),comp); // int (*comp)(const void*,const void *)
  34. cout<<"sort"<<endl;
  35. int maxlen = 0;
  36. int index=0;
  37. for(int i=0;i<l-1;i++) {
  38. int clen = com_len(b[i],b[i+1]);
  39. if(clen>maxlen) {
  40. maxlen = clen;
  41. index = i;
  42. }
  43. }
  44. cout<<maxlen<<endl;
  45. b[index][maxlen]='\0';
  46. cout<<b[index]<<endl;
  47. cout<<b[index+1]<<endl;
  48. return 0;
  49. }

结果:

   precious things, the silver, and the gold, and the spices, and the

   precious ointment, and all the house of his armour, and all that was

   found in his treasures: there was nothing in his house, nor in all his

   dominion, that Hezekiah shewed them not.

两个字符串的最大公共子串,可以用动态规划实现:

D[i][j] 表示以s1中第i个结束,s2中以第j个结束的最大公共字串,可以说是前缀数组(以某个字符结束)

D[i][j] = D[i-1][j-1] + 1 ( s1[i-1] == s2[j-1]

D[i][j] = 0; 

最长递增子序列

D[i] = max(s[i-1]>=s[j-1] ? D[j] + 1)  j 满足 [1,i-1]

  1. #include <iostream>
  2. #include <vector> 
  3. using namespace std;
  4. int  longseq(const string & input){
  5. int sz = input.size();
  6. if(sz==0) return 0;
  7. int maxlen = 0;
  8. int index = 0;
  9. vector<int> flag(sz+1,0);
  10. for(int i=1;i<=sz;i++) {
  11. int value=1;
  12. for(int j=i-1;j>=1;j--) {
  13. if(input.at(j-1)<=input.at(i-1)){
  14. if(flag[j]+1>value) {
  15. value = flag[j]+1;
  16. }
  17. }
  18. }
  19. flag[i]=value;
  20. if(value>maxlen) {
  21. maxlen =value;
  22. index = i;
  23. }
  24. }
  25. cout<<index<<endl;
  26. cout<<maxlen<<endl;
  27. return maxlen;
  28. }
  29. int main(){
  30. string s="12345123679";
  31. longseq(s);
  32. return 0;
  33. }

最大连续子序列之和

  1. #include <iostream>
  2. #include <vector>
  3. #include <limits.h>
  4. using namespace std;
  5. int longsum(const vector<int> & input){
  6. int maxvalue = INT_MIN;
  7. int sum = 0;
  8. int begin=0;
  9. int end = 0;
  10. int newbegin=0;
  11. for(int i=0;i<input.size();i++) {
  12. sum += input[i];
  13. if(sum>maxvalue) {
  14. maxvalue = sum;
  15. end = i;
  16. begin = newbegin;
  17. if(sum<0) {
  18. sum = 0;
  19. newbegin = i+1;
  20. }
  21. }
  22. for(int i=begin;i<=end;i++) cout<<input[i]<<endl;
  23. return maxvalue;
  24. }
  25. int main() {
  26. int a[]={-5,2,3,-9,4};
  27. vector<int> input(a,a+5);
  28. cout<<longsum(input)<<endl; 
  29. }

http://www.cnblogs.com/grenet/archive/2010/06/03/1750454.html

最长公共字串,满足的动态规划方程:

为了讲解计算LCS(A,B),特给予以下几个定义

  A=a1a2……aN,表示A是由a1a2……aN这N个字符组成,Len(A)=N

  B=b1b2……bM,表示B是由b1b2……bM这M个字符组成,Len(B)=M

  定义LCS(i,j)=LCS(a1a2……ai,b1b2……bj),其中0≤i≤N,0≤j≤M

  故:  LCS(N,M)=LCS(A,B)

      LCS(0,0)=0

      LCS(0,j)=0

      LCS(i,0)=0

 

  对于1≤i≤N,1≤j≤M,有公式一

  若ai=bj,则LCS(i,j)=LCS(i-1,j-1)+1

  若ai≠bj,则LCS(i,j)=Max(LCS(i-1,j-1),LCS(i-1,j),LCS(i,j-1))   LCS(i-1,j-1) <= MAX(LCS(i,j-1),LCS(i-1,j))

论证算法A的正确性(http://www.cnblogs.com/grenet/archive/2011/02/27/1959223.html)

       To find L(i,j) ,let a common subsequence of that length be denoted by S(i,j)=c1c2……cp , If ai=bj, we can do no better than by taking cp=ai and looking for c1……cp-1 as a common subsequence of length L(i,j)-1 of string A1,i-1 and B1,j-1. Thus , in this case ,L(i,j)=L(i-1,j-1)+1

      为了计算L(i,j),把长度和其相等的公共子序列定义为S(i,j)=c1c2……cp,如果ai=bj,则cp=ai,并且c1……cp-1A1,i-1B1,j-1的最长公共子序列,长度为L(i,j)-1。因此,在这种情况下,L(i,j)=L(i-1,j-1)+1

 

      If ai≠bj ,then cp is ai,bj, or neither (but not both). If cp is ai , then a solution C to problem(A1i,B1j) [written P(i,j)] will be a solution to P(i,j-1) since bj is not used. Similarly , if cp is bj , then we can get a solution to P(i,j)by solving P(i-1,j). If cp is neither, then a solution to either P(i-1,j) or P(i,j-1) will suffice . In determining the length of the solution, it is seen that L(i,j) [corresponding to P(i,j)] will be the maximum of L(i-1,j) and L(i,j-1).

      如果ai≠bj,则cp要么是ai,要么是bj,要么两者都不是(肯定不会都是)。如果cp=ai,因为bj不是C的元素,则求解C的问题(A1i,B1j)[写作P(i,j)]等同于求解P(i,j-1)。同样的,如果cp=bj,求解P(i,j)等同于求解P(i-1,j)。如果,cp两者都不是,则必是P(i-1,j)P(i,j-1)中的一个。求解的长度称为L(i,j)[和P(i,j)相一致]将会是L(i-1,j) 和L(i,j-1)中的最大值。

 

编辑距离:

A=a1a2……aN,表示A是由a1a2……aN这N个字符组成,Len(A)=N

  B=b1b2……bM,表示B是由b1b2……bM这M个字符组成,Len(B)=M

  定义LD(i,j)=LD(a1a2……ai,b1b2……bj),其中0≤i≤N,0≤j≤M

  故:  LD(N,M)=LD(A,B)

      LD(0,0)=0

      LD(0,j)=j

      LD(i,0)=i

 

  对于1≤i≤N,1≤j≤M,有公式一

  若ai=bj,则LD(i,j)=LD(i-1,j-1)

  若ai≠bj,则LD(i,j)=Min(LD(i-1,j-1),LD(i-1,j),LD(i,j-1))+1

http://www.kngine.com/#Know!q=atoi  (程序员搜索引擎)

 

利用该图进行推导。

http://www.cnblogs.com/SwordTao/p/3824980.html 

posted @ 2014-08-20 12:32  purejade  阅读(291)  评论(0)    收藏  举报