您的位置:首页 > 其它

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

2012-09-26 11:15 861 查看
#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: