BF算法与KMP算法

BF算法:
即暴风(Brute Force)算法,是普通的模式匹配算法,它的思想就是将子串的第一个字符与母串的第一个字符进行匹配,若相等,则继续比较子串的第二个字符和母串的第二个字符;若不相等,则比较母串的第二个字符和子串的第一个字符,依次比较下去,知道得出最后的匹配结果。算是一种蛮力算法。
代码:

int BF(Str *s,Str *sub,int pos)
{
    assert(sub != NULL && s != NULL);
    if(pos < 0 || pos > s->length)
    {
        return -1;
    }
    int i = pos;
    int j = 0;
    while( i < s->length && j < sub->length)
    {
        if(s->elem[i] == sub->elem[j])
        {
            i++;
            j++;
        }
        else
        {
            i = i -j + 1;
            j = 0;
        }

    }
    if(j >= sub->length)
    {
        return i -j;
    }
    else
    {
        return -1;
    }
}

KMP算法:
相比较于BF 算法,KMP算法建立了一个子串的next数组,用来储存子串j回退的位置;
next 数组各值的含义:代表当前字符之前的字符串中,有多大长度的相同前缀后缀。例如如果next [j] = k,代表j 之前的字符串中有最大长度为k 的相同前缀后缀。
此也意味着在某个字符失配时,该字符对应的next 值会告诉你下一步匹配中,模式串应该跳到哪个位置(跳到next [j] 的位置)。如果next [j] 等于0或-1,则跳到模式串的开头字符,若next [j] = k 且 k > 0,代表下次匹配跳到j 之前的某个字符,而不是跳到开头,且具体跳过了k 个字符。
KMP的next 数组相当于告诉我们:当模式串中的某个字符跟文本串中的某个字符匹配失配时,模式串下一步应该跳到哪个位置。如模式串中在j 处的字符跟文本串在i 处的字符匹配失配时,下一步用next [j] 处的字符继续跟文本串i 处的字符匹配,相当于模式串向右移动 j - next[j] 位。
代码:

void GetNext(int  *next,char *sub)//获取子串的next值
{
    int lensub=strlen(sub);//计算sub的长度
    next[0]=-1;
    next[1]=0;//已知前两项的next值为-10
    int i=2;//第二项开始
    int k=0;//0开始
    while(i<lensub)
    {
        if((k==-1)||sub[k]==sub[i-1])//假设条件
        {
            next[i]=k+1;
            i++;
            k++;
        }
        else
        {
            k=next[k];
        }
    }
}
int KMP(char *str,char *sub,int pos)
{
    int lens=strlen(str);
    int lenb=strlen(sub);//分别计算str和sub的长度
    if(pos<0||pos>lens)
    {
        return -1;
    }
    int *next=(int *)malloc(sizeof(int)*lenb);
    GetNext(next,sub);
    assert(next!=NULL);
    int i=pos;
    int j=0;
    while(i<lens&&j<lenb)//遍历循环
    {
        if(j==-1||str[i]==sub[j])
        {
            i++;
            j++;
        }
        else
        {
            j=next[j];
        }
    }
        free(next);
        if(j>=lenb)
        {
            return i-j;//找到后  最后返回i-j的值
        }
        else
        {
            return -1;//否则   返回-1
        }   
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值