上午 学kmp,做题没做出来
下午 学长讲课 做kmp题
晚上 哈希
题目描述
给出两个字符串 s_1s1 和 s_2s2,若 s_1s1 的区间 [l, r][l,r] 子串与 s_2s2 完全相同,则称 s_2s2 在 s_1s1 中出现了,其出现位置为 ll。
现在请你求出 s_2s2 在 s_1s1 中所有出现的位置。定义一个字符串 ss 的 border 为 ss 的一个非 ss 本身的子串 tt,满足 tt 既是 ss 的前缀,又是 ss 的后缀。
对于 s_2s2,你还需要求出对于其每个前缀 s's′ 的最长 border t't′ 的长度。输入格式
第一行为一个字符串,即为 s_1s1。
第二行为一个字符串,即为 s_2s2。输出格式
首先输出若干行,每行一个整数,按从小到大的顺序输出 s_2s2 在 s_1s1 中出现的位置。
最后一行输出 |s_2|∣s2∣ 个整数,第 ii 个整数表示 s_2s2 的长度为 ii 的前缀的最长 border 长度。输入输出样例
输入 #1复制
ABABABC ABA输出 #1复制
1 3 0 0 1
kmp模板
#include<stdio.h>
#include<string.h>
char s1[1000000],s2[1000000];
int next[1000000];
void get_next(char s2[],int next[],int n)
{
n = strlen(s2);
next[0] = -1;
int i = 0;
int j = -1;
while(i <= n){
if(j == -1 || s2[i] == s2[j]){
i++;
j++;
next[i] = j;
}
else{
j = next[j];
}
}
}
void kmp(char s1[],char s2[],int next[])
{
int m = strlen(s1);
int n = strlen(s2);
int i = 0,j = 0;
get_next(s2,next,n);
while(i < m){
// printf("%d %d\n",i,j);
if(j >= n-1 && s1[i] == s2[j]){
printf("%d\n",i-j+1);
j = next[j];
}
if(s1[i] == s2[j]){
i++;
j++;
}
else{
j = next[j];
if(j == -1){
i++;
j++;
}
}
}
for(int q = 1;q < n;q++){
printf("%d ",next[q]);
}
printf("%d\n",next[n]);
}
int main()
{
scanf("%s%s",s1,s2);
kmp(s1,s2,next);
return 0;
}
题目描述
如题,给定 NN 个字符串(第 ii 个字符串长度为 M_iMi,字符串内包含数字、大小写字母,大小写敏感),请求出 NN 个字符串中共有多少个不同的字符串。
友情提醒:如果真的想好好练习哈希的话,请自觉,否则请右转PJ试炼场:)
输入格式
第一行包含一个整数 NN,为字符串的个数。
接下来 NN 行每行包含一个字符串,为所提供的字符串。
输出格式
输出包含一行,包含一个整数,为不同的字符串个数。
输入输出样例
输入 #1复制
5 abc aaaa abc abcc 12345输出 #1复制
4说明/提示
对于 30\%30% 的数据:N\leq 10N≤10,M_i≈6Mi≈6,Mmax\leq 15Mmax≤15。
对于 70\%70% 的数据:N\leq 1000N≤1000,M_i≈100Mi≈100,Mmax\leq 150Mmax≤150。
对于 100\%100% 的数据:N\leq 10000N≤10000,M_i≈1000Mi≈1000,Mmax\leq 1500Mmax≤1500。
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define base 131//一般冲突最小
typedef unsigned long long ull;
ull mod = pow(2,64),b[10001];
char a[10000];
ull Hash(char a[])//对应的哈希值
{
ull sum = 0;
int n = strlen(a);
for(int i = 0;i < n;i++){
sum = (sum * base + (ull)a[i])%mod;
}
return sum;
}
int main()
{
int N;
scanf("%d",&N);
for(int i = 0;i < N;i++){
scanf("%s",a);
b[i] = Hash(a);
}
int s = 0;
sort(b,b+N);//排序
for(int i = 0;i < N;i++){
if(b[i] != b[i+1]) s++;//不一样的就加1
}
printf("%d\n",s);
}
老是想不通,明天继续学吧