Kmp算法笔记

最近刷了一个Kmp的题目才发现,自己对Kmp算法只是一知半解,就去复习了一下。

看了几个版本的算法都感觉不太好,算导的代码感觉不够清晰,其他版本的竟然都是从1开始而非大家习惯的0。经历了各种痛苦之后,终于得到的正确的结果。

懒得写过程,直接上代码吧,主要给自己看的。。。

class KMP
    {
        public int Match(string target, string pattern)
        {
            int n = target.Length;
            int m = pattern.Length;
            var next = GetNext(pattern);
            int i = 0;
            int j = 0;
            while (i < n && j < m)
            {
                if (j == -1 || target[i] == pattern[j])//理由同上
                {
                    i++;
                    j++;
                }
                else
                {
                    j = next[j];
                }
            }
            if (j == m)
                return i - j;
            return -1;
        }

        private int[] GetNext(string pattern)
        {
            int m = pattern.Length;
            int[] next = new int[m];
            next[0] = -1; //按照算导的理论来说,这里应该是0,但是我们其实使用的是索引而不是偏移量,有所区别,但是道理一样。长度为0时,那么前面的索引值肯定小于0,我们用的是-1,因为方便
            int k = -1;//让整个操作过程能够统一,就从-1开始
            int i = 0;//可以让i从第二个字符开始匹配
            while (i < m - 1)
            {
                if (k == -1 || pattern[i] == pattern[k])//全不匹配时,让i后移一个单位,当k为-1时,有一次循环i的值不会变,这里就是一个校正的过程。
                {
                    i++;
                    k++;
                    if (pattern[i] == pattern[k])//用于放置aaaaa这种重复时的无效匹配过程,算是一种优化吧。
                        next[i] = next[k];
                    else
                        next[i] = k;
                }
                else
                {
                    k = next[k];
                }
            }

            return next;
        }
    }

  

转载于:https://www.cnblogs.com/36hours/p/KMP.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值