字符串匹配算法


//最简单版本
//输入:str 长字符串; match:欲匹配字符串
//输出:若匹配成功,输出match在str中起始位置,输出-1表示匹配失败
int NaiveStringMatch(char* str, char* match)
{
    int len = strlen(str);
    int m_len = strlen(match);
    for (int i = 0; i < len - m_len; i++)
    {
        int j;
        for ( j= 0; j < m_len; j++)
        {
            if (str[i + j] != match[j])
            {
                break;
            }
        }
        if (j == m_len)
        {
            return i;
        }
    }
    return -1;
}


----------


----------
/*RabinKarp 算法
简单来说,就是把要匹配的字符串换算成d进制的数,然后再比较
例如,str="23569841235";
要匹配的字符串match="5698";
可以把match转换成十进制数5698,在从str中按顺序取4个字符,转换成十进制数再比较
*/
void RabinKarp(char* str, char* match,int d,int q)
{
    int len_s = strlen(str);
    int len_m = strlen(match);

    int len_num = len_s - len_m + 1;
    int* arr = new int[len_num];
    int* arr_mod = new int[len_num];
    for (int i = 0; i < len_num; i++)
    {
        arr[i] = 0;
        arr_mod[i] = 0;
    }
    int num = 0;
    int num_match = 0;
    int i;
    for (i = 0; i < len_m-1; i++)
    {
        num += str[i] ;
        num_match += match[i];
        num *= d;
        num_match *= d;
    }
    num_match += match[i] ;
    num += str[i] ;

    int high = pow(d, len_m - 1);
    int mod = q;
    int match_mod = num_match%mod;

    arr[0] = num;
    arr_mod[0] = num%mod;
    if (arr_mod[0] == match_mod)
    {
        for (int i = 0; i < len_m; i++)
        {
            if (str[i] != match[i])
            {
                break;
            }
        }
    }
    int index=0;
    for (int i = 1; i < len_num; i++)
    {
        arr[i] = (arr[i - 1] - (str[i - 1]) * high)*d + str[i + len_m - 1];
        arr_mod[i] = arr[i] % mod;

        if (arr_mod[i] == match_mod)
        {
            for (index = i; index < i+len_m; index++)
            {
                if (str[index] != match[index-i])
                {
                    break;
                }
            }
            if (index == i + len_m)
            {
                printf("Pattern occurs with shift %d\n", i);
            }
        }
    }
}

Boyer-Moore算法
/*
BM算法定义了两个规则:

坏字符规则:当文本串中的某个字符跟模式串的某个字符不匹配时,我们称文本串中的这个失配字符为坏字符,此时模式串需要向右移动,移动的位数 = 坏字符在模式串中的位置 - 坏字符在模式串中最右出现的位置。此外,如果"坏字符"不包含在模式串之中,则最右出现位置为-1。
好后缀规则:当字符失配时,后移位数 = 好后缀在模式串中的位置 - 好后缀在模式串上一次出现的位置,且如果好后缀在模式串中没有再次出现,则为-1。
*/
//本程序只依靠坏字符规则,好字符规则没有实现


----------


int BoyerMoore(char* str, char* pattern)
{
    int len_s = strlen(str);
    int len_p = strlen(pattern);
    int index = len_p-1;
    int begin = 0;
    while (begin+len_p <= len_s)
    {
        int i = len_p - 1;
        while (str[begin + i] == pattern[i]&&i>=0)
        {
            i--;
        }
        if (i < 0)
        {
            return begin;
        }
        char bad = str[begin + i];
        int end = i;
        while (pattern[i] != bad&&i>=0)
        {
            i--;
        }
        begin += end - i;
    }
    return -1;
}

Sunday算法
/*
 Sunday算法由Daniel M.Sunday在1990年提出,它的思想跟BM算法很相似:

只不过Sunday算法是从前往后匹配,在匹配失败时关注的是文本串中参加匹配的最末位字符的下一位字符。
如果该字符没有在模式串中出现则直接跳过,即移动位数 = 匹配串长度 + 1;
否则,其移动位数 = 模式串中最右端的该字符到末尾的距离+1。
*/

int Sunday(char* str, char* pattern)
{
    int len_s = strlen(str);
    int len_p = strlen(pattern);
    int index = len_p - 1;
    int begin = 0;
    while (begin + len_p <= len_s)
    {
        int index = begin;
        while (str[index] == pattern[index - begin])
        {
            index++;
        }
        if (index - begin >= len_p)
        {
            return begin;
        }
        else
        {
            char bad = str[begin + len_p];
            int end = begin+len_p-1;
            index = end;
            while (bad != pattern[index-begin] && index >= begin)
            {
                index--;
            }
            begin += end - index+1;
        }
    }
    return -1;
}
----------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值