題:判斷一個字符串是否包含另一個字符串(尋找下標、尋找包涵幾個子串等)
看到問題首先想到循環一下就解決了,循環比對沒問題
bool test1(char *contentChars, char *itemChars) {
bool searchSucc = false;
int searchCount = 0;
for (int i = 0; i < strlen(contentChars); i ++) {
for (int j = i; j < strlen(contentChars); j ++) {
if (contentChars[j] == itemChars[j]) {
if (j >= strlen(itemChars)) {
searchCount ++;
searchSucc = true;
break;
}
} else {
break;
}
}
}
return searchSucc;
}
這樣解題是可以解的,可以看到複雜度爲n*m,那有沒有別的解法可以優化一下。
所以引出了KMP算法,這裏不解釋KMP算法的原理(網上有很多解釋,可以去搜一下),直接上代碼
void buildNext(const char *T, int Next[]) {
int i,j;
Next[0] = -1;
j = Next[1] = 0;
for (i = 2; i < strlen(T); i++){
while (j > 0 && T[i-1] != T[j]) j = Next[j];
if (T[i-1] == T[j]) j++;
Next[i] = j;
}
}
bool stringContains(char *contentChars, char *itemChars) {
unsigned long zLength = strlen(contentChars);
unsigned long length = strlen(itemChars);
int Next[128] = {0};
buildNext(itemChars, Next);
int i,j;
i = j = 0;
bool searchSucc = false;
int searchCount = 0;
int rollCount = 0;
while (i < zLength) {
rollCount ++;
if (contentChars[i] == itemChars[j]) {
i ++;
j ++;
if (j >= length) {
searchSucc = true;
searchCount ++;
//找到,是否繼續尋找
bool continueSearch = true;
if (continueSearch) {
j = Next[j - 1] + 1;
} else {
break;
}
}
} else {
i = i + (j == 0 ? 1 : 0);
j = j > 0 ? Next[j] : 0;
}
}
printf("尋找子字符串【%s】%s,共循環%d次,字符串長度%lu,共找到%d個",itemChars, searchSucc ? "成功" : "失敗", rollCount, zLength, searchCount);
return searchSucc;
}
上面就是利用KMP算法進行查找子字符串