字符串匹配的朴素模式与KMP模式

* 什么是朴素模式?

朴素模式思路:从主串的第一位开始与要匹配的字符串的第一位做对比,若相同,比较下一位,若不同,从主串的第二位开始与要匹配的字符串的第一位做对比,以此类推。

  例:主字符串 M 为 ababcdx,要匹配的字符串 T 为 abx。
  第一次:M[0] == T[0], M[1] == T[1], M[2] != T[2], 第一次匹配失败。
  第二次:M[1] != T[0], 第二次匹配失败。
  第三次:M[2] == T[0], M[3] == T[1], M[4] != T[2], 第三次匹配失败。
  第四次:M[3] != T[0], 第四次匹配失败。
  第五次:M[4] != T[0], 第五次匹配失败。
  第六次:主字符串未匹配字符只剩2个,匹配彻底失败。

代码如下:

int Index(char* M, char* T, int Mlength, int Tlength)
{
    int i = 0, j = 0;
    while (i < Mlength && j < Tlength)      //当i小于M长度,j小于T的长度时循环
    {
        if (M[i] == T[j])                           //若一个字符匹配,则匹配下一个字符
        {
            i++;
            j++;
        }
        else                                        //若不匹配,则i回到上次匹配首位的下一位,j回第0位
        {
            i = i - j + 1;
            j = 0;
        }
    }
    if (j >= Tlength)
        return i - Tlength; 
    else
        return 0;
}

* 什么是KMP模式?

在朴素模式中,有重复遍历的情况出现,使用KMP模式可以避免这些情况。

void get_next(char* T, int Tlength, int* next)
{
    int i = 2, j = 1;
    next[1] = 0;
    next[2] = 1;
    while (i < Tlength)
    {
        if (j == 0 || T[i - 1] == T[j - 1])
        {
            i++;
            j++;
            next[i] = j;
        }
        else
            j = next[j];
    }
}

int index_KMP(char* M, char* T, int Mlength, int Tlength)
{
    int i = 0, j = 0;
    int* next = (int*)malloc((Tlength + 1) * sizeof(int));
    get_next(T, Tlength, next);
    while (i < Mlength && j < Tlength)
    {
        if (M[i] == T[j])
        {
            i++;
            j++;
        }
        else
            j = next[j + 1] - 1;
    }
    if (j >= Tlength)
        return i - Tlength;
    else
        return 0;
}

朴素模式算法的改进:

void get_nextval(char* T, int Tlength, int* nextval)
{
    int i = 2, j = 1;
    nextval[1] = 0;
    nextval[2] = 1;
    while (i < Tlength)
    {
        if (j == 0 || T[i - 1] == T[j - 1])
        {
            i++;
            j++;
            if (T[i - 1] != T[j - 1])
                nextval[i] = j;
            else
                nextval[i] = nextval[j];
        }
        else
            j = nextval[j];
    }
}

int index_KMP(char* M, char* T, int Mlength, int Tlength)
{
    int i = 0, j = 0;
    int* next = (int*)malloc((Tlength + 1) * sizeof(int));
    get_nextval(T, Tlength, next);
    while (i < Mlength && j < Tlength)
    {
        if (M[i] == T[j])
        {
            i++;
            j++;
        }
        else
            j = next[j + 1] - 1;
    }
    if (j >= Tlength)
        return i - Tlength;
    else
        return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值