字符串很神奇,因为它在计算机中应用很广泛,就每一个程序都需要用到字符串,所以学好字符串是非常重要的。

接下来就介绍两个字符串的基本操作

1:字符串hash  一种可以查找几个字符串有几个不同的字符串。

其精髓就是把一堆字符串都转换成几个数字的和的形式。

要领就是把字符串每一位字母的阿斯克码不会拼啊都乘上一个比较神奇的数,再%上一个神奇的数,比如你的生日啊,qq号什么的,尽量是质数,太大了也不行,会爆炸的。

van成之后,再把这个值都存进一个数组中,最后查的时候直接用就是了。

为什么这样就可以实现查找不同的字符串呢。

因为这相当于给每个字符串一个编号,且这个编号就是每个字符串的每个位数乘上一个上文提到的很神奇的数,来保证不会出现编号重了的现象。

如果这样你还是觉得不保险,你还可以双hash,这样成功率会大大增加,但还是不排除出现错误,这种情况又叫哈希冲突。

好了,解释完毕上代码

  1. #include<iostream>
  2. #include<string>
  3. #include<cstdio>
  4. #include<map>
  5. using namespace std;
  6. const int mod=;
  7. int n,hash[],total;
  8. map<int,int>m;
  9. string s;
  10. int find_hash(string x)
  11. {
  12. int ans=;
  13. for(int i=;i<x.size();i++)
  14. {
  15. ans=(ans*%mod+((int)x[i]))%mod;
  16. }
  17. return ans;
  18. }
  19. int main()
  20. {
  21. scanf("%d",&n);
  22. for(int i=;i<=n;i++)
  23. {
  24. cin>>s;
  25. hash[i]=find_hash(s);
  26. }
  27. for(int i=;i<=n;i++)
  28. {
  29. if(m[hash[i]])continue;
  30. m[hash[i]]=;
  31. total++;
  32. }
  33. printf("%d",total);
  34. }

2:KMP字符串匹配算法

既然知道了如何查找不同的算法,那么接下来就要实现KMP字符串匹配了,

KMP字符串匹配就是指 给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置。

当然就需要引进一个数组叫next数组也叫子串的前缀数组。

next数组指什么呢,指这个串的最长的前缀与后缀相等的长度。

比如说

下标:01234

值:   ABABA

的next数组是

下标:01234

值:   00123

因为字符串的第一位的下标默认为0.

所以我们也把下标弄成和字符串一样的格式.

有了这个数组有什么用呢?

我们想如果这个字符串失配了,那这个位置的子串字符一定不与父串字符相等,但是之前的所有字符都相等。

所以我们就匹配到之前的相等的字符处

比如:

父串:ABABCABABA

子串:   ABABA

当匹配到s1[4] 和 s2[4]时(以字符串的下标)s1[4]!=s2[4]

我们就要回到之前的位置,那之前的位置在哪呢,你可能会想应该在next[4]这里吧,但是你看如果在next[4]这里,那么s2[现在失配的位置]=s2[next[4]]那我们这样做有什么用呢照样失配,

所以我们应该回到next[i-1]的位置,或者让next的下标集体+1,这就是有些KMP的代码中有现在失配的位置=next[现在失配的位置]。

还有一点,第0位的next数组是算不出来的,所以我们找next数组的函数中的循环要从1开始。

但是如果父串的这个位置与任何的前缀都不行,那就只能放弃这个位置了,让父串的位置+1.

代码:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. using namespace std;
  6. char a[1000010],b[1000010];
  7. int n,m,j,next[1000010];
  8. void pre()
  9. {
  10. next[1]=0;
  11. j=0;
  12. for(int i=1;i<m;i++)
  13. {
  14. while(j>0&&b[i]!=b[j])
  15. j=next[j-1];
  16. if(b[i]==b[j])
  17. j++;
  18. next[i]=j;//这一步在上一步的原因是,nex[i]是i失配后要跳到的不等于s[i-1]和s[i]的一个字符的位置,所以j要加1之后b[nex[i]]就不等于b[i]了
  19. }
  20. }
  21. void kmp()
  22. {
  23. for(int i=0;i<n;i++)
  24. {
  25. while(j>0&&a[i]!=b[j])
  26. j=next[j-1];
  27. if(a[i]==b[j])
  28. j++;
  29. if(j==m)
  30. {
  31. cout<<i+1-(m-1)<<endl;//j要返回到上次的位置,这样可以使i重复利用,因此不能使j=0;
  32. }
  33. }
  34. }
  35. int main()
  36. {
  37. cin>>a;
  38. cin>>b;
  39. n=strlen(a);
  40. m=strlen(b);
  41. pre();
  42. j=0;
  43. kmp();
  44. for(int i=0;i<m;i++)
  45. cout<<next[i]<<" ";
  46. }

  

字符串哈希及KMP的更多相关文章

  1. UVA - 11475 Extend to Palindrome —— 字符串哈希 or KMP or 后缀数组

    题目链接:https://vjudge.net/problem/UVA-11475 题意: 给出一个字符串,问在该字符串后面至少添加几个字符,使得其成为回文串,并输出该回文串. 题解: 实际上是求该字 ...

  2. 【CodeForces】961 F. k-substrings 字符串哈希+二分

    [题目]F. k-substrings [题意]给定长度为n的串S,对于S的每个k-子串$s_ks_{k+1}...s_{n-k+1},k\in[1,\left \lceil \frac{n}{2} ...

  3. UVA - 11019 Matrix Matcher (二维字符串哈希)

    给你一个n*m的矩阵,和一个x*y的模式矩阵,求模式矩阵在原矩阵中的出现次数. 看上去是kmp在二维情况下的版本,但单纯的kmp已经无法做到了,所以考虑字符串哈希. 类比一维情况下的哈希算法,利用容斥 ...

  4. Luogu P4503 [CTSC2014]企鹅QQ(字符串哈希)

    P4503 [CTSC2014]企鹅QQ 题面 题目背景 \(PenguinQQ\) 是中国最大.最具影响力的 \(SNS(Social Networking Services)\) 网站,以实名制为 ...

  5. Petr#(字符串哈希)

    CF113B Petr# 大概就是字符串匹配加一个字符串哈希判重.懒得打kmp,就用字符串哈希匹配了. 字符串哈希大概就是把字符串转成一个p进制的数,每一段字符串都有一个对应的哈希值.p尽量取质数,这 ...

  6. HDU 1880 魔咒词典(字符串哈希)

    题目链接 Problem Description 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一 ...

  7. 洛谷P3370 【模板】字符串哈希

    P3370 [模板]字符串哈希 143通过 483提交 题目提供者HansBug 标签 难度普及- 提交  讨论  题解 最新讨论 看不出来,这题哪里是哈希了- 题目描述 如题,给定N个字符串(第i个 ...

  8. HDU2594 Simpsons’ Hidden Talents 字符串哈希

    最近在学习字符串的知识,在字符串上我跟大一的时候是没什么区别的,所以恶补了很多基础的算法,今天补了一下字符串哈希,看的是大一新生的课件学的,以前觉得字符串哈希无非就是跟普通的哈希没什么区别,倒也没觉得 ...

  9. LA 6047 Perfect Matching 字符串哈希

    一开始我用的Trie+计数,但是不是计多了就是计少了,后来暴力暴过去的…… 看了别人的代码知道是字符串哈希,但是仍有几个地方不理解: 1.26^500溢出问题 2.没考虑哈希碰撞? 跪求指点! #in ...

随机推荐

  1. python之socket模块详解--小白博客

    主要是创建一个服务端,在创建服务端的时候,主要步骤如下:创建socket对象socket——>绑定IP地址和端口bind——>监听listen——>得到请求accept——>接 ...

  2. 利用tushare进行对兴业银行股价的爬取,并使用numpy进行分析

    import sysimport tushare as tsimport numpy as npdata=ts.get_h_data('601066')print(data)#读出兴业银行7列数据da ...

  3. 提取PPT文件中的Vba ProjectStg Compressed Atom。Extract PPT VBA Compress Stream

    http://msdn.microsoft.com/en-us/library/cc313106(v=office.12).aspx  微软文档 PartI ********************* ...

  4. 斐波那契数列yield表示

    def fib(num): n=0 a,b=0,1 while n<num: print(b) yield a,b=b,a+b n=n+1a=fib(30)next(a)next(a)  

  5. python知识点及面试面试大集合

    题目来源:武sir--一个很有意思的人,点击这儿跳转 一.基础篇 为什么学习Python? 通过什么途径学习的Python? Python和Java.PHP.C.C#.C++等其他语言的对比? 简述解 ...

  6. pycharm异常问题之Unable to save settings: Failed to save settings. Please restart PyCharm

    pycharm异常之Unable to save settings: Failed to save settings. Please restart PyCharm 今天一不小心将电脑关了,但是关机之 ...

  7. rest-framework的认证组件

    认证组件 1.登录认证(与组件无关): 首先要在model表内添加用户表和token表: from django.db import models # Create your models here. ...

  8. Zabbix appliance manual

    https://www.zabbix.com/documentation/4.0/manual/appliance If the appliance fails to start up in Hype ...

  9. YOLO.h5 下载

    链接:https://pan.baidu.com/s/1sTxkuaFWXqT4yXLHQ9BgUA 密码:ga0o fhwayd_w1231234asd><321$%

  10. 下拉框、下拉控件之Select2

    一.Select2的功能简介 select2插件给我们带来了更加友好的交互方式,比如查询控件展开后可通过关键字进行检索 例如: Select2也可以选择带查询控件的选择框... Select2也可以选 ...