精华内容
下载资源
问答
  • KMP算法实现的C++代码

    2017-10-24 10:43:13
    KMP算法实现的C++代码,KMP算法实现的C++代码,KMP算法实现的C++代码
  • kmp算法c++代码实现(完整版详解)

    千次阅读 多人点赞 2020-02-25 18:23:02
    难理解的还是前后缀表的问题,这个表存的...为什么第一个位置是-1,是因为当他为0的时候在kmp中 当len=0时,(len=prefix[len])之后len=-1,再加1正好是0的下标。 代码 #pragma GCC optimize(3,"Ofast","inline") #...

    难理解的还是前后缀表的问题,这个表存的这些数字的目的是
    就是要碰到不匹配的时候向右移位的个数
    从而防止一些不必要的查找。
    具体这个表里储存的什么内容呢请看下图
    因为字符串下标从0开始,所以为了方便操作,我把数组整体往后移了一位
    整体后移以后,我没有去掉最后最长的前后缀那个一数(因为方便我找出所有的字符串)
    把最开头补上-1
    为什么第一个位置是-1,是因为当他为0的时候在kmp中 当len=0时,(len=prefix[len])之后len=-1,再加1正好是0的下标。
    在这里插入图片描述
    再看这一张图(当匹配失败时的操作)当匹配失败,查询prefix表中当前的值并将它付给len (代码中&&&&&&&&&标记位置
    这样子做的目的显而易见,我们可以少进行两次比较从而减少时间复杂度
    在这里插入图片描述

    再看这一张图,这就是为什么不删掉最长的原因,因为prefix[len] (当len=他的实际长度时)就发挥作用了 (这里对应着我代码里标*******的位置
    当找到一个时,我们可以直接移动,从而少查找了 ABA 三位
    当然如果只找第一次出现的位置可以不需要储存最长的那一段表的数字也就是(ABABCDABA)
    在这里插入图片描述

    代码

    #pragma GCC optimize(3,"Ofast","inline")
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <math.h>
    #include <string>
    #include <list>
    #include <set>
    #include <map>
    #include <queue>
    #include <stack>
    #include <algorithm>
    #include <stdlib.h>
    #define maxn  1000005
    //#define true false
    //#define false true
    const int MaxN = 0x3f3f3f3f;
    const int MinN = 0xc0c0c00c;
    const double pi = acos(-1);
    typedef long long ll;
    const int mod = 1e9 + 7;
    using namespace std;
    string s, t;
    int prefix[1000];
    int firstplace;
    void prefix_table() {  //求前后缀表
        prefix[0] = -1;
        int i = 0, len = -1;
        while (i < s.size()) {
            if (len == -1 || s[i] == s[len]) {
                i++, len++;
                prefix[i] = len;
            }
            else  len = prefix[len];  //&&&&&&&&&&&&
        }
    }
    
    int ans_kmp() {
        int i = 0, len = 0;
        bool flag = false;
        int ans = 0;
        prefix_table();
        while (i < t.size()) {
            if (len == -1 || s[len] == t[i])  i++, len++;
            else  len = prefix[len];
            if (len == s.size()) {
                if (flag == false)  firstplace = i - s.size() + 1;
                ans++;
                cout << i - s.size() + 1 << endl;
                len = prefix[len];  //这一块处理看上图  ********
                flag = true;
            }
        }
        if (flag)  return ans;
        else  return-1;
    }
    
    int main()
    {
        cin >> t;
        cin >> s;
        int sum = ans_kmp();
        cout << endl;
        if (sum) {
            cout << "出现的总次数为: " << sum << endl;
            cout << "第一次出现此字符串的位置为: " << firstplace << endl;
        }
        else   cout << "not found!" << endl;
    
        return 0;
    }
    
    
    

    因为也是新手,刚接触这个算法,所以有什么问题和不足欢迎大家指出。

    展开全文
  • KMP算法c++代码

    千次阅读 2019-04-15 21:26:11
    1、kmp算法的核心就是减少不必要的回溯,也就是说,我们在匹配到中间某个字符发现失配的时候,不需要重头再来(回忆太累人了你说是吧),我们已经在过程中有了很多线索,这些线索可以帮助我们只回溯到必要的部分。...

    先放代码,对着代码来讲一讲(代码没加注释)

    
    #include<iostream>
    
    #include<string.h>
    const int MAXLEN = 50;
    int next[MAXLEN] = { 0 };
    int nextval[MAXLEN] = { 0 };
    
    void get_next(char s[],int lens)
    {
    	int j = 0;
    	int k = -1;
    	next[j] = k;
    	while (j < lens-1)
    	{
    		if (k == -1 || s[j] == s[k])
    		{
    		    k++;
    		    j++;
    		    next[j] = k;
    		}
    		else
    		    k = next[k];
    	}
    }
    
    int main()
    {
    	char strings[] = "hello worldolollo,I'm the king of the world,and you'll be die!";
    	char pattern[] = "olol";
    	int lens = strlen(strings);
    	int lenpatt = strlen(pattern);
    	get_next(pattern, lenpatt);
    	int i = 0, j = 0;
    	while (i < lens&&pattern[j]!='\0')
    	{
    		if (j == -1 || strings[i] == pattern[j])
    		{
    			i++;
    			j++;
    		}
    		else
    		{
    			j = next[j];
    		}
    	}
    	if (pattern[j] == '\0')
    		printf("%d\n", i - lenpatt);
    	else
    		printf("not found\n");
    		return 0;
    }

    1、kmp算法的核心就是减少不必要的回溯,也就是说,我们在匹配到中间某个字符发现失配的时候,不需要重头再来(回忆太累人了你说是吧),我们已经在过程中有了很多线索,这些线索可以帮助我们只回溯到必要的部分。

    这里我给出一个粗略的理解:

    这就是回溯位置的函数,很直观的一个理解就是,字符串1由ABCABD六个子串(每个子串都有若干字符)连接而成,字符串2由ABCABE组成,这时候匹配到E自然就产生失配,可是我们不需要回到开头的那个A。如下图(灵魂画手上线),我们想找一个位置可以减小回溯,那么这个位置之前,也就是第三行格子紫色格子之前,必须和第一行格子(也就是要匹配的文本)对应位置匹配,而由之前的步骤可知,图中3处 已经和图中2处匹配,所以我们要找的位置有这样的位置关系

    1处==2处

    2处==3处

    所以 1处==3处 也就是1处等于4处(因为第二行和第三行是一模一样滴),这也就是上面的函数表达式。

    理解了算法的思路,关键在于求next 数组 。而求next数组其实也是利用了上面的思想,具体可看代码,仔细想想。

    展开全文
  • KMP算法C++实现)

    2013-07-08 11:16:42
    *KMP算法的思想就是在匹配过程称若发生不匹配的情况 *如果next[j]>=0则目标串的指针i不变将模式串的指针j移动到next[j]的位置继续进行匹配 *若next[j]=-1则将i右移1位并将j置0继续进行比较 *...
  • KMP算法C++实现

    2017-10-27 14:13:47
    原创作者:Daniel 日期:2017.9.27 ...KMP算法包括两个过程: 1.计算模式的特征向量 int * next(string P ){ int m = P.length(); int* M = new int[m]; M[0] = 0; for(int i = 1; i ; ++i){ i

    原创作者:Daniel

    日期:2017.9.27

    地点:大连理工大学软件学院

    KMP算法包括两个过程:

    1.计算模式的特征向量

    int * next(string P ){
        int m = P.length();
    
        int* M = new int[m];
    
        M[0] = 0;
    
        for(int i = 1; i < m; ++i){
    
            int k = M[i -1];
    
            while(k > 0 && P[k] != P[i])
                k = M[k - 1];
            if(P[k] == P[i])
                M[i] = k + 1;
            else
                M[i] = 0;
        }
    
        return M;
    }
    


    2.KMP模式匹配算法

    int KMPstring_match(const string & P, const string & T, int* next ){
        int i = 0;
        int j = 0;
        while(T[i] != '\0' && P[j] != '\0'){
    
            if(T[i ] == P[j]){
                i++;
                j++;
            }
            else{
                if(j == 0)
                    i ++;
                else
                    j = next[j - 1];
            }
        }
    
        if( j == P.length())
            return i - j;
        else
            return -1;
    }



    具体讲讲模式的特征向量的求法。

    KMP算法实际上是根据模式自身的特点来简化传统模式匹配过程的,在传统配

    过程中,每次匹配不满足时,都会将模式指针 p = 0,然后让目标上的指针 t ++,所

    以,每匹配一次都会进行回溯,造成了效率低下,具体时间复杂度是:O(M*N);

    下边是传统模式匹配C++代码:

    int naive_string_match(string P, string T){
         int p = 0;
         int t = 0;
         int plen = P.length();
         int then = T.length();
         while(P[p] != '\0'&& T[t] != '\0'){
    
                if(P[p] == T[t]){
                     p++;
                     t++;
                }
               else{
                   p = 0;
                   t = t - p + 1  //为了将t移动到下一个匹配位置。
                    }
       }
         if(p >= plen)
              return t - p;
         else
              return -1
    }


    可以看到,在匹配失败后,仅仅将模式右移动了一位。

    特征向量 next()函数求法:

       特征向量的分量n[i]如下定义:

       1、n[0] = 0,对于 i > 0 的 n[I] ,n[i - 1] = k;

       2、如果i > 0,并且 P[k] = P[i],n[i] = k + 1;

       3、如果P[k] != P[i] , 令 k = n[k -1];

       4、如果P[k] != P[i] && k == 0 , n[i] = 0;

    在 i 位置匹配失败后,就直接从P[i - n[i - 1]]继续匹配,避免了回溯。

    在模式走到结尾时 返回 EOF;

    模式匹配成功返回 i - j;


    展开全文
  • KMP算法c++实现

    千次阅读 2017-03-16 21:44:28
    一、原理看下面视频 ... 二、c++代码: #include #include #include #include using namespace std; void get_next(string s1, int next[]){

    一、原理看下面视频

    http://baidu.ku6.com/watch/1196605033445674118.html?page=videoMultiNeed


    二、c++代码:

    #include<iostream>
    #include<cmath>
    #include<vector>
    #include<cstring>
    using namespace std;
    
    void get_next(string s1, int next[]){
        int len = s1.size();
        next[0] = 0;
        int i=1;
        int j=0;
        while(i<len){
            if(s1[i] == s1[j]){
                next[i] = j+1;
                i++;
                j++;
            }else{
                while(j>0 && s1[i]!=s1[j]){
                    j = next[j-1];
                }
                if(s1[i] == s1[j]){
                    next[i] = j+1;
                    i++;
                    j++;
                }else if(j == 0 && s1[i] != s1[j]){
                    next[i] = 0;
                    i++;
                }
            }
        }
    
    }
    
    bool kmpAlgorithm(string s1, string s2, int next[]){
        //s1是主串,求s2是否能在s1中模糊匹配出来
        int len1 = s1.size();
        int len2 = s2.size();
        //next的长度和s2的长度是一样的
        int j=0;  //i用来遍历s1,j用来遍历s2
    
        for(int i=0;i<len1;i++){
            while(j>0 && s1[i]!= s2[j]){
                j = next[j];
            }
            if(s1[i] == s2[j]){
                j++;
            }
            if(j == len2){
                return true;
            }
        }
    
        return false;
    }
    
    
    
    int main(){
        string s1,s2;
        while(cin>>s1>>s2){
            //s1是主串,s2是要判断的串
            int *next = new int[s2.size()+1];
            get_next(s2, next);
            cout<<s1<<endl;
            cout<<s2<<endl;
            cout<<kmpAlgorithm(s1, s2, next)<<endl;
        }
    
        return 0;
    }

    next数组的测试用例

    s字符串: aabaabaaa

    next数组:010123452

    s字符串:abcaby

    next数组:000120

    展开全文
  • kmp算法c++

    2012-11-24 18:19:14
    kmp的改进算法 有next函数的输出 可查询多处字符
  • void get_next(string s, vector&lt;int&gt;&amp;next) {  int len = s.size();  next.resize(len);  int i, j;  i = 0;  j = -1;  next[0]=-1;... len-1)  {  if (j == -1||s[j]=...
  • kmp算法c++模板

    2020-04-12 03:20:17
    } } int kmp(string t, string p) { //t, p都从位置1开始存储 int i = 1, j = 1, count = 0; while (i ()) { while (i () && j ()) { if (j == 0 || t[i] == p[j]) { i++; j++; } else { j = n[j]; } } if (j == p....
  • KMP算法C++实现

    2020-08-25 17:09:22
    KMP算法由D.E.Knuth,J.H.Morris和V.R.Pratt提出,因此称为KMP算法KMP算法是一种用于字符串匹配的算法,能够从一个主串中快速找出是否存在需要的模式串。相比于暴力法,KMP算法在时间复杂度上有很大的改善。暴力法...
  • KMP算法代码

    2016-09-12 16:14:11
    KMP next算法
  • kmp算法c++实现

    2019-08-12 11:45:27
    KMP_index ( const char * mainStr , const char * patternStr , int * next ) { int i = 0 , j = 0 ; cout "patternStr length: " strlen ( patternStr ) endl ; cout...
  • 字符串匹配KMP算法C++代码实现

    千次阅读 2016-10-30 10:21:03
    看到了一篇关于《字符串匹配的KMP算法》(见下文)的介绍,地址:http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html,这篇博客对KMP算法的解释很清晰,但缺点是没有代码的...
  • KMP算法详解及C++实现

    2021-10-04 14:29:24
    目录一、介绍KMP算法解决的问题二、KMP算法的核心思想三、KMP的代码实现(C++) 一、介绍KMP算法解决的问题 KMP算法实际上解决的是一个字符串匹配的问题,即从一个目标字符串(通常非常长)中找到与给定字符串(也...
  • KMP算法c++实现(完整代码)

    千次阅读 2020-03-28 22:55:17
    因为看了《大话数据结构》里的KMP算法的实现,里面用的是c语言的写法,因此通过学习整理思路通过C++实现 如果你看不懂为什么要这样做,建议先看看《大话数据结构》或者其他数据结构的书或资料。 首先是:get_next...
  • KMP算法C++实现。

    2020-03-04 17:45:47
    KMP算法 KMP 匹配算法是由 "Knuth Morris Pratt" 提出的一种快速的模式匹配算法。 hint:不为自身的最大首尾重复子串长度 1.待解决的问题:假设P为给定的子串,T是待查找的字符串,要求从T中找出与P相同的所有...
  • C++实现的KMP算法

    2009-09-04 18:56:24
    C++语言实现的KMP算法。经过调试。供广大算法学习者参考。
  • KMP算法 C++

    2018-08-08 21:44:11
    int KMP(char* S, char* T, int next[]){ int s_size = strlen(S); int t_size = strlen(T); int i = 0, j = 0; while(i){ if(j==-1 || S[i] == T[j]){ ++i; ++j; } else if(j==0){ ++i; } ...
  • kmp算法c++实现

    千次阅读 2018-10-31 09:25:01
     KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串...
  • KMP算法 C++代码

    2013-09-06 22:03:32
    int KMPIndex(char S[],char T[], int nextval[], int pos) { int i=pos; int j=1; while(i[0] && j[0]) { if(j==0 || S[i]==T[j]) { ++i; ++j; } else j=nextval[j]; } if(j>T[0]) ...}
  • KMP算法c++实现,根据一篇讲解kmp算法的文档写的,带工程可编译,可以直接作为项目代码使用,也可以作为学习使用,实现简单、灵活
  • KMP算法C++实现及解释(简洁,通俗易懂) 最近在回顾字符串的匹配相关算法,把之前的思路又理了理。 问题描述 有两个字符串str1和str2,我们想知道str2是否在str1中。计算机实现这个有很多算法,比如BF算法(暴力...
  • KMP算法(C++)

    2018-07-18 15:55:44
    KMP算法: void getNext(const string&amp; needle,int next[]) { const int n = needle.size(); int i = 0; int j = -1; next[i] = j; while (i &lt; n) { if (j == -1 || needle[i] == needle[j...
  • } } int kmp_index(const string& str1,const string& str2,int next[]) { int i = 0;int j = 0; while(i { if(j==-1||str1[i]==str2[j]) { ++i; ++j; } else j = next[j]; } if(j==str2.length()) return i-str2....
  • KMP算法 c++

    2018-11-04 17:29:36
    我不认为以我乏力的描述能讲清楚KMP算法,所以我在这里推荐两个大佬写的博客,以供我自己遗忘时再次复习。 NEXT数组的理解: https://blog.csdn.net/lee18254290736/article/details/77278769 作者:JensLee KMP...
  • C++模板实现的数据结构字符串类,实现了字符串的拼接、删除、截取、转换、匹配、替换等常用功能,其中匹配算法使用了基于KMP的快速匹配算法。程序具有良好的编码风格和详细的算法注释。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,438
精华内容 4,175
关键字:

kmp算法c++

c++ 订阅