洛谷刷题C++语言 | P3370 字符串哈希


学习C++从娃娃抓起!记录下洛谷C++学习和备考过程中的题目,记录每一个瞬间。

附上汇总贴:洛谷刷题C++语言 | 汇总


【题目描述】

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

【输入】

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

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

【输出】

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

【输入样例】

5
abc
aaaa
abc
abcc
12345

【输出样例】

4

【代码详解】

在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
int n, ans;
string s;
ull a[10005];
ull myhash(string s)
{
    ull code = 0, x = 131, y = 140814840257324663;  // y为小于a/131-131的最大质数
    for (int i=0; i<s.size(); i++)
        code = (code*x + (ull)s[i]) % y;
    return code;
}
int main()
{
    cin >> n;
    for (int i=1; i<=n; i++) {
        cin >> s;
        a[i] = myhash(s);
    }
    sort(a+1, a+n+1);
    ans = unique(a+1, a+n+1)-(a+1);
    cout << ans;
    return 0;
}

【运行结果】

5
abc
aaaa
abc
abcc
12345
4

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
KMP算法是一种用于字符串匹配的算法,其中最关键的部分是构建next数组,用于指导模式串的匹配过程。在构建next数组的时候,可以使用字符串哈希的思想,将模式串的前缀和后缀进行哈希处理,然后进行比较,从而得出next数组。 具体实现如下: ```c #include <stdio.h> #include <string.h> #define ll long long const int N = 1e6 + 5, P = 131; char s[N], t[N]; int n, m; ll h[N], p[N], ht[N], pt[N], nxt[N]; void init() { p[0] = pt[0] = 1; for(int i = 1; i <= n; ++i) { h[i] = h[i - 1] * P + s[i]; p[i] = p[i - 1] * P; } for(int i = 1; i <= m; ++i) { ht[i] = ht[i - 1] * P + t[i]; pt[i] = pt[i - 1] * P; } } int check(int len) { for(int i = 1; i + len - 1 <= m; ++i) { ll h1 = ht[i + len - 1] - ht[i - 1] * pt[len]; ll h2 = h[len]; if(h1 == h2) return i; } return 0; } void getnxt() { int j = 0; nxt[1] = 0; for(int i = 2; i <= m; ++i) { while(j && t[j + 1] != t[i]) j = nxt[j]; if(t[j + 1] == t[i]) ++j; nxt[i] = j; } } int main() { scanf("%s%s", s + 1, t + 1); n = strlen(s + 1), m = strlen(t + 1); init(); getnxt(); int j = 0; for(int i = 1; i <= n; ++i) { while(j && t[j + 1] != s[i]) j = nxt[j]; if(t[j + 1] == s[i]) ++j; if(j == m) { printf("%d\n", i - m + 1); j = nxt[j]; } } return 0; } ``` 其中,h[i]表示s的前i个字符的哈希值,ht[i]表示t的前i个字符的哈希值。p[i]和pt[i]分别表示P的i次方。check函数用于检查长度为len的模式串是否在t中出现过,并返回第一次出现的位置。getnxt函数用于计算next数组。在主函数中,使用KMP算法进行匹配,当j等于m时,说明匹配成功,输出匹配的起始位置,并更新j为nxt[j],继续匹配。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值