求解两个字符串的最长公共子串
2016-03-08 10:19
344 查看
一、前言
求解两个字符串的最长公共子串(Longest Common Substring, LCS)与求解两个字符串的最长公共子序列(Longest
Common Subsequence, LCS)是不一样的,求解最长公共子序列问题请参阅我的另一篇博客
http://blog.csdn.net/heart_love/article/details/50804301
假定给出两个字符串X=“abcdef"和Y=“abacdef"那么"a"、"ab"、"cdef"等都是其公共子串,其中"cdef"是X和Y的最长公共子串。
二、求解算法
对于两个字符串X={x1,x2,....xm}和Y={y1,y2,.....yn},我们利用一个二维数组c[i][j]来记录Xi与Yj是否相等,如果Xi == Yj,那么c[i][j] = 1,否则c[i][j] = 0。如下图所示:
![](http://img.blog.csdn.net/20160308110721599?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
然后我们遍历所有的斜下角,找出最多的连续为1的值。这种遍历太浪费时间,我们把算法改进一下:如果Xi == Yj,那么c[i][j] =
c[i - 1][j - 1] + 1,否则c[i][j] = 0。如下图所示:
![](http://img.blog.csdn.net/20160308112315730?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
然后我们找出二维数组中的最大值,即可求出其最长公共子串。此算法还有一个缺点就是所使用的二维数组占用了过的内存,我们继续对算法进行改进,使用一维数组来保存值:具体算法如下面的代码所示
求解两个字符串的最长公共子串(Longest Common Substring, LCS)与求解两个字符串的最长公共子序列(Longest
Common Subsequence, LCS)是不一样的,求解最长公共子序列问题请参阅我的另一篇博客
http://blog.csdn.net/heart_love/article/details/50804301
假定给出两个字符串X=“abcdef"和Y=“abacdef"那么"a"、"ab"、"cdef"等都是其公共子串,其中"cdef"是X和Y的最长公共子串。
二、求解算法
对于两个字符串X={x1,x2,....xm}和Y={y1,y2,.....yn},我们利用一个二维数组c[i][j]来记录Xi与Yj是否相等,如果Xi == Yj,那么c[i][j] = 1,否则c[i][j] = 0。如下图所示:
然后我们遍历所有的斜下角,找出最多的连续为1的值。这种遍历太浪费时间,我们把算法改进一下:如果Xi == Yj,那么c[i][j] =
c[i - 1][j - 1] + 1,否则c[i][j] = 0。如下图所示:
然后我们找出二维数组中的最大值,即可求出其最长公共子串。此算法还有一个缺点就是所使用的二维数组占用了过的内存,我们继续对算法进行改进,使用一维数组来保存值:具体算法如下面的代码所示
#include <iostream> using namespace std; char *lcs(const char X[],const char Y[],char str[]); int main() { char str[1024]; lcs("aecdfab", "abecdfa", str); cout << str << endl; } char *lcs(const char X[], const char Y[], char str[]) { int Xlen = strlen(X); int Ylen = strlen(Y); int *pre = (int *)malloc(sizeof(int)* Ylen);//用来记录前一行的数据 int *cur = (int *)malloc(sizeof(int)* Ylen);//用来记录当前行的数据 int max[2] = { 0 }; //max[0]用来记录最长公共子串的长度,max[1]用来记录此时X串的下表 int i, j; /*初始化pre数组*/ for (j = 0; j < Ylen; j++) { if (X[0] == Y[j]) { pre[j] = 1; max[0] = pre[j] > max[0] ? pre[j]:max[0]; } else pre[j] = 0; } for (i = 1; i < Xlen; i++) { for (j = 0; j < Ylen;j++) { if (j == 0) { if (X[i] == Y[0]) { cur[0] = 1; max[0] = cur[0] > max[0] ? cur[0] : max[0]; max[1] = cur[0] > max[0] ? i : max[1]; }else cur[0] = 0; }else { if (X[i] == Y[j]) { cur[j] = pre[j - 1] + 1; max[1] = cur[j] > max[0] ? i : max[1]; max[0] = cur[j] > max[0] ? cur[j] : max[0]; } else cur[j] = 0; pre[j - 1] = cur[j - 1]; } } pre[j] = cur[j]; } strncpy(str, X + max[1] - max[0] + 1, max[0]); str[max[0]] = '\0'; free(pre); free(cur); return str; }运行结果为:
相关文章推荐
- 如何在SpringMVC中获取request对象
- POJ 3384 Feng Shui 半平面交
- jQuery获取屏幕的宽度
- SPRING IN ACTION 第4版笔记-第九章Securing web applications-008-使用非关系型数据库时如何验证用户(自定义UserService)
- static inline func 内联函数
- jQuery实现带水平滑杆的焦点图动画插件
- linux下用/proc/stat文件来计算cpu的利用率
- java设计模式——创建型之原型模式
- 支付系统开发中可能遇到的问题
- 前端学习-jQuery源码学习
- 查看用户登录命令last
- Leetcode ☞ 147. Insertion Sort List ☆
- 11.leetcode题目171: Excel Sheet Column Number
- 正则表达式之PHP篇split 与 php函数explode
- 数据库精选1
- ijkplayer编译脚本分析(一)——init-android.sh
- hive1.2.1 在hadoop 2.6.0中搭建的问题
- hihocoder: hiho一下 第八十八周 88
- 2015级C++第2周实践项目
- mongodb权限