Chinaunix首页 | 论坛 | 博客
  • 博客访问: 243924
  • 博文数量: 62
  • 博客积分: 973
  • 博客等级: 准尉
  • 技术积分: 530
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-16 23:25
文章分类

全部博文(62)

文章存档

2013年(1)

2012年(14)

2011年(47)

分类: C/C++

2011-12-12 19:20:06


找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的。其实这又是一个序贯决策问题,可以用动态规划来求解。我们采用一个二维矩阵来记录中间的结果。这个二维矩阵怎么构造呢?直接举个例子吧:"bab"和"caba"(当然我们现在一眼就可以看出来最长公共子串是"ba"或"ab")

   b  a  b

c  0  0  0

a  0  1  0

b  1  0  1

a  0  1  0

我们看矩阵的斜对角线最长的那个就能找出最长公共子串。

不过在二维矩阵上找最长的由1组成的斜对角线也是件麻烦费时的事,下面改进:当要在矩阵是填1时让它等于其左上角元素加1。

   b  a  b

c  0  0  0

a  0  1  0

b  1  0  2

a  0  2  0

这样矩阵中的最大元素就是 最长公共子串的长度。

在构造这个二维矩阵的过程中由于得出矩阵的某一行后其上一行就没用了,所以实际上在程序中可以用一维数组来代替这个矩阵。


// Eequal matrix:            arr matrix:
//   a b a b                   a b a b
// c 0 0 0 0                 c 0 0 0 0
// a E 0 1 0         ==>     a 1 0 1 0        ==>  aba
// b 0 E 0 1                 b 1 2 1 2
// a 1 0 E 0                 a 1 2 3 2

  1. // 亲测,部分原创。
  2. // 参考://blog.csdn.net/wangwh485/article/details/6754764

  3. #include "stdafx.h"
  4. #include <string.h>
  5. #include <stdlib.h>

  6. #define MSTRLEN 100

  7. char* maxCommStr(char *str_x, char *str_y, int *longest)
  8. {
  9.     int xlen = strlen(str_x);
  10.     int ylen = strlen(str_y);
  11.     int i,j,max,end;
  12.     char *p_ret = NULL;
  13.     int arr[MSTRLEN][MSTRLEN];

  14.     if(NULL == str_x || NULL == str_y)
  15.         return NULL;
  16.     // initial
  17.     max=end=0;
  18.     for(i=0; i<MSTRLEN; ++i)
  19.     {
  20.         for(j=0; j<MSTRLEN; ++j)
  21.         {
  22.             arr[i][j] = 0;
  23.         }
  24.     }
  25.     // find longest commen of the two string
  26.     for(i=0; i<ylen; ++i)
  27.     {
  28.         for(j=0; j<xlen; ++j)
  29.         {
  30.             if(str_x[j] == str_y[i])
  31.             {
  32.                 if(0 == j || 0 == i)
  33.                     arr[i][j] = 1;
  34.                 else
  35.                     arr[i][j] = arr[i-1][j-1] + 1;
  36.             }
  37.             if(arr[i][j] > max)
  38.             {
  39.                 max = arr[i][j];
  40.                 end = j;
  41.             }
  42.         }
  43.         for(j=0; j<xlen; ++j)
  44.         {
  45.             printf("%d ", arr[i][j]);
  46.         }
  47.         printf("\n");
  48.     }
  49.     // deal with return value
  50.     *longest = max;
  51.     p_ret = (char *)malloc(max+1);
  52.     for(i=0; i<max; i++)
  53.     {
  54.         p_ret[i] = str_x[end+1-max+i];
  55.     }
  56.     p_ret[i] = '\0';

  57.     return p_ret;
  58. }

  59. // a better one
  60. char* strLCS(char *str_x, char *str_y, int *longest)
  61. {
  62.     int xlen = strlen(str_x);
  63.     int ylen = strlen(str_y);
  64.     int i,j,max,end;
  65.     char *p_ret = NULL;
  66.     int tmp[MSTRLEN], arr[MSTRLEN];

  67.     if(NULL == str_x || NULL == str_y)
  68.         return NULL;
  69.     // initial
  70.     max=end=0;
  71.     for(i=0; i<xlen; ++i)
  72.     {
  73.         tmp[i] = 0;
  74.     }
  75.     // find longest common of the two string
  76.     for(i=0; i<ylen; ++i)
  77.     {
  78.         for(j=0; j<xlen; ++j)
  79.         {
  80.             if(str_x[j] == str_y[i])
  81.             {
  82.                 if(0 == j)
  83.                     arr[j] = 1;
  84.                 else
  85.                     arr[j] = tmp[j-1] + 1;
  86.             }
  87.             if(arr[j] > max)
  88.             {
  89.                 max = arr[j];
  90.                 end = j;
  91.             }
  92.         }
  93.         for(j=0; j<xlen; ++j)
  94.         {
  95.             tmp[j] = arr[j];
  96.             printf("%d ", arr[j]);
  97.             arr[j] = 0;
  98.         }
  99.         printf("\n");
  100.     }
  101.     // deal with return value
  102.     *longest = max;
  103.     p_ret = (char *)malloc(max+1);
  104.     for(i=0; i<max; i++)
  105.     {
  106.         p_ret[i] = str_x[end+1-max+i];
  107.     }
  108.     p_ret[i] = '\0';

  109.     return p_ret;
  110. }

  111. int _tmain(int argc, _TCHAR* argv[])
  112. {
  113.     char * strA = "21232523311324";
  114.     char * strB = "312123223445";
  115.     // result should be: 21232, len=5
  116.     int maxlen = 0;
  117.     char *strLcs = maxCommStr(strA, strB, &maxlen);
  118.     //char *strLcs = strLCS(strA, strB, &maxlen);

  119.     printf("\nlongest is:%s, len=%d\n", strLcs, maxlen);

  120.     free(strLcs);

  121.     return 0;
  122. }
阅读(1390) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~