字符串匹配算法

字符串匹配(string match)是在实际工程中经常会碰到的问题,通常其输入是原字符串(String)和子串(又称模式,Pattern)组成,输出为子串在原字符串中的首次出现的位置。通常精确的字符串搜索算法包括暴力搜索(Brute force),KMP。下面分析这几种方法并给出其实现。假设原字符串长度M,字串长度为N。

1. Brute force.

该方法又称暴力搜索,也是最容易想到的方法。

预处理时间 O(0)

匹配时间复杂度O(N*M)

主要过程:从原字符串开始搜索,若出现不能匹配,则从原搜索位置+1继续。

/*ret=0,find与text不匹配
 *ret = -1,输入不符合要求
 *ret = -2,find的长度小于text的长度
 *若匹配,返回text中开始匹配的位置
 */
int brute_force(const char *text, const char *find)
{
    int ret = 0;
    if (text == NULL || find == NULL)
    {
        ret = -1;
        printf("func brute_force() err:%d\n", ret);
        return ret;
    }

    int find_len = strlen(find);
    int text_len = strlen(text);
    if (text_len < find_len)
    {
        ret = -2;
        printf("func brute_force() err:%d\n", ret);
        return ret;
    }

    char *pSmall = find;
    char *pBig = text;
    while (*pBig != '\0')
    {
        if (*pBig == *pSmall)
        {
            pBig++;
            pSmall++;
        }
        else
        {
            pSmall = find;
            pBig++;
        }
        if (*pSmall == '\0')
        {
            ret = (pBig - text) - (pSmall - find);
            break;
        }
    }
    return ret;
}

2. KMP.

KMP是经典的字符串匹配算法。

预处理时间:O(M)

匹配时间复杂度:O(N)

主要过程:通过对字串进行预处理,当发现不能匹配时,可以不进行回溯。

int kmp(const char *text, const char *find)
{
    //判断输入
    int ret = 0;
    if (text == NULL || find == NULL)
    {
        ret = -1;
        printf("func brute_force() err:%d\n", ret);
        return ret;
    }
    //判断匹配字符串的长度
    int find_len = strlen(find);
    int text_len = strlen(text);
    if (text_len < find_len)
    {
        ret = -2;
        printf("func brute_force() err:%d\n", ret);
        return ret;
    }
    //建立匹配数组
    int next[find_len];
    memset(next, 0, find_len*sizeof(int));
    next[0] = 0;
    next[1] = 0;
    int j = 0;
    int i = 1;
    while (i < find_len)
    {
        if (j==0 || find[i] == find[j])
        {
            i++;
            j++;
            if (find[i] != find[j])
            {
                next[i] = j;
            }
            else
            {
                next[i] = next[j];
            }
        }
        else
        {
            j = next[j];
        }
    }

    i=0;
    j=0;
    while (i <=text_len && j<=find_len)
    {
        if (text[i]==find[j])
        {
            i++;
            j++;
        }
        else
        {
            j = next[j];
            if (j == 0)
            {
                i++;
            }
        }
        if (j==find_len)
        {
            ret = i - j;
        }
    }

    return ret;
}



你可能感兴趣的:(字符串匹配算法)