思路:利用Karp-Rabin算法的思想,对每个子串进行Hash,如果Hash值相等则认为这两个子串是相同的(事实上还需要做进一步检查),Karp-Rabin算法的Hash函数有多种形式,但思想都是把字符串映射成一个数字。本题hash函数是把字串转化为NC进制的数(实际上程序中计算结果已经被转换为10进制,因为NC进制数不同转化为10进制数自然不同,所以不影响判断结果),数组开到了1.6×10^7(我试了一下1.2×10^7也能AC),实际上这也是不严谨的,因为我们不能保证hash之后的数值在这个范围内,比如N=NC=35,程序就有Bug了,但是这题后台数据可能没这么给。在实际运用中是需要取模的,而且即使hash值相等也需要进一步比对。


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
bool hash[16000005];
int is_have[300];
char str[1000005];
int main(){
int n, nc;
/* freopen("in.c", "r", stdin); */
while(~scanf("%d%d", &n, &nc)){
memset(str, 0, sizeof(str));
memset(hash, 0, sizeof(hash));
memset(is_have, 0, sizeof(is_have));
scanf("%s", str);
int len = strlen(str);
int k = 0, ans = 0;
for(int i = 0;i < len;i ++) is_have[str[i]] = 1;
for(int i = 0;i < 256;i ++)
if(is_have[i]) is_have[i] = k++;
for(int i = 0;i <= len - n;i ++){
int key = 0;
for(int j = i;j < i + n;j ++) key = key*nc + is_have[str[j]];
if(!hash[key]) ans ++, hash[key] = 1;
}
printf("%d\n", ans);
}
return 0;
}

下面附上一般情况的实现代码(均来自其他网友):



1. 原文链接:http://www.xefan.com/archives/83853.html

#include <stdio.h>
#include <math.h>
int mod = 0x7fffffff;
const int d = 128;
int rabin_karp(char *T, char *P, int n, int m)
{
if (n < m) return -2;
int h = pow(d, m-1);
int p = 0;
int t = 0;
int i, j;
for (i=0; i<m; i++) {
p = (d*p + P[i]) % mod;
t = (d*t + T[i]) % mod;
}
for (j=0; j<=n-m; j++) {
if (p == t) {
return j;
}
if (j < n-m) {
t = (d*(t - h*T[j]) + T[j+m]) % mod;
}
}
return -1;
} int main(int argc, char *argv[])
{
char t[] = "BBC ABCDAB ABCDABCDABDE";
char p[] = "ABCDABD";
int len1 = sizeof(t) - 1;
int len2 = sizeof(p) - 1;
int index = rabin_karp(t, p, len1, len2);
printf("index: %d\n", index);
return 0;
}

2.原文链接:http://blog.csdn.net/onezeros/article/details/5531354



//Karp-Rabin algorithm,a simple edition
int karp_rabin_search(const char* text,const int text_len,const char* pattern,const int pattern_len)
{
int hash_text=0;
int hash_pattern=0;
int i; //rehash constant:2^(pattern_len-1)
int hash_const=1;
/*for (i=1;i<pattern_len;i++){
hash_const<<=1;
}*/
hash_const<<=pattern_len-1; //preprocessing
//hashing
for (i=0;i<pattern_len;++i){
hash_pattern=(hash_pattern<<1)+pattern[i];
hash_text=(hash_text<<1)+text[i];
} //searching
for (i=0;i<=text_len-pattern_len;++i){
if (hash_pattern==hash_text&&memcmp(text+i,pattern,pattern_len)==0){
return i;
}else{
//rehash
hash_text=((hash_text-text[i]*hash_const)<<1)+text[i+pattern_len];
}
}
return -1;
}

POJ 1200 Crazy Search的更多相关文章

  1. poj 1200 Crazy Search(hash)

    题目链接:http://poj.org/problem?id=1200 思路分析:从数据来看,该题目使用线性时间算法,可见子串的比较是不可能的:使用hash可以在常数时间内查找,可以常数时间内判重, ...

  2. POJ 1200 Crazy Search(字符串简单的hash)

    题目:http://poj.org/problem?id=1200 最近看了一个关于hash的问题,不是很明白,于是乎就找了些关于这方面的题目,这道题是一道简单的hash 字符串题目,就先从他入手吧. ...

  3. POJ – 1200 Crazy Search

    http://poj.org/problem?id=1200 #include<iostream> #include<cstring> using namespace std; ...

  4. POJ 1200 Crazy Search (哈希)

    题目链接 Description Many people like to solve hard puzzles some of which may lead them to madness. One ...

  5. POJ 1200 Crazy Search 【hash】

    <题目链接> 题目大意: 给定n,nc,和一个字符串,该字符串由nc种字符组成,现在要你寻找该字符串中长度为n的子字符串有多少种. 解题分析: 因为要判重,所以讲这些字符串hash一下,将 ...

  6. POJ 1200 Crazy Search【Hash入门】

    RK法:https://www.cnblogs.com/16crow/p/6879988.html #include<cstdio> #include<string> #inc ...

  7. POJ 1200 Crazy Search 字符串的Hash查找

    第一次涉及HASH查找的知识 对于字符串的查找有很多前人开发出来的HASH函数,比较常用的好像是ELF 和 BKDR. 这道题没想到突破点是在于其nc值,告诉你组成字符串的字母种类. 还有用26进制, ...

  8. poj 1200 crasy search

    https://vjudge.net/problem/POJ-1200 题意: 给出一个字符串,给出子串的长度n和给出的字符串中不同字符的个数nc,统计这个字符串一共有多少不同的长度为n的子串. 思路 ...

  9. POJ 1200:Crazy Search(哈希)

    Crazy Search Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 32483   Accepted: 8947 Des ...

随机推荐

  1. LESS语法备忘

    变量 很容易理解: @nice-blue: #5B83AD; @light-blue: @nice-blue + #111; #header { color: @light-blue; } 输出: # ...

  2. mysql中的load命令使用方法

    使用mysql 中的load 命令,可以将txt 文件中的内容加载到数据库表中 使用mysql 中的load 命令,讲txt 文件中的内容加载到数据库表中,例如,创建table,名称是user,一个字 ...

  3. jcom2在win7 X86上操作Excel

    浅谈Java中利用JCOM实现仿Excel编程   在JAVA中使用JCOM和JXL注意要点: (1)在你的lib下要有jdom-1.0.jar,jxl-2.5.5.jar,jcom-2.2.4.ja ...

  4. AppExtention - today

    声明: 本文转自王巍 WWDC 2014 Session笔记 - iOS 通知中心扩展制作入门 本文是我的 WWDC 2014 笔记 中的一篇,涉及的 Session 有 Creating Exten ...

  5. Shell编程练习

    1.使用case语句 2.使用while....do....done语句 3.使用

  6. 将 Photoshop CC 2015.5 英文界面换成中文, 英文与中文界面互换

    注:转载或引用请注明出处 在英文的win server 2012 r2 上安装PS CC 2015.5 时,安装程序自动按成了英文版的PS,那么如何将英文换成中文呢? 网上大多讲的都是将中文换成英文, ...

  7. 解决Linux/aix 下的websphere log4j不生效

    websphere 解决Linux/aix下的log4j不生效 在目录: /IBM/WebSphere/AppServer/profiles/AppSrv01/properties 增加一个文件:可以 ...

  8. IOS ITunesConnect 修改开发商名称

    ItunesConnect→ManagerApps→应用→Contact Us

  9. HDU1395+快速幂

    #include<stdio.h> int fast_pow( int a,int b,int mod ){ ; ){ == ){ res = res*a%mod; } a = a*a%m ...

  10. UVA 10801 Lift Hopping

    算是一道需要动脑筋的最短路问题了,关键在于建图部分,对于n个电梯中每一个都要经过cnt个楼层,a[0],a[1],a[2],a[3],a[4],......a[cnt-1],那么对于任意两个楼层a[j ...