KMP hihoCoder1015 KMP算法

人太蠢,,看了一天的KMP。。

刚开始看训练指南的,,后来才惊奇的发现原来刘汝佳写的f数组并不是Next数组!

总觉得和之前看过的完全不一样。。。

后来又百度了一下KMP,研究了很久,然后用自己的逻辑写了一份

http://blog.chinaunix.net/uid-23767307-id-5033555.html

这个人把KMP大篇幅的讲了,,大家可以看看。。

个人认为只要能理解Next数组的意义后,写出KMP算法就不是很难了

然而自己语文也不好就不多做解释了,,直接贴下我的模板好了

#include<map>
#include<set>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;

const int MX = 1e6 + 5;

char S1[MX], S2[MX];
int Next[MX];

int KMP(char *A, char *B) {
    int m = strlen(A), n = strlen(B);

    Next[0] = 0;
    for(int i = 1; i < n; i++) {
        int k = Next[i - 1];
        while(B[i] != B[k] && k) k = Next[k - 1];
        Next[i] = B[i] == B[k] ? k + 1 : 0;
    }

    int ans = 0, j = 0;
    for(int i = 0; i < m; i++) {
        while(A[i] != B[j] && j) j = Next[j - 1];
        if(A[i] == B[j]) j++;
        if(j == n) ans++;
    }
    return ans;
}

int main() {
    int T, ansk = 0;
    //freopen("input.txt", "r", stdin);
    scanf("%d", &T);
    while(T--) {
        scanf("%s%s", S1, S2);
        printf("%d\n", KMP(S2, S1));
    }
    return 0;
}

其中,如果想函数返回的是出现的次数,而不是匹配的次数

因为匹配的次数中会有一些部分是重叠的,那只要改一个地方就行了

把if(j == n) ans++;换成if(j == n) ans++, j = 0;就可以了

int KMP(char *A, char *B) {//A是被搜索的串,B是搜索的内容,返回B在A中出现的次数
    int m = strlen(A), n = strlen(B);

    Next[0] = 0;
    for(int i = 1; i < n; i++) {
        int k = Next[i - 1];
        while(B[i] != B[k] && k) k = Next[k - 1];
        Next[i] = B[i] == B[k] ? k + 1 : 0;
    }

    int ans = 0, j = 0;
    for(int i = 0; i < m; i++) {
        while(A[i] != B[j] && j) j = Next[j - 1];
        if(A[i] == B[j]) j++;
        if(j == n) ans++, j = 0;
    }
    return ans;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-06 11:56:07

KMP hihoCoder1015 KMP算法的相关文章

KMP及其改进算法

本文主要讲述KMP已经KMP的一种改进方法.若发现不正确的地方,欢迎交流指出,谢谢! KMP算法的基本思想: KMP的算法流程: 每当一趟匹配过程中出现字符比较不等时,不需回溯 i 指针,而是利用已经得到的部分匹配的结果将模式向右滑动尽可能远的一段距离后,继续进行比较. 设S为目标串,T为模式串,设 i 指针和 j 指针分别指示目标串和模式串中正待比较的字符. 开始时,令i=0,j=0.如果Si==Tj,则使i和j的值分别增加l:反之,i不变,j的值退回到j=next[j]的位置(即模式串右滑)

关于两个字符串的kmp比对算法

关于两个字符串的kmp比对算法 假设有字符串X和Y,满足len(X)>len(Y),要比对这两个字符串. 我们知道,最朴实的方法,就是现将二者对齐,然后依次比对对应位置的字符.如果能匹配到Y最后位置,则匹配成功:如果匹配失败,则将Y右移一位,再从头进行匹配. 设字符串X为dababeabafdababcg:字符串Y为ababc. 这种比对方法如下所示: 起始时,二者对其,第一个字符不匹配 :| :dababeabafdababcg :ababc 右移一位,比对位置移动到Y起始位置 : | :da

字符串(1)---KMP &amp; 扩展KMP &amp; Manacher

练习:点击打开链接 字符串也是ACM中的重头戏,基本内容有KMP ,扩展KMP, Manacher ,AC自动机,后缀数组,后缀自动机.按照专题来做共分三部分. LCS LIS LCIS不知道算不算....点击打开链接 小技巧:匹配问题不区分大小写,则将其全部转为小写. 暴力匹配: 用strstr函数就能解决       I M N Z(枚举长度 三份) 一.KMP算法 解决单一模式串匹配问题. 利用失配后的nxt数组减少移位,达到O(n)级别.资料自行百度. 延展: 1.求最小循环节 点击打开

KMP &amp; 扩展KMP &amp; Manacher 专题

KMP & 扩展KMP & Manacher  专题 先来模版: void getNext(int *b,int m) { Next[0]=-1; int i=0,j=-1; while(i<m&&j<m){ if(j==-1||b[i]==b[j]) Next[++i]=++j; else j=Next[j]; } } int kmp(int *a,int *b,int n,int m) { getNext(b,m); int i=0,j=0; while(i

[kuangbin带你飞]专题十六 KMP &amp; 扩展KMP &amp; Manacher :G - Power Strings POJ - 2406(kmp简单循环节)

[kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher G - Power Strings POJ - 2406 题目: Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of

KMP&amp;扩展KMP

声明 本文将不断加入例题,稍安勿躁,今天的总结争取9:30写完. KMP KMP,中文名字叫字符串匹配,用于解决一类字符串匹配问题. 先下一些定义: \(s\)表示匹配串,\(t\)表示文本串,字符串匹配用于求\(s\)在\(t\)中的出现情况. \(n\)和\(m\)分别为\(s\)和\(t\)的字符串串长. \(nxt_i\)表示对于\(s\)的前缀\(s_{1...i}\)的最长公共前后缀. 首先我们先想一想\(nxt_i\)对于求解问题有怎样的帮助. 暴力匹配 我们对于每一个\(t_i=

【数据结构】 字符串&amp;KMP子串匹配算法

字符串 作为人机交互的途径,程序或多或少地肯定要需要处理文字信息.如何在计算机中抽象人类语言的信息就成为一个问题.字符串便是这个问题的答案.虽然从形式上来说,字符串可以算是线性表的一种,其数据储存区存储的元素是一个个来自于选定字符集的字符,但是字符串由于其作为一个整体才有表达意义的这个特点,显示出一些特殊性.人们一般关注线性表都会关注其元素和表的关系以及元素之间的关系和操作,而字符串常常需要一些对表整体的关注和操作. 字符串的基本概念如长度,比大小,子字符串等等这些,只要有点编程基础的人都懂就不

KMP和BF算法-C语言实现

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <malloc.h> //以下为KMP算法 void get_next(char * T, int next[]) //修正前的next数组 { int i = 1, j = 0; next[0] = -1; next[1] = 0; int m = strlen(T); while (i<strlen(T) - 1)

KMP字符串查找算法

#include <iostream> #include <windows.h> using namespace std; void get_next(char *str,int *num) { int idFront = 0; int len = strlen(str); int amount = 1; int flag = 0;//相等时一直往下循环 int flag2 = 0;//标记是否在循环过程中不匹配,如果在循环过程中不匹配,则要防止跳过这个数 for(int i =