<九度 OJ>题目1094:String Matching


题目描述:

    Finding all occurrences of a pattern in a text is a problem that arises frequently in text-editing programs. 
    Typically,the text is a document being edited,and the pattern searched for is a particular word supplied by the user.  
    We assume that the text is an array T[1..n] of length n and that the pattern is an array P[1..m] of length m<=n.We further assume that the elements of P and  T are all alphabets(∑={a,b...,z}).The character arrays P and T are often called strings of characters.  
    We say that pattern P occurs with shift s in the text T if 0<=s<=n and T[s+1..s+m] = P[1..m](that is if T[s+j]=P[j],for 1<=j<=m).  
    If P occurs with shift s in T,then we call s a valid shift;otherwise,we calls a invalid shift. 
    Your task is to calculate the number of vald shifts for the given text T and p attern P.

输入:

   For each case, there are two strings T and P on a line,separated by a single space.You may assume both the length of T and P will not exceed 10^6. 

输出:

    You should output a number on a separate line,which indicates the number of valid shifts for the given text T and pattern P.

样例输入:
abababab abab
样例输出:
3
KMP算法的简单应用

<span style="font-size:12px;">#include <iomanip>//小数点精确
#include <cstdio>  
#include <cstdlib>  
#include "vector"
#include "string"
#include "algorithm"
#include <iostream>
#include "stack"
#include "math.h"  
 
using namespace std;
 
//计算模式P的部分匹配值,保存在next数组中    
void MakeNext(const string &P, vector<int> &next)
{
    int q, k;//k记录所有前缀的对称值    
    int m = P.size();//模式字符串的长度    
    next[0] = 0;//首字符的对称值肯定为0    
    for (q = 1, k = 0; q < m; ++q)//计算每一个位置的对称值    
    {
        //k总是用来记录上一个前缀的最大对称值    
        while (k > 0 && P[q] != P[k])
            k = next[k - 1];//k将循环递减,值得注意的是next[k]<k总是成立    
        if (P[q] == P[k])
            k++;//增加k的唯一方法    
        next[q] = k;//获取最终值    
    }
}
 
 
int KmpMatch(const string &T, const string &P, vector<int> &next)
{
    int n = 0, m = 0, count = 0;
    n = T.size();
    m = P.size();
    MakeNext(P, next);
    for (int i = 0, q = 0; i < n; ++i)
    {
        while (q > 0 && P[q] != T[i])
            q = next[q - 1];
        if (P[q] == T[i])
            q++;
        if (q == m)
        {
            q = next[q - 1];//寻找下一个匹配  
            count++;
        }
    }
    return count;
}
 
int main()
{
    string T;//文本  
    string P;//待搜索字符串 
    vector<int> next(200, 0);//保存待搜索字符串的部分匹配表(所有前缀函数的对称值)  
    while (cin >> T >> P)
    {//本题为kmp算法的简单应用
        cout << KmpMatch(T, P, next) << endl;
    }
         
    return 0;
}
/**************************************************************
    Problem: 1094
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:160 ms
    Memory:3052 kb
****************************************************************/</span>


注:本博文为EbowTang原创,后续可能继续更新本文。如果转载,请务必复制本条信息!

原文地址:http://blog.csdn.net/ebowtang/article/details/43567601

原作者博客:http://blog.csdn.net/ebowtang

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值