KMP算法

KMP算法

http://www.nowcoder.com/questionTerminal/a376cfc811db43719768b1a79ec3829a

题目描述
给定两个字符串str和match,长度分别为N和M。实现一个算法,如果字符串str中含有子串match,则返回match在str中的开始位置,不含有则返回-1
若出现了多次,则按照升序输出所有出现位置

[要求]
时间复杂度为O(n)O(n)

输入描述:
第一行一个字符串str
第二行一个字符串match

输出描述:
输出若干个数,分别为match在str中出现的位置,从0开始标号。
若不存在输出-1

代码:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

//获取next数组
vector<int> GetNext(string& match)
{
    vector<int> next(match.size() + 1,0);

    //设为-1是为了标记匹配到头了,如果为0可能会导致死循环
    next[0] = -1;

    //从第二个开始
    int i = 2;

    //用来找公共前后缀的指针
    int k = 0;
    while(i < match.size())
    {
        //如果出现相等,代表出现一个相同的前缀
        if(match[i - 1] == match[k])
        {
            //保存
            next[i] = k + 1;

            //更新k的下标
            k = next[i];
            i++;
        }
        //等于-1代表匹配到头,需要重新开始匹配
        else if(k == -1)
        {
            next[i] = 0;
            i++;
        }
        //否则不为-1代表之前还有匹配,继续往前找
        else 
        {
            k = next[k];
        }
    }
    return next;
}

int main()
{
    string str;
    string match;
    while(getline(cin,str))
    {
        getline(cin,match);

        //获取next数组
        vector<int> next = GetNext(match);

        //用来标记是否出现过匹配的情况,题意需要输出-1
        int flag = 1;

        //双指针
        int i = 0;
        int j = 0;

        //开始循环
        while(i < str.size())
        {
            //如果两个位置的字符相等直接++,判断是否匹配完成即可
            if(str[i] == match[j])
            {
                i++;
                j++;
                if(j == match.size())
                {
                    flag = 0;
                    cout<<i - match.size()<<" ";
                    j = next[j];
                }
            }
            //代表两个位子的字符不想等,kmp就是为了不回溯i而回朔j的
            else
            {
                //j回溯到有相同前后缀的位子
                j = next[j];
                if(j == -1)
                {
                    j = 0;
                    i++;
                }
            }
        }
        if(flag)
            cout<<-1<<endl;
    }
    return 0;
}
全部评论

相关推荐

死在JAVA的王小美:哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈,我也是,让我免了一轮,但是硬气拒绝了
点赞 评论 收藏
分享
我已成为0offer的糕手:别惯着,胆子都是练出来的,这里认怂了,那以后被裁应届被拖工资还敢抗争?
点赞 评论 收藏
分享
1 1 评论
分享
牛客网
牛客企业服务