字符串匹配从BF到BM再到KMP(一个非主流NEXT函数)

#include <stdlib.h>
#include <string.h>
#include <malloc.h>

int bf(char* text, char* pattern){
    int i = 0;
    int j = 0;
    while(i<strlen(text) && j<strlen(pattern)){
        if(text[i] == pattern[j]){
            i++;
            j++;
        }else{    
            //i回溯到 开始匹配的下一个位置 
            i = i-j+1;
            //j回溯到最开始0处 
            j = 0;
        }
    }
    //匹配到时候是j<strlen(pattern)条件不满足的时候 
    return j>strlen(pattern)-1 ? i-j : -1;
}

int* jump(char* pattern){
    int* result = malloc(sizeof(int)*128);
    int i=0;
    for(;i<128;i++){
        result[i] = (int)strlen(pattern);
    }
    for(i=0;i<strlen(pattern);i++){
        result[(int)pattern[i]] = strlen(pattern)-1-i;
    }
    
    return result;
}

int bm(char* pattern, char* text){
    int* jumpTable = jump(pattern);    
    int textComparePos = strlen(pattern)-1;
    int patternComparePos = strlen(pattern)-1;
    while(textComparePos<strlen(text)){
        if(pattern[patternComparePos] != text[textComparePos]){
            textComparePos += jumpTable[(int)text[textComparePos]];
            patternComparePos = strlen(pattern)-1;
        }else{
            if(patternComparePos == 0){
                return textComparePos;
            }
            textComparePos--;
            patternComparePos--;
        }
    }
    return -1;
}

//在J位置发生不匹配以后,找到一个k使 P[0~K]==P[K+1~J]调整将J调整为K 
//这个方法也可以将next(j-1)求解出的子问题存储起来,这么写主要是为了好想 
int next(char* pattern, int j){
    if(j==0||j==-1){
        return 0;
    }
    if(pattern[j]==pattern[next(pattern, j-1)+1]){
        return next(pattern, j-1)+1;
    }else{
        while(1){
            int k = next(pattern, j-1);
            if(pattern[j]==pattern[k+1]){
                return next(pattern, k);
            }
        }    
    }
}

int kmp(char* text, char* pattern){
    int i = 0;
    int j = 0;
    while(i<strlen(text) && j<strlen(pattern)){
        if(text[i] == pattern[j] || j==0){
            i++;
            j++;
        }else{
            //j位置发生不匹配    
            //j通过分析模式串,计算出模式串下一个比较位置和文本不匹配位置匹配 
            j = next(pattern, j-1);
            
        }
    }
    return j>strlen(pattern)-1 ? i-j : -1;
}

int main(){
    char* text =   "adjfskjfskdjsfkglsi";
    char* pattern = "skdj";
    
    printf("bf matches on %d\r\n",bf(text, pattern));
    printf("kmp matches on %d\r\n",kmp(text, pattern));
    printf("bm matches on %d\r\n",bm(pattern,text));
    return 0;
}
原文地址:https://www.cnblogs.com/23lalala/p/2703628.html