题目描述:

这是一道模板题。

给定一个字符串 A 和一个字符串 B ,求 B 在 A  中的出现次数。A 和 B中的字符均为英语大写字母。

求A 在 B 中出现了几次。(可重叠)

样例输入:

3

BAPC

BAPC

AZA

AZAZAZA

VERDI

AVERDXIVYERDIAN

样例输出:

1

3

0

首先要知道什么是字符串hash(滚动哈希):

  单哈希可以O(m)的时间计算长度为m的字符串的哈希值,但对于本题,总的时间复杂度没有改观。时间会爆。

  这时我们就需要一个叫做滚动哈希的优化技巧。

  我们选取两个合适的互质常数b和h(b<h),假设字符串C=c1c2……cm,那么我们定义哈希函数:H(C)=(c1bm-1+c2bm-2+……+cmb0) mod h 。

  正常数字是十进制的,这里b是基数,相当于把字符串看做是b进制数。

  这一过程是递推计算的,设H(C,k)为前k个字符构成的字符串的哈希值,则:(以下均不考虑取模的情况)

  H(C,k+1)=H(C,k)× b + ck+1

  字符串哈希,通常题目要求的是判断主串的一段字符串与另一个匹配串是否匹配,即判断字符C=c1c2……cm从位置k+1开始的长度为n的子串C'=ck+1ck+2……ck+n的哈希值与另一匹配串S=s1s2……sn的哈希值是否相等,则:

  H(C')=H(C,k+n) - H(C,k) × bn

  于是我们只要预求得b,就能在O(1)时间内得到任意字符串的字符串的子串哈希值,从而完成字符串匹配,那么上述字符串匹配问题的算法复杂度就为O(n+m)。

  在实现算法时,可以利用32位或64位无符号整数计算hash值(如:unsigned long long),并取h=232或h=264,通过自然溢出省去取模运算。

                                                                              ——By《一本通》

那么本题就可以用上述方式AC了(书上代码有bug,需自己改动)

 AC代码如下:

#include<cstring>
#include<cstdio>
using namespace std;
#define ULL unsigned long long
#define K 103
int N;
char s1[], s2[];
ULL f[],l1,l2,t;
ULL a[];
ULL get(int x,int y)
{
return f[y]-f[x-]*a[y-x+];
}
int main()
{
//freopen("字符串匹配(求s1在s2中出现的次数).in","r",stdin);
//freopen("字符串匹配(求s1在s2中出现的次数).out","w",stdout);
scanf("%d",&N);
a[]=;
for(int i=;i<=;++i)//预处理出a^n
a[i]=a[i-]*K;
for(int i=;i<=N;++i)
{
int ans();t=;
scanf("%s%s",s2+,s1+);
l1=strlen(s1+);l2=strlen(s2+);
for(int j=;j<=l1;++j)
f[j]=f[j-]*K+(s1[j]-'A');//计算主串的滚动哈希值
for(int j=;j<=l2;++j)
t=t*K+(s2[j]-'A');//计算匹配串的哈希值
for (int j=;j+l2-<=l1;++j)
{
if(get(j,j+l2-)==t)//枚举起点为i,长度为n的子串,判断与匹配串是否匹配
ans++;
}
printf("%d\n",ans);//输出
}
return ;
}

Hash——字符串匹配(求s1在s2中出现的次数)的更多相关文章

  1. 选拔赛 hash 字符串匹配 哈希算法(白书p374)

    hash   Description dr所在国度的有个奇怪的规定:他们的字母不是a~z,而是用1~1000表示. 利用这个奇怪的规定,dr想出了一个好玩的游戏:首先给出n个字符串(当然每个字符用1~ ...

  2. JAVA常见算法题(三十三)---求子串在字符串中出现的次数

    计算某字符串中子串出现的次数. public static void main(String[] args) { String s1 = "adcdcjncdfbcdcdcd"; ...

  3. hdoj 4552 怪盗基德的挑战书【求前缀在字符串中出现的次数之和】

    怪盗基德的挑战书 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Su ...

  4. 字符串匹配--Regex

    利用Regix实现字符串匹配 Eg:匹配嵌入到[]中的字符 string pattern = Regex.Escape("[") + "(.*?)]"; str ...

  5. C语言:求n(n<10000)以内的所有四叶玫瑰数。-将字符串s1和s2合并形成新的字符串s3,先取出1的第一个字符放入3,再取出2的第一个字符放入3,

    //函数fun功能:求n(n<10000)以内的所有四叶玫瑰数并逐个存放到result所指数组中,个数作为返回值.如果一个4位整数等于其各个位数字的4次方之和,则称该数为函数返回值. #incl ...

  6. 浅谈Hash在多个字符串匹配类型问题中的应用

    在生活中们有时会遇到一些有关字符串匹配的问题. 这时打暴力往往显得很愚蠢,效率低下. 所以就需要一些算法和数据结构来提高效率. Hash Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把 ...

  7. squeeze(s1,s2),将字符串s1中任何与字符串s2中匹配的字符都删除

    void squeeze(char a[],char b[]) { //要实现把s2的任意字符如果出现的话就在s1中删除 //1.首先判断s1[j]==s2[i]&&s1[j]=='\ ...

  8. TCPL学习笔记:编写expand(s1, s2),将字符串s1中类似于a-z一类的速记符号在s2中扩充完整。可以处理大小写及字符,以及a-b-c, a-z0-9以及-a-z等多种情况。

    话不多说,看代码: #include <stdio.h> #include <stdlib.h> int main(void) { ] = "a-z0-9hahah- ...

  9. 【模板】字符串匹配的三种做法(Hash、KMP、STL)

    题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 输入输出格式 输入格式: 第一行为一个字符串,即为s1 第二行为一个字符串,即为s2 输出格式: 1行 ...

随机推荐

  1. 解决keepalived脑裂问题

    检测思路:正常情况下keepalived的VIP地址是在主节点上的,如果在从节点发现了VIP,就设置报警信息 脚本如下: #!/bin/bash # 检查脑裂的脚本,在备节点上进行部署 LB01_VI ...

  2. gradle 定义打包后的项目名

    war { archiveName 'ROOT.war' } 或 task makeWar(type:org.gradle.api.tasks.bundling.War) { //指定生成的jar名 ...

  3. Eclipse Luna在线安装Maven时报错:Java heap space

    问题描述: 在线安装Maven插件时发生了:Java heap space 问题截图:

  4. 注册页面的JSON响应方式详细分析(与前端页面交互方式之一)

    控制器层 需求分析: 访问路径:`/user/reg.do` //自己根据功能需求设定的请求参数:`username=xx&password=xx&&phone=xx& ...

  5. pyqt5 点开小窗口

    # -*- coding: utf-8 -*- import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * class Fi ...

  6. Scrapy小技巧-MySQL存储, MYSQL拼接

    这两天上班接手,别人留下来的爬虫发现一个很好玩的 SQL脚本拼接. 只要你的Scrapy Field字段名字和 数据库字段的名字 一样.那么恭喜你你就可以拷贝这段SQL拼接脚本.进行MySQL入库处理 ...

  7. Docker学习笔记之Docker 的简历

    0x00 概述 在了解虚拟化和容器技术后,我们就更容易理解 Docker 的相关知识了.在这一小节中,我将介绍关于 Docker 的出现和发展,Docker 背后的技术.同时,我们将阐述 Docker ...

  8. DOM EventListener

    向元素添加事件句柄的语法:element.addEventListener(event, function, useCapture); 第一个参数是事件的类型,如click或者mousedown,注意 ...

  9. wait与sleep的区别

    1.这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类. sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用了b的sleep方法,实际上还 ...

  10. ORACLE 12c 配置PL/SQL 并登录

    一.安装12c简易客户端 下载:instantclient-basic-nt-12.2.0.1.0.zip 下载并解压到本地目录D:\app\instantclient_12_2 创建tns连接文件: ...