Day20

昨天没能把BM算法看明白,今天又把各种演示和说明文字看了一圈,大概有些明白了,但是好后缀的部分看到别人的代码又有些蒙圈,不过暂时还是记下,免得以后找都没地方找。

代码参考:典型字符串匹配算法实现

//BM算法主体
int BMMatch(char[] str, char[] subStr)
{
    int[] bc = BadCharacter(subStr);
    int[] gs = GoodSuffix(subStr);
    int i = 0;
    while(i+subStr.Length < str.Length)
    {
        int j = subStr.Length - 1;
        while(subStr[j] == str[i+j])
        {
            j--;
            if(j < 0)
            {
                break;               //对比结束
            }
        }
        if(j<0)
        {
            break;                   //对比结束
        }
        else
        {
            i += Max(gs[j], j-bc[T[i+j]]);   //在坏字符的情况和好后缀的情况中选一个可移动的最长的步长
        }
    }
}

//记录成为坏字符的英文字符与移动步长关系的数组
int[] BadCharacter(char[] subStr)
{
    int m = subStr.Length;
    int[] bc = new int[256];
    for(int i = 0; i<256; i++)
    {
        bc[i] = m;
    }
    for(int i = 0; i<m; i++)
    {
        bc[(int)subStr[i]] = m - i - 1;
    }
    return bc;
}

//好后缀分为3种情况:
//1. subStr中有子串匹配好后缀,则subStr中最靠右的与好后缀相同的子串同好后缀对齐;
//2. subStr中没有子串匹配好后缀,但有最大前缀与好后缀靠右子串匹配,则将subStr中的最大匹配前缀与好后缀中相匹配的字符对齐;
//3. 以上两种情况都不存在,则直接向后移动subStr的长度的位置。

//所以需要两个数组用来记录:
//1. 好后缀的最后一个字符之前的字符与好后缀最大长度的关系
//2. 好后缀前的第一个字符与subStr将要移动的步长的关系
int[] Suffixes(char[] subStr)
{
    int m = stbStr.Length;
    int f = 0;
    int g = m-1;
    int[] suff = new int[m];
    for(int i = 0; i < m; i++)
    {
        suff[i] = 0;
    }
    suff[m-1] = m;
    for(int i = m-2; i >=0; i--)
    {
        if(i > g && suff[i+m-1-f] < i-g)
        {
            suff[i] = suff[i+m-1-f];
        }
        else
        {
            if(i < g)
            {
                g = i;
            }
            f = i;
            while(g>=0 && subStr[g] == subStr[g+m-1-f])
            {
                g--;    
            }
            suff[i] = f-g;
        }
    }
    return suff;
}
int[] GoodSuffix(char[] subStr)
{
    int m = subStr.Length;
    int[] suff = Suffixes(subStr);
    int[] gc = new int[m];
    for(int i = 0; i<m; i++)
    {
        gs[i] = m;
    }
    int j = 0;
    for(int i = m-1; i>=0; i--)
    {
        if(suff[i] == i+1)
        {
            for(j = 0; j<m-1-i; j++)
            {
                if(gs[j] == m)
                {
                    gs[j] = m-1-i;
                }
            }
        }
    }
    for(int i = 0; i <= m-2; i++)
    {
        gs[m-1-suff[i]] = m-1-i;
    }
}

坑爹的盗版最后一章讲排序,然后也是大部分都被cut掉了。。。所以接下来以另一本书为教材复习之前没复习到的地方,感觉还挺多的。。。真希望一天能有72个小时。。。意识到光复习理论知识,但是还没有刷过题。。。/(ㄒoㄒ)/~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值