zoukankan      html  css  js  c++  java
  • 字符串匹配从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;
    }
  • 相关阅读:
    mysql 定时器
    mysql 存储过程记录
    mysql 常用sql
    mysql 取最后一条数据 分组
    Java8 Stream使用flatMap合并List 交 并 合 差集
    微服务技术栈
    spring boot 拦截 以及Filter和interceptor 、Aspect区别
    在springMVC的controller中获取request,response对象的一个方法
    spring boot 用@CONFIGURATIONPROPERTIES 和 @Configuration两种方法读取配置文件
    SSRS 2016 Forms Authentication
  • 原文地址:https://www.cnblogs.com/23lalala/p/2703628.html
Copyright © 2011-2022 走看看