zoukankan      html  css  js  c++  java
  • 子串查找【哈希算法】

    子串查找

    传送门: 链接   来源: UPC8170

    题目描述

    给定一个字符串A和一个字符串B,求B在A中的出现次数。A和B中的字符均为英语大写字母或小写字母。
    A中不同位置出现的B可重叠。

    输入

    输入共两行,分别是字符串A和字符串B。

    输出

    输出一个整数,表示B在A中的出现次数。

    样例输入

      zyzyzyz

      zyz

    样例输出

      3

    提示

    1≤A,B的长度≤106,A、B仅包含大小写字母。

    思路:

    之前总结过string的函数和它的很多用法,直接用string暴力(反正b的长度知道,只需要枚举起点即可),结果T了。

    (知道string耗时高,但也太高了吧!!)

    TLE的代码:

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        string a,b;
        cin>>a>>b;
        int la=a.size(),lb=b.size();
        int cnt=0;
        for(int i=0;i<la;i++){
            if(a[i]==b[0]&&i+lb<=la){
                string c(a.begin()+i,a.begin()+i+lb);
                //cout<<c<<endl;
                if(b==c) cnt++;
            }
        }
        cout<<cnt;
        return 0;
    }
    

    就用hash写了,hash之前没接触过,看了讲解之后感觉就是把密码加密其它字符的一个过程,它的密码本有很多种,所以如果出现加密后相同的结果就要更换加密方式了,不然会被hack掉。

    我用的这个模板来自: 任小喵r

    里面用的转化方法是化成k进制(k=26 好像不太容易被hack)即进制哈希,但里面没有对求出的hash值取模所以肯定会爆long long,如果单纯是用hash的话,爆就让它爆了也不会影响结果,但要做类似记录一个hash值并让它与后面的数比较那就要取模了,不然很可能wa。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const LL MAX=1e6;
    LL ha[MAX+5];
    LL k=26;
    LL qpow(LL m,LL q)
    {
        LL ans=1;
        while(q){
            if(q%2){
                ans*=m;
            }
            m*=m;
            q/=2;
        }
        return ans;
    }
    LL hashb(string b)
    {
        LL ans=0,lb=b.size();
        for(LL i=lb-1;i>=0;i--)
            ans=ans*k+b[i];
        return ans;
    }
    
    void hasha(string a)
    {
        LL la=a.size();
        for(LL i=la-1;i>=0;i--){
            ha[i]=ha[i+1]*k+a[i];
        }
    }
    
    int main()
    {
        string a,b;
        cin>>a>>b;
        LL la=a.size(),lb=b.size();
        LL hb=hashb(b);
        hasha(a);
        LL num=qpow(k,lb),ans=0;
        for(LL i=0;i<=la-lb;i++){
            if(hb==ha[i]-ha[i+lb]*num){ ///要是不理解就把k换成10,自己出样例模拟一下就懂了
                ans++;
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    
  • 相关阅读:
    Django数据库查询优化-事务-图书管理系统的搭建
    模型层字段-多表查询-神奇的双下划线查询-F,Q查询
    Django的View(视图)-settings源码的解析-模板层-模板语法
    Django路由层与视图层
    Django框架的前奏(安装及介绍)
    面向对象的三大特性
    一,类的初识
    一,对象初识
    装饰器
    闭包
  • 原文地址:https://www.cnblogs.com/ldu-xingjiahui/p/12407417.html
Copyright © 2011-2022 走看看