【題解】字符串匹配
阿新 • • 發佈:2019-01-19
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) { returnx.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; }
【題解】字符串匹配