轉載請註明出處
http://blog.csdn.net/MonkeyAndy
問題:給出兩個字串,求出這兩個字串的連續的最長公用子序列
例如 :
char* a="aocdfacddcdfe";
char* b="pmcdfacdfe";
連續的最長公用子序列為 “cdfacd”
問題分析:
思路及演算法流程:
1、以a串為主串,遍曆a串,記錄下b串中與a[i]字元相等的字元所在的位置,indexs初始化為0,放於int* indexs中;
2、遍曆indexs[j],進入3; 當遇到0時停止遍曆;
3、將a[i] 的下一個字元與 indexs[j] + 1 的字元相比較,如果相等則繼續下一個,否則記錄下此時的長度len,進入4
4、若len大於maxlen,則修改maxlen為len,記錄字串的最長紀錄,並且記錄下a[i] 距離a[0]的位移量offset
5、返回*a+offset;
以i=2時為例
a:aocdfacddcfe
b:pmcdfacdfe
此時indexs[0] = 3, indexs[1] = 7, indexs[2] = 0;
先以indexs[0]=3開始,比較b中indexs[0]+1和a[i+1]的值, 兩者都為d,於是同時向後移一位,直到比較到
a : aocdfacddcdfe
b: pmcdfacdfe
此時記錄下len=6;
同理繼續從indexs[1]開始和a[i+1]比較,同理比較到
a : aocdfacddcdfe
b: pmcdfacdfe
時停止比較,此時len=3,故此次迴圈的最大長度為6,
迴圈遍曆a,直到結束
附上代碼,親測。(在字串長度較小的情況下通過測試,沒有測試大量的字串情況下的結果,歡迎各位批評指正)
#include <iostream>#include <cstdlib>#include <cstring>using namespace std;/**根據ch,找出str中與之相等的字元所在的位置並存於indexs;中*/void initIndexs(char ch, char * str, int *indexs){ for(unsigned int i=0,j=0; i<strlen(str);i++) { if(ch == str[i]) indexs[j++] = i+1; }}/* *找出兩個字串中最長的公用子序列,有序的;返回最長公用子序列在在str1中的位置, *並將長度賦值給maxLen *例如輸入字元"aocdfe" "pmcdfacdfe",返回 cdfe */char * LCS(char *str1, char *str2, int *maxLen){ int *indexs=NULL; //存放在str2中與str1[i]中字元相等的字元所在位置, int start,end;//最長公用子序列的起始和終止位置 int len=0;//公用子字串的長度 int offset=0;//最長公用子字串起始位置的位移量 for(unsigned int i=0; i<strlen(str1); i++)//遍曆str1 { start = i; free(indexs); //重新分配記憶體並初始化為0 indexs = (int *) calloc(strlen(str2),sizeof(int)); initIndexs(str1[i], str2, indexs); for(int j=0; indexs[j] !=0; j++)//找出str2中與str1中字元相等的字串 { end = i + 1; for(; str1[end] == str2[indexs[j]]; ) { end++; indexs[j]++; } len = end - start; if( len > *maxLen) { *maxLen = len; //找出最長公用子字串的長度 offset = start; } } } return str1+offset;}int main(){ char * str1="aocdfacddcdfe"; char * str2="pmcdfacdfe"; int len=0; char *ch = LCS(str1,str2,&len);
cout <<"The longest common string is "; for(int i=0;i<len;i++) cout << ch[i]; return 0;}
參考:http://blog.csdn.net/orbit/article/details/6850706