求两个字符串最长公共子串

一.问题描述:

最长公共子串 (LCS-Longest Common Substring) LCS问题就是求两个字符串最长公共子串的问题。比如输入两个字符串"ilovechina"和“chinabest”的最长公共字符串有"china",它们的长度是5.

二.解法

解法就是用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为1,否则为0。然后求出对角线最长的1序列,其对应的位置就是最长匹配子串的位置。如下图:

          i   l   o  v  e  c   h  i  n  a

        c    0  0  0  0  0  1  0  0  0  0

        h    0  0  0  0  0  0  1  0  0  0

        i     1  0  0  0  0  0  0  1  0  0

        n    0  0  0  0  0  0  0  0  1  0

        a    0  0  0  0  0  0  0  0  0  1

        b    0  0  0  0  0  0  0  0  0  0

        e    0  0  0  0  1  0  0  0  0  0

        s    0  0  0  0  0  0  0  0  0  0

        t    0  0  0  0  0  0  0  0  0  0

由于要得到结果还要找到此矩阵中最长的1对角线序列即上图中的红色部分,需要花一定的时间,于是出现了下面的改进,

          i   l   o  v  e  c   h  i  n  a

        c    0  0  0  0  0  1  0  0  0  0

        h    0  0  0  0  0  0  2  0  0  0

        i     1  0  0  0  0  0  0  3  0  0

        n    0  0  0  0  0  0  0  0  4  0

        a    0  0  0  0  0  0  0  0  0  5

        b    0  0  0  0  0  0  0  0  0  0

        e    0  0  0  0  1  0  0  0  0  0

        s    0  0  0  0  0  0  0  0  0  0

        t    0  0  0  0  0  0  0  0  0  0

改进算法:当字符匹配的时候,我们并不是简单的给相应元素赋上1,而是赋上其左上角元素的值加一。我们用个标记变量来标记矩阵中值最大的元素的位置,在矩阵生成的过程中来判断当前生成的元素的值是不是最大的,据此来改变标记变量的值,那么到矩阵完成的时候,最长匹配子串的位置和长度就已经出来了。

代码:

 1 #define M 100
 2 char *myLCS(char *str1,char *str2)
 3 {
 4     /** 遍历两个字符串每个字符串中的每个字符都和另一个字符串中的所有字符判断 */
 5     // 1. 获取两个字符串长度
 6     int length1 = (int)strlen(str1);
 7     int length2 = (int)strlen(str2);
 8     // 2. 创建并初始化矩阵
 9     int matrix[M][M] = {0};
10     /*int **matrix = (int **)malloc(sizeof(int*)*length1);
11     for (int i = 0; i< length1;i++)
12     {
13         matrix[i] = (int *)malloc(sizeof(int)*length2);
14     }*/
15     int startIndex = 0;
16     int endIndex = 0;
17     int maxLenth = 0;
18
19     // 3. 遍历
20     for (int i = 0; i < length1; i++)
21     {
22         for (int j = 0; j < length2; j++)
23         {
24             if (str1[i] == str2[j])
25             {
26                 // 第一行 或 第一列 相等的初始化为1 其余以他们左上角值加1
27                 if ((i == 0) || (j == 0))
28                 {
29                     matrix[i][j] = 1;
30                 }
31                 else // 左上角的值加1
32                 {
33                     matrix[i][j] = matrix[i-1][j-1] + 1;
34                 }
35             }
36             else // 不相等置为0
37             {
38                 matrix[i][j] = 0;
39             }
40             if (matrix[i][j] > maxLenth)
41             {
42                 maxLenth = matrix[i][j];
43                 endIndex = j;
44             }
45         }
46     }
47     // 起始位置 =  结束位置 - maxlength + 1;
48     startIndex = endIndex - maxLenth +1;
49     for (int k = 0; k < maxLenth; k++)
50     {
51         printf("%c",str2[startIndex++]);
52     }
53     return str1;
54 }

测试代码:

1 int main(int argc, const char * argv[]) {
2
3     char *s1 = "ilovechina";
4     char *s2 = "chinabest";
5     myLCS(s1,s2);
6     return 0;
7 }

结果:

china

时间: 2024-10-03 13:04:05

求两个字符串最长公共子串的相关文章

求两个字符串最长公共子串(动态规划)

code如下: //Longest common sequence, dynamic programming method void FindLCS(char *str1, char *str2) { if(str1 == NULL || str2 == NULL) return; int length1 = strlen(str1)+1; int length2 = strlen(str2)+1; int **csLength,**direction;//two arrays to recor

两个字符串最长公共子串的问题

算法的基本思想: 当字符匹配的时候,不是简单的给相应元素赋上1,而是赋上其左上角元素的值加一. 我们用两个标记变量来标记矩阵中值最大的元素的位置,在矩阵生成的过程中来判断 当前生成的元素的值是不是最大的,据此来改变标记变量的值,那么到矩阵完成的时 候,最长匹配子串的位置和长度就已经出来了.===========================================================================程序:#include<string.h> #define

java实现字符串匹配问题之求两个字符串的最大公共子串

转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/38924981 近期在项目工作中有一个关于文本对照的需求,经过这段时间的学习,总结了这篇博客内容:求两个字符串的最大公共子串. 算法思想:基于图计算两字符串的公共子串.详细算法思想參照下图: 输入字符串S1:achmacmh    输入字符串S2:macham 1)第a步,是将字符串s1,s2分别按字节拆分,构成一个二维数组: 2)二维数组中的值如b所看到的,比方第一行第一列的值

Python基础-求两个字符串最长公共前轴

最长公共前缀,输入两个字符串,如果存在公共前缀,求出最长的前缀,如果没有输出no.如“distance”和“discuss”的最长公共前缀是“dis”. s1 = input('请输入第1个字符串-->') s2 = input('请输入第2个字符串-->') # 判断两个字符串长度,避免循环溢出. if len(s1) < len(s2): n = len(s1) else: n = len(s2) # 把s1转换为list L1 = list(s1) # 把s2转换为list L2

求两个字符串的最大公共子串

1 #include <stdio.h> 2 #include <string.h> 3 4 void substr(char *s1, char *s2) 5 { 6 /* 1.设长串开始位置 p, 最大匹配串开始 结束位置 maxStart, maxEnd*/ 7 char *p = s1, *maxStart = s1, *maxEnd = s1; 8 char *q = s2; /* 设短串*/ 9 10 if(strlen(s1)<strlen(s2))/* 判断长

c++ KMP求两个字符串的最大公共子串

1 #include <iostream> 2 #include <string> 3 #include <cassert> 4 using namespace std; 5 6 void KMPStrMatching(string S, string P, int *N, int &start, int &len) 7 { 8 int j= 0; // 模式的下标变量 9 int i = 0; // 目标的下标变量 10 int pLen = P.le

UVA 题目760 DNA Sequencing (后缀数组求两个串最长公共子串,字典序输出)

 DNA Sequencing  A DNA molecule consists of two strands that wrap around each other to resemble a twisted ladder whose sides, made of sugar and phosphate molecules, are connected by rungs of nitrogen-containing chemicals called bases. Each strand is

[小作品][JS][JQuery]求两个字符串的最大公共串

算法大概描述就是,分别用两个字符串作为横坐标和纵坐标建一个矩阵,遇到横竖字符相同的时候把这点的值设成1,否则设成零,最后矩阵中最长的不为零的对角线就是最大子字串. 例如:   m a c h i a 0 1 0 0 0 b 0 0 0 0 0 m 1 0 0 0 0 a 0 1 0 0 0 c 0 0 1 0 0 这样有点问题:建完矩阵还要去找最长对角线,麻烦. 解决方案是:相等时不只把矩阵元素设为“1”,而是设成它左上角的元素值加一. 例如:   m a c h i a 0 1 0 0 0 b

POJ 3450 Corporate Identity 求所有字符的最长公共子串

Description Beside other services, ACM helps companies to clearly state their "corporate identity", which includes company logo but also other signs, like trademarks. One of such companies is Internet Building Masters (IBM), which has recently a