P3370 【模板】字符串哈希

题目描述

如题,给定 N 个字符串(第 i 个字符串长度为 Mi​,字符串内包含数字、大小写字母,大小写敏感),请求出 N 个字符串中共有多少个不同的字符串。

输入格式

第一行包含一个整数 N,为字符串的个数。

接下来 N 行每行包含一个字符串,为所提供的字符串。

输出格式

输出包含一行,包含一个整数,为不同的字符串个数。

输入输出样例

5
abc
aaaa
abc
abcc
12345
4

对于这道题的总结如下:

首先字符串哈希得明白它就是把不同的字符串映射成不同的整数,然后如下:

1.把字符串映射成一个p进制数字,对于一个长度为n的字符串s,我们可以这样定义它的hash函数

h(s)=\sum s[i]*p^{n-i}(mod M) (1<=i<=n),你也可以定义自己的hash函数。

2.但是如果碰到两字符串不一样,但hash值却一样,怎么办呢?

3.所以我们要设置p和M的值,保证p与M互质

所以p通常取131或13331

M我们就定义成unsigned 就行,刚好省去自己去模。因为无符号整形超过会自动溢出,等价于取模。

下面是我的ac代码:

#include<bits/stdc++.h>
using namespace std;
using ULL = unsigned long long;
int n;
const int N = 1e4 + 10;
const int p = 131;
ULL h[N], ans[N];
char ch[N];
ULL init(char* s, int len) {
    h[0] = 0;
    for (int i = 1; i <= len; i++) {
        h[i] = h[i - 1] * p+s[i];
    }
    return h[len];
}
int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        scanf("%s", ch + 1);
        int len = strlen(ch + 1);
        ans[i] = init(ch, len);
    }
    sort(ans + 1, ans + 1 + n);
    int cnt = 0;
    for (int i = 1; i <= n; i++) {
        if (ans[i] != ans[i - 1])cnt++;
    }
    cout << cnt << endl;
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值