还是一样的郁闷呢|

gonghr

园龄:4年1个月粉丝:307关注:25

字符串匹配-BF算法和KMP算法

声明:图片及内容基于https://www.bilibili.com/video/av95949609

BF算法

原理分析

Brute Force 暴力算法

用来在主串中查找模式串是否存以及出现位置.

 

 

核心就是回溯

如果模式串下标 j 始终没有到达'\0'则没有找到

如果主串下标 i 最后到达了'\0'则没有找到

 

复杂度分析

 

完整代码

#include<iostream>
using namespace std;
int BF(char S[], char T[]) {
    int i = 0, j = 0,start=0;
    while (S[i]!='\0'&&T[j]!='\0') {
        if (S[i] == T[j]) {         //相等的话,i,j都后移一位
            i++; j++; 
        } 
        else {                        //一旦有不相等的,回溯。i回到起始位置加一,j回到模式串头
            start++;
            i = i - j + 1;
            j = 0;
        }
    }
    if (T[j] == '\0') return start; //也可以return i-j;
    //if (S[i] == '\0') return -1;  //主串到达'\0'说明没找到
    else return -1;                  //模式串没到达'\0'说明没找到
}
int main() {
    char S[] = "DABCDABD";
    char T[] = "ABD";
    int i=BF(S, T);
    if (i>=0) {
        cout << "已找到,在主串下标为"<<i<<"的地方"<<endl;
    }
    else cout << "未找到" << endl;
    return 0;
}

 KMP算法

原理分析

比BF算法高效,区别是主串的下标 i 不会回溯,一直前进。而模式串下标 j 回溯到特定位置。

关键是模式串找最大的相同的前后缀,用next数组记录前后缀字符数。

对模式串回溯的正确性分析:如上图已经找到模式串中最大长度的相等的前后缀且模式串前后缀以及中间的元素已经与主串匹配。

模式串中ab!=cd,故模式串中ab!=主串中cd,模式串中的前缀ab没有再与主串比较的必要,故模式串下标 j 移动到c,主串下标 i 不动

next数组

 

完整代码

#include<iostream>
using namespace std;
void getNext(char *T, int *next) {
    int j = -1;   //前缀
    int i = 0;    //后缀
    next[0] = -1;
    while (i < strlen(T)) {
        if (j == -1 || T[i] == T[j] ){
            i++; j++;
            next[i] = j;
        }
        else {
            j=next[j];  //回溯
        }
    }
}
int KMP(char S[], char T[],int *next) {
    int i = 0, j = 0;
    int lengthS = strlen(S);
    int lengthT = strlen(T);
    while (i < lengthS && j < lengthT) {
        if (j== -1||S[i] == T[j]) {
            i++; j++;
        }
        else {
            j = next[j];
        }
    }
    if (j == lengthT) return (i - j);
    else return -1;
}
int main() {
    char S[] = "DABCDABD";
    char T[] = "ABC";
    int next[100];
    getNext(T,next);
    int i = KMP(S, T,next);
    if (i>=0) {
        cout << "已找到,在母串下标为"<<i<<"的地方"<<endl;
    } 
else cout << "未找到" << endl;
    return 0;
}

 

BF算法和KMP算法比较

在KMP算法中 j == -1因为next数组next[0]= -1,得到 j 可能为-1

next数组的优化--nextval数组

对模式串回溯作进一步优化,其回溯的位置next[j]如果与回溯前的数相等,则此回溯没有任何作用,由此出现nextval数组优化

 

根据next值求nextval值的方法:

模式串 a b a a b c a c
next值 -1 0 0 1 1 2 0 1
nextval值 -1 0 -1 1 0 2 -1 1

代码

void getNextval(char* T, int* nextval) {
    int i = 0, j = -1;                          //j是前缀,i是后缀
    nextval[0] = -1;
    while (i < strlen(T)) {
        if (j == -1 || T[i] == T[j]) {
            i++; j++;
            if (nextval[i] != nextval[j]) {
                nextval[i] = j;
            }
            else {
                nextval[i] = nextval[j];         //这是nextval与next数组的区别,i,j加一后在比较nextval[i]和nextval[j]
            }                                    //如果相等则nextval[i]=nextval[j]
        }
        else {
            j = nextval[j];                    
        }
    }
}

 

本文作者:GHR

本文链接:https://www.cnblogs.com/gonghr/p/14526458.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   gonghr  阅读(334)  评论(0编辑  收藏  举报
评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示
  1. 1 Whenever you are ONE OK ROCK
Whenever you are - ONE OK ROCK
00:00 / 00:00
An audio error has occurred.

作词 : TAKA

作曲 : TAKA

I'm telling you

Tonight tonight

You are my angel

爱してるよ

爱してるよ

2人は一つに

Tonight tonight

I just say…

Wherever you are I always make you smile

Wherever you are I'm always by your side

Whatever you say 君を思う気持ち

I promise you forever right now

I don't need a reason

I don't need a reason

I just want you baby

Alright alright

Day after day

この先长いことずっと

この先长いことずっと

どうかこんな仆とずっと

死ぬまで Stay with me

We carry on…

Wherever you are I always make you smile

Wherever you are I'm always by your side

Whatever you say' 君を思う気持ち

I promise you forever right now

Wherever you are I never make you cry

Wherever you are I'never say goodbye

Whatever you say 君を思う気持ち

I promise you forever right now

仆らが出逢った日は2人にとって

一番目の记念すべき日だね

そして今日という日は2人にとって

二番目の记念すべき日だね

心から爱せる人

心から爱せる人

心から爱しい人

この仆の爱の真ん中には

いつも君(きみ)がいるから

Wherever you are I always make you smile

Wherever you are I'm always by your side

Whatever you say 君を思う気持ち

I promise you forever right now

Wherever you are wherever you are

Wherever you are

おわり

おわり

おわり