zoukankan      html  css  js  c++  java
  • HDU Count the string (KMP)

    题面见http://acm.hdu.edu.cn/showproblem.php?pid=3336

    给你一个字符串,让你找它的前缀在整个字符串出现的次数。

    作为一个不会思考的笨比,直接用kmp去一个个计数,果不其然,t了

    找了博客来看,大概就是kmp+dp,要用到kmp中的pret数组(有的人习惯叫next数组,知道就行)

    dp的方程形式很简单,但很难理解。

    这是原博主的原话:

    如果用dp[i]表示该字符串前i个字符中出现任意以第i个字符结尾的前缀的次数,它的递推式是 dp[i]=dp[pret[i]]+1,

    即以第i个字符结尾的前缀数等于以第pret[i]个字符为结尾的前缀数加上它自己本身,这里要好好理解一下,不太好解释

    这个好好理解就很灵性了,orz。

    仔细看dp[i]代表的含义,以第i个字符结尾的前缀,那么dp[pret[i]]代表什么呢,以第pret[i]结尾的前缀,(pret[i]的字符和i的字符是一样的)

    那么dp[i]和dp[pret[i]]唯一不同的是什么呢?再看刚开始的那句话,dp[i]代表的含义,以第i个字符结尾的前缀,答案就很明显了,虽然它们结尾的字符是一样的

    但dp[i]多了一个它自己本身,于是就有了那个dp方程。

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define INF 0x7fffffffffffffff
    
    typedef long long ll;
    const double PI=3.1415926535897931;
    const long long mod=1e9+7;
    const int MA= 1e7+10;
    const int ma= 2*1e5+10;
    const int few=1e3+10;
    const int maxn=1e8+10;
    using namespace std;
    //////////////////////////////////////////////
    string a;
    int pret[ma];
    int n;
    int dp[ma];
    void pre()
    {
        int i = 0,len = -1;
        pret[0]=-1;
        while (i < n)
        {
            if(len == -1||a[i]==a[len])
            {
                i++;
                len++;
                pret[i] = len;
            }
            else
            {
                len = pret[len];
            }
        }
        return ;
    }
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            cin>>n;
            cin>>a;
            pre();
            ll ans=0;
            dp[0]=0;
            for(int i=1; i<=n; i++)
            {
                dp[i]=dp[pret[i]]+1;
                dp[i]%=10007;
                ans=(ans+dp[i])%10007;
            }
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    如何解决App无法收到android开机广播
    如何实现开机启动、清缓存、杀进程、悬浮窗口单双击区分,附源码
    WaitForSingleObject 介绍【转】
    C++ Unicode SBCS 函数对照表【转】
    数字IP字符串IP转换
    打印内存【CSDN】
    巧妙的无重复随机数方法
    <unnamedtag>”后面接“int”是非法的
    友元函数与重载运算符【转】
    QT QTableWidget 用法总结【转】
  • 原文地址:https://www.cnblogs.com/Aracne/p/12601805.html
Copyright © 2011-2022 走看看