亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

最長公共子字符串的使用分析

2020-01-26 16:10:17
字體:
來源:轉載
供稿:網友
子字符串的定義和子串的定義類似,但要求是連續分布在其他字符串中。比如輸入兩個字符串BDCABA和ABCBDAB的最長公共字符串有BD和AB,它們的長度都是2。
最長公共子字符串共有兩種解決方法,下面具體說說我的思路
方法一:
Longest Common Substring和Longest Common Subsequence是有區別的
X = <a, b, c, f, b, c>
Y = <a, b, f, c, a, b>
X和Y的Longest Common Sequence為<a, b, c, b>,長度為4
X和Y的Longest Common Substring為 <a, b>長度為2
其實Substring問題是Subsequence問題的特殊情況,也是要找兩個遞增的下標序列
<i1, i2, ...ik> 和 <j1, j2, ..., jk>使
xi1 == yj1
xi2 == yj2
......
xik == yjk
與Subsequence問題不同的是,Substring問題不光要求下標序列是遞增的,還要求每次
遞增的增量為1, 即兩個下標序列為:
<i, i+1, i+2, ..., i+k-1> 和 <j, j+1, j+2, ..., j+k-1>
類比Subquence問題的動態規劃解法,Substring也可以用動態規劃解決,令
c[i][j]表示Xi和Yi的最大Substring的長度,比如
X = <y, e, d, f>
Y = <y, e, k, f>
c[1][1] = 1
c[2][2] = 2
c[3][3] = 0
c[4][4] = 1
動態轉移方程為:
如果xi == yj, 則 c[i][j] = c[i-1][j-1]+1
如果xi ! = yj,  那么c[i][j] = 0
最后求Longest Common Substring的長度等于
max{  c[i][j],  1<=i<=n, 1<=j<=m}
 完整的代碼如下:
復制代碼 代碼如下:

/**
找出兩個字符串的最長公共連續子串的長度
** author :liuzhiwei 
** data:2011-08-16
**/
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
int longest_common_substring(char *str1, char *str2)
{
 int i,j,k,len1,len2,max,x,y;
 len1 = strlen(str1);
 len2 = strlen(str2);
 int **c = new int*[len1+1];
 for(i = 0; i < len1+1; i++)
  c[i] = new int[len2+1];
 for(i = 0; i < len1+1; i++)
  c[i][0]=0;//第0列都初始化為0
 for(j = 0; j < len2+1; j++)
  c[0][j]=0;//第0行都初始化為0
 max = -1;
 for(i = 1 ; i < len1+1 ; i++)
 {
  for(j = 1; j < len2+1; j++)
  {
   if(str1[i-1]==str2[j-1])//只需要跟左上方的c[i-1][j-1]比較就可以了
    c[i][j]=c[i-1][j-1]+1;
   else//不連續的時候還要跟左邊的c[i][j-1]、上邊的c[i-1][j]值比較,這里不需要
    c[i][j]=0;
   if(c[i][j]>max)
   {
    max=c[i][j];
    x=i;
    y=j;
   }
  }
 }
 //輸出公共子串
 char s[1000];
 k=max;
 i=x-1,j=y-1;
 s[k--]='/0';
 while(i>=0 && j>=0)
 {
  if(str1[i]==str2[j])
  {
   s[k--]=str1[i];
   i--;
   j--;
  }
  else  //只要有一個不相等,就說明相等的公共字符斷了,不連續了
   break;
 }
 printf("最長公共子串為:");
 puts(s);
 for(i = 0; i < len1+1; i++)//釋放動態申請的二維數組
  delete[] c[i];
 delete[] c;
 return max;
}
int main(void)
{
 char str1[1000],str2[1000];
 printf("請輸入第一個字符串:");
 gets(str1);
 printf("請輸入第二個字符串:");
 gets(str2);
 int len = longest_common_substring(str1, str2);
 printf("最長公共連續子串的長度為:%d/n",len);
 system("pause");
 return 0;
}

效果圖如下: 

方法二:
將字符串s1和s2分別寫在兩把直尺上面(我依然用s1,s2來表示這兩把直尺),然后將s1固定,s2的頭部和s1的尾部對齊,然后逐漸移動直尺s2,比較重疊部分的字符串中的公共子串的長度,直到直尺s2移動到s1的頭部。在這個過程中求得的最大長度就是s1、s2最大子串的長度。
下圖是求解過程的圖示(下圖有點錯誤,應該是將s2從右往左移動),藍色部分表示重疊的字符串,紅色的部分表示重疊部分相同的子串
其中s1="shaohui",s2="ahui",最后求得的結果為3

完整的代碼如下:
復制代碼 代碼如下:

/**
找出兩個字符串的最長公共連續子串的長度
** author :liuzhiwei 
** data   :2011-08-16
**/
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
int longest_common_substring(char *str1, char *str2)
{
 int i,len1,len2,len,s1_start,s2_start,idx,curmax,max;
 len1 = strlen(str1);
 len2 = strlen(str2);
 len = len1 + len2;
 max = 0;
 for(i = 0 ; i < len ; i++)
 {
  s1_start = s2_start = 0;
  if(i < len1)
   s1_start = len1 - i;    //每次開始匹配的起始位置
  else
   s2_start = i - len1;
  curmax = 0;
  for(idx = 0 ; ( s1_start + idx < len1 ) && ( s2_start + idx < len2 ); idx++ )
  {
   if(str1[s1_start+idx]==str2[s2_start+idx])
    curmax++;
   else     //只要有一個不相等,就說明相等的公共字符斷了,不連續了,要保存curmax與max中的最大值,并將curmax重置為0
   {
    max = curmax > max ? curmax : max;
    curmax = 0;
   }
  }
  max = curmax > max ? curmax : max;
 }
 return max;
}
int main(void)
{
 char str1[1000],str2[1000];
 printf("請輸入第一個字符串:");
 gets(str1);
 printf("請輸入第二個字符串:");
 gets(str2);
 int len = longest_common_substring(str1, str2);
 printf("最長公共連續子串的長度為:%d/n",len);
 system("pause");
 return 0;
}

效果圖如下:

稍微改動一下,便可以輸出公共子串了,就是要保存一下連續公共子串最后一個字符在其中一個字符串中的下標位置:
復制代碼 代碼如下:

/**
找出兩個字符串的最長公共連續子串的長度
** author :liuzhiwei 
** data   :2011-08-16
**/
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
int longest_common_substring(char *str1, char *str2)
{
 int i,k,len1,len2,len,s1_start,s2_start,idx,curmax,max;
 len1 = strlen(str1);
 len2 = strlen(str2);
 len = len1 + len2;
 max = 0;
 for(i = 0 ; i < len ; i++)
 {
  s1_start = s2_start = 0;
  if(i < len1)
   s1_start = len1 - i;    //每次開始匹配的起始位置
  else
   s2_start = i - len1;
  curmax = 0;
  for(idx = 0 ; ( s1_start + idx < len1 ) && ( s2_start + idx < len2 ); idx++ )
  {
   if(str1[s1_start+idx]==str2[s2_start+idx])
    curmax++;
   else     //只要有一個不相等,就說明相等的公共字符斷了,不連續了,要保存curmax與max中的最大值,并將curmax重置為0
   {
    //max = curmax > max ? curmax : max;
    if(curmax > max)
    {
     max = curmax;
     k = s1_start+idx-1;      //保存連續子串長度增加時連續子串最后一個字符在str1字符串中的下標位置,便于輸出公共連續子串
    }
    curmax = 0;
   }
  }
  //max = curmax > max ? curmax : max;
  if(curmax > max)
  {
   max = curmax;
   k = s1_start+idx-1;
  }
 }
 //輸出公共子串
 char s[1000];
 for(i=0;i<max;i++)
  s[i]=str1[k-max+1+i];     //公共字串在str1中的下標起始位置為k-max+1,結束位置為k
 s[i]='/0';
 printf("最長公共子串為:");
 puts(s);
 return max;
}
int main(void)
{
 char str1[1000],str2[1000];
 printf("請輸入第一個字符串:");
 gets(str1);
 printf("請輸入第二個字符串:");
 gets(str2);
 int len = longest_common_substring(str1, str2);
 printf("最長公共連續子串的長度為:%d/n",len);
 system("pause");
 return 0;
}

效果圖如下:

擴展:子串也可以是反串,比如HDOJ 1238
題目意思是要搜索最長的子串
給出一系列字符串,幾個子串可以是反串
rose
orchid 
這里最長的子串是 ro 跟or 長度為2。
如果窮舉搜索的話,肯定過不了。
所以可以找出所有字符串中最短的串,枚舉最短的字符串的子串
判斷是否都是別的字符串的子串,求出最大長度即可。。
復制代碼 代碼如下:

/**
找出兩個字符串的最長公共連續子串的長度
** author :liuzhiwei 
** data   :2011-08-16
**/
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
char str[100][100];
int k;
int match(int start,int end,int n)   //最短字符串中的起點下標、終點下標,字符串總數
{
 int i,j,len,p,h;
 for(i=0;i<n;i++)
 {
  if(i==k)
   continue;
  len=strlen(str[i]);
  for(j=0;j<=len-1-end+start;j++)    //str[i]字符串可以組成len-1-end+start個長度為end-start的連續子串
  {
   for(p=start,h=j;p<=end;p++,h++)    //順序判斷子串
   {
    if(str[k][p]!=str[i][h])       //不等即跳出
     break;
   }
   if(p>end)                   //如果全部相等,則匹配成功,終止
    break;
   for(p=end,h=j;p>=start;p--,h++)             //逆序判斷子串
   {
    if(str[k][p]!=str[i][h])       //不等即跳出
     break;
   }
   if(p<start)                   //如果全部相等,則匹配成功,終止
    break;
  }
  if(j>len-1-end+start)    //如果搜索完畢都沒終止,即無匹配
   return 0;
 }
 return 1;
}
int main(void)
{
 int t,i,j,n,len,minlen,flag;
 scanf("%d",&t);
 while(t--)
 {
  minlen=1000,flag=0;
  scanf("%d",&n);
  for(i=0;i<n;i++)
  {
   scanf("%s",str[i]);
   len = strlen(str[i]);
   if(len<minlen)
   {
    minlen=len;      //保存最短字符串的長度
    k=i;             //保存最短字符串的序號
   }
  }
  for(i=0;i<minlen;i++)    //對最短字符串的連續字串進行匹配查找
  {
   for(j=0;j<=i;j++)
   {
    if(match(j,j+minlen-1-i,n))    //子串是否匹配
    {
     flag=1;
     break;
    }
   }
   if(flag==1)
    break;
  }
  printf("%d/n",minlen-i);
 }
 system("pause");
 return 0;
}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩精品高清在线观看| 日韩成人在线视频| 久热精品视频在线观看一区| 免费91在线视频| 成人一区二区电影| 欧美性xxxxx极品娇小| 日韩精品免费在线视频观看| 欧美午夜精品久久久久久人妖| 国产中文字幕91| 久久精品中文字幕| 性欧美视频videos6一9| 91系列在线观看| 免费不卡欧美自拍视频| 欧美午夜宅男影院在线观看| 亚洲国产又黄又爽女人高潮的| 亚洲社区在线观看| 国产精品久久久久免费a∨| 久久精品视频中文字幕| 91在线国产电影| 亚洲一级黄色av| 亚洲欧美日韩爽爽影院| 日韩在线观看成人| 精品中文字幕在线| 成人写真福利网| 日韩欧美在线视频日韩欧美在线视频| 国产精品久久久久免费a∨| 欧美激情videos| 欧美一级视频一区二区| 欧美香蕉大胸在线视频观看| 国产亚洲激情在线| 亚洲人av在线影院| 成人免费在线网址| 精品久久国产精品| 91亚洲精品在线| 亚洲男女自偷自拍图片另类| 日韩欧美精品在线观看| 久久久久久香蕉网| 色婷婷综合成人| 性色av一区二区三区红粉影视| 久久伊人免费视频| 欧美激情一区二区三区久久久| 中文字幕亚洲专区| 黄色一区二区在线观看| 国产精品视频999| 色妞在线综合亚洲欧美| 欧美激情2020午夜免费观看| 韩国一区二区电影| 国产精品久久久久一区二区| 久久久亚洲影院你懂的| 欧美精品久久久久久久久| 亚洲精品国精品久久99热一| 成人免费视频在线观看超级碰| 亚洲美女自拍视频| 欧美国产日产韩国视频| 57pao国产成人免费| 国产日本欧美一区二区三区在线| 成人网在线观看| 欧美视频国产精品| 亚洲成人网在线观看| 午夜精品久久久久久久久久久久| 国产精品视频专区| 亚洲资源在线看| 欧美另类69精品久久久久9999| 国产精品日韩在线一区| 日av在线播放中文不卡| 亚洲自拍偷拍福利| 日韩免费在线播放| 欧美性猛交xxxx偷拍洗澡| 成人黄色激情网| 亲爱的老师9免费观看全集电视剧| 国产精品午夜一区二区欲梦| 国产91精品视频在线观看| 国产精品电影久久久久电影网| 日韩精品www| 91精品综合视频| 欧美丝袜一区二区三区| 国产精品一区二区三| 91免费在线视频网站| 亚洲国产精品久久久久| 亚洲国产欧美日韩精品| 影音先锋欧美在线资源| 亚洲精品美女在线观看| 国产精品免费久久久| 欧美黄色成人网| 欧美壮男野外gaytube| 国产精品久久久一区| 高清视频欧美一级| 国产精品午夜国产小视频| 日韩电影大全免费观看2023年上| 国产精品www色诱视频| 九色成人免费视频| 久久精品电影网| 国产ts人妖一区二区三区| 精品爽片免费看久久| 亚洲精品久久7777777| 97成人精品视频在线观看| 色阁综合伊人av| 国产精品视频自拍| 欧美一区二区三区艳史| 亚洲精品国产美女| 久久免费精品视频| 91久久精品视频| 日韩高清中文字幕| 51久久精品夜色国产麻豆| 91久久久久久久久久| 成人精品视频99在线观看免费| 国产午夜精品美女视频明星a级| 久久久伊人欧美| 欧美伊久线香蕉线新在线| 97国产精品人人爽人人做| 国产精品网站视频| 久久国产色av| 亚洲电影第1页| 91成人免费观看网站| 久久999免费视频| 国产成人拍精品视频午夜网站| 丁香五六月婷婷久久激情| 欧美性生活大片免费观看网址| 国产91精品黑色丝袜高跟鞋| 精品久久久久久中文字幕一区奶水| 亚洲女人天堂网| 亚洲欧洲日产国码av系列天堂| 亚洲欧美变态国产另类| 欧美黑人国产人伦爽爽爽| 亚洲第一区第一页| 日本精品一区二区三区在线播放视频| 日韩成人中文字幕在线观看| 91精品国产99| 欧美日韩国产一区二区| 欧美激情第6页| 亚洲福利视频二区| 日韩精品在线看| 久久久亚洲影院你懂的| 国产精品99久久久久久久久| 欧美xxxx做受欧美.88| 国产精品一区二区三区成人| 日韩欧美精品在线观看| 成人免费自拍视频| 在线看欧美日韩| 91麻豆国产语对白在线观看| 亚洲精品日韩丝袜精品| 亚洲国产另类久久精品| 国产精品香蕉av| 国产美女精品视频免费观看| 91精品国产综合久久香蕉的用户体验| 国产精品福利观看| 国产精品成人观看视频国产奇米| 成人h猎奇视频网站| 国产一区二区三区在线播放免费观看| 国产精品视频精品视频| 欧洲成人免费aa| 欧美一级在线亚洲天堂| 国产一区二区三区在线免费观看| 色中色综合影院手机版在线观看| 欧美日韩视频免费播放| 中文字幕日韩在线视频| 欧美日韩国产二区| 国产精品日韩av| 欧美成人精品不卡视频在线观看| 亚洲一区美女视频在线观看免费| 日韩在线观看电影| 国产欧美精品日韩| 性色av一区二区三区红粉影视| 欧美在线一级va免费观看|