KOBOSP

导航

简单kmp算法(poj3461)

题目简述:

    给你两个字符串p和s,求出p在s中出现的次数。

思路简述:

    在介绍看BF算法时,终于了解到了大名鼎鼎的KMP算法,结果属于KMP从入门到放弃系列,后来看了几位大神的博客,似乎有点懂了。此题为KMP算法的简单应用。

KMP简述:

    BF算法为穷举法,而此法通过next数组的指引,巧妙的跳过了模式串即短的那串中几个不需要去比较的字符,实现效率的提高。next数组为模式串前后完全重复的最大子串,前串以第一个字母开

    头,后串以所求数值的前一位为结束,重复最大子串中字母数量即next数组相应位置的值。还有一种可以优化的情况,下面的代码没写进去。百度

基础版代码:

#include <iostream>
#include <cmath>
#include<stdio.h>
#include <cstdio>
#include <cstring>
#include<algorithm>
using namespace std;


#define N 100010 char s[N * 10], p[N];//s为输入长的,p为短的 int nextval[N]; int lens, lenp; void getnext()//根据模式串得出next数组 { int i = 0, j = -1; nextval[0] = -1;//next数组最前面为-1 while (i != lenp)//当后搜索符未达到模式串即短的那串的结束 { if (j == -1 || s[i] == s[j])//前搜索符刚刚开始搜索或前后搜索符对应字母相等时 nextval[++i] = ++j;//进行相应next的赋值 else j = nextval[j];//前搜索符回到开始或已经得到的相应的next值,后搜索符不变 } } int KMP() { int i = 0, j = 0, count = 0; while (i != lens && j != lenp)//因为是要得到所有所处的位置 { if (s[i] == p[j] || j == -1)//前搜索符刚刚开始搜索或前后搜索符对应字母相等时 ++i, ++j; else j = nextval[j]; //前搜索符回到开始或已经得到的相应的next值,后搜索符不变 if (j == lenp)//当到达短的那串结尾时,说明一次完全匹配完成 { count++; j = nextval[j];//把前搜索符转到相应next值处 } } return count; } int main() { int ncase; int len; int ans; scanf("%d", &ncase); while (ncase--) { scanf("%s %s", p, s); lens = strlen(s); lenp = strlen(p); getnext(); ans = KMP(); printf("%d\n", ans); } return 0; }

  

posted on 2018-01-25 00:54  KOBOSP  阅读(154)  评论(0)    收藏  举报