从一个参考书上得到的求解算法,描述如下:
To determine if a pattern P with gap characters exists in T partition P into substrings P1, ..., Pk determined by the gap characters. Search for P1 and if found continue searching for P2 and so on. This clearly find a pattern if one exists.
由以上思路不难写出代码,如下:
#include <iostream>
#include <cstring>
using namespace std;
//使用朴素的字符串比较算法,返回第一个匹配的起始地点,若没有则为NULL
const char* findFirstContainMatch(const char* text, const char* pattern){
int textLen = strlen(text);
int patternLen = strlen(pattern);
for(int s = 0; s <= textLen - patternLen; ++s){
int i =0;
for(; i < patternLen; ++i){
if(text[s+i] != pattern[i]){
break;
}
}
//包含
if(i == patternLen){
return (text + s);
}
}
return NULL;
}
bool isSubStr(const char* text, const char* pattern){
while(true){
//找到某个不包含分隔符的子串的开始处
for(; *pattern == '*'; ++pattern);
cout<<*pattern <<" ";
if(*pattern == '\0'){
return true;
}
//找到第一个相匹配的地方
for(; *text != '\0' && *text != *pattern; ++text);
if(*text == '\0'){
return false;
}
//统计当前模式中下一个不包含分隔符的子串的长度
unsigned patternLen = 0;
for(const char* temp = pattern; *temp != '\0' && *temp != '*'; ++temp){
++patternLen;
}
//将模式中某个不包含分隔符的子串提取出来
char* subStr = new char[patternLen+1];
subStr[patternLen] = '\0';
strncpy(subStr, pattern, patternLen);
if((text = findFirstContainMatch(text, subStr)) == NULL){
return false;
}
//开始匹配下一个子串
pattern = pattern + patternLen;
text = text + patternLen;
delete[] subStr;
}
return false;
}
int main(){
char text[] = "cabccbacbacba";
char pattern[] = "****abcc*b*a*c*b*b*a";
cout << (isSubStr(text, pattern) ? "find it!" : "not find!") <<endl;
return 0;
}