1. 程式人生 > >【題解】字符串匹配

【題解】字符串匹配

fin can pre pri 長度 click name ios char

題目描述

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

輸入輸出格式

輸入格式

  第一行包含一個整數N,為字符串的個數。

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

輸出格式

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

輸入輸出樣例

輸入樣例

5

abc

aaaa

abc

abcc

12345

輸出樣例

4

說明

數據規模:

  對於30%的數據:N<=10,Mi≈6,Mmax<=15;

  對於70%的數據:N<=1000,Mi≈100,Mmax<=150

  對於100%的數據:N<=10000,Mi≈1000,Mmax<=1500

樣例說明:

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

題解

  字符串匹配,明顯就是字符串hash的裸題。

  最初本來是想用map來裝hash值來判斷是否有重復,但實際上不同那麽麻煩,只需要按照hash值排序一下,然後直接遍歷一遍序列就行了。

技術分享圖片
#include <iostream>
#include 
<algorithm> #include <cstring> #include <cstdio> #define MAX_N 10000 #define MAX_M 1500 using namespace std; int n; struct String { char str[MAX_M | 1]; int len; unsigned long long hash; friend bool operator < (String x, String y) { return
x.hash < y.hash; } }a[MAX_N | 1]; inline int Insert(char s[], int len) { unsigned long long res = 0; for(register int i = 0; i < len; ++i) { if(s[i] >= 0 && s[i] <= 9) { res = res * 62 + s[i] - 0; } else if(s[i] >= A && s[i] <= z) { res = res * 62 + s[i] - A + 10; } else { res = res * 62 + s[i] - a + 36; } } return res; } int main() { scanf("%d", &n); for(register int i = 1; i <= n; ++i) { scanf("%s", a[i].str); a[i].len = strlen(a[i].str); a[i].hash = Insert(a[i].str, a[i].len); } sort(a + 1, a + n + 1); int ans = 1; for(register int i = 1; i < n; ++i) { if(a[i].hash ^ a[i + 1].hash) ++ans; } printf("%d", ans); return 0; }
參考程序

【題解】字符串匹配