1. 程式人生 > 實用技巧 >洛谷-P3370 【模板】字串雜湊

洛谷-P3370 【模板】字串雜湊

洛谷-P3370 【模板】字串雜湊

原題連結:https://www.luogu.com.cn/problem/P3370


題目描述

如題,給定 \(N\) 個字串(第 \(i\) 個字串長度為 \(M_i\),字串內包含數字、大小寫字母,大小寫敏感),請求出 \(N\) 個字串中共有多少個不同的字串。

#友情提醒:如果真的想好好練習雜湊的話,請自覺,否則請右轉PJ試煉場:)

輸入格式

第一行包含一個整數 \(N\),為字串的個數。

接下來 \(N\) 行每行包含一個字串,為所提供的字串。

輸出格式

輸出包含一行,包含一個整數,為不同的字串個數。

輸入輸出樣例

輸入 #1

5
abc
aaaa
abc
abcc
12345

輸出 #1

4

說明/提示

對於 \(30\%\) 的資料:\(N\leq 10\)\(M_i≈6\)\(Mmax\leq 15\)

對於 \(70\%\) 的資料:\(N\leq 1000\)\(M_i≈100\)\(Mmax\leq 150\)

對於 \(100\%\) 的資料:\(N\leq 10000\)\(M_i≈1000\)\(Mmax\leq 1500\)

樣例說明:

樣例中第一個字串(abc)和第三個字串(abc)是一樣的,所以所提供字串的集合為{aaaa,abc,abcc,12345},故共計4個不同的字串。

Tip: 感興趣的話,你們可以先看一看以下三題:

BZOJ3097:http://www.lydsy.com/JudgeOnline/problem.php?id=3097

BZOJ3098:http://www.lydsy.com/JudgeOnline/problem.php?id=3098

BZOJ3099:http://www.lydsy.com/JudgeOnline/problem.php?id=3099

如果你仔細研究過了(或者至少仔細看過AC人數的話),我想你一定會明白字串雜湊的正確姿勢的_

C++程式碼

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;

ull base=131, mod=212370440130137957ll, prime=233317;

ull hashe(string s) {
    ull ans = 0;
    for (int i=0; i<s.size(); ++i)
        ans = (ans * base + s[i]) % mod + prime;
    return ans;
}

int main() {
    int n, ans = 1;
    cin >> n;
    int h[n];
    string m[n];
    for (int i=0; i<n; ++i)
        cin >> m[i];
    for (int i=0; i<n; ++i)
        h[i] = hashe(m[i]);
    sort(h, h+n);
    for (int i=1; i<n; ++i)
        if (h[i-1] != h[i])
            ++ans;
    cout << ans << endl;
    return 0;
}