面试的时候遇到求两个字符串的最大公共子串,一开始写的很乱,自己都没整明白,现在回想起来,补在这里。
#include<iostream>
using namespace std;
void findMaxSubStr(const char* src,const char *dest)
{
const char *p=NULL;//存放短的字符串
const char *q=NULL;
int size_src = 0;
while('\0' != src[size_src] ){
size_src++;
}
int size_dest = 0;
while('\0' != dest[size_dest] ){
size_dest++;
}
if(size_src < size_dest){
p = src;
q = dest;
}else{
p = dest;
q = src;
}
int index = 0, i =0, j = 0,temp=0;
int start=0,max_len=0;
while('\0' != p[index]){ //p是否到底
i = index;
j = 0;
while('\0' != q[j]){ //q是否到底
while(p[i] != q[j]){ //不相等
j++;
if('\0' == q[j] )
break;
}
if('\0' == q[j] )
break;
temp = j;
while(p[i] == q[j]){
i++;
j++;
if('\0' == q[j]){
break;
}
if('\0' == p[i]){
break;
}
}
if((i-index) > max_len){
start = index;
max_len = i - index;
}
i = index;
j = temp + 1;
}
index++;
}
i=0;
while(i < max_len){
cout<<p[start+i];
i++;
if('\0' == p[start+i]){
break;
}
}
cout<<endl;
}
int main(void)
{
char *src = "laskdjflkajsdlfjaslkdjflkasjdlfjasdlkj";
char *dest = "aksjdklfjalsjdflajsdljfalsjdlfkasldjlfjasldkjflkasjdlkfalsd";
findMaxSubStr(src, dest);
return 0;
}
google了下,本题解法有很多,可以限制不用指针,用string类。也可以用DP算法解决。也可以用KMP算法。接下来一个一个分析。
#include <iostream>
using namespace std;
int findMaxSubString(const char*src, const char* dest)
{
int src_len = strlen(src);
int dest_len = strlen(dest);
const char *p = ( src_len>=dest_len ) ? src : dest;
const char *q = ( src_len<dest_len ) ? src : dest;
int start = 0;
int max = 0;
int count = 0;
int k = 0;
for(int i = 0; i<=src_len; ++i){
for(int j = 0; j <=dest_len; ++j){
k= 0;
while( i+k<src_len && j+k<dest_len ){
if( p[i+k]!=q[j+k] ){
break;
}
++k;
}
if( k > max ){
start = j;
max = k;
cout<<"count = "<<++count<<'\t';
}
}
}
for(int j = start; j < start+max; ++j){
cout<<q[j];
}
cout<<endl;
cout<<"start = "<<start<<endl;
cout<<"length = "<<max<<endl;
return 0;
}
int main()
{
char *src = "ksajflkasjdklfjasdlkfjaslkdjflaksdjlfasjdlfdsajlk";
char *dest = "aksjdhfkjahsdkjgfkadhsfkjsadhfjkshdkjhdsfjakhfdkj";
findMaxSubString( src, dest );
return 0;
}
用for循环更清晰,更好理解。
下面是 另一种思路:
#include <cstring>
#include <iostream>
using namespace std;
int GetLongestCommonSubString(const char *pStr1, const char *pStr2)
{
/* 判断参数合法性 */
if (pStr1 == NULL || pStr2 == NULL) {
return -1;
}
int n = strlen(pStr1);
int m = strlen(pStr2);
int longestCommonSubString = 0;
int k = 0;
/* 申请辅助空间,并初始化为0 */
int *LCS = new int[m];
for (int i = 0; i < m; ++i) {
LCS[i] = 0;
}
/* 不断判断pStr[i] ?= pStr[j],然后根据不同情况来更新LCS */
for ( i = 0; i < n; i++) {
for (int j = m - 1; j >= 0; j--) {
if (pStr1[i] == pStr2[j]) { /* 如果pStr1[i] == pStr2[j],LCS[j] = LCS[j-1] + 1 */
if (j == 0) {
LCS[j] = 1;
} else {
LCS[j] = LCS[j-1] + 1;
}
} else { /* 如果pStr1[i] != pStr2[j],LCS[j] = 0 */
LCS[j] = 0;
}
/* 更新最长子串的长度 */
if (LCS[j] > longestCommonSubString) {
longestCommonSubString = LCS[j];
k = j;
}
}
}
delete LCS;
LCS = NULL;
for( i = 0; i < longestCommonSubString; ++i ){
cout<<pStr2[ i + k - longestCommonSubString + 1]<<'\t';
}
return longestCommonSubString;
}
int main() {
GetLongestCommonSubString( "sslagdddkjflkdsjlf", "sklagdddkjflasjdlfkasd" );
return 0;
}