题意
给定一个由NC个字母组成的字符串,求长度为N的不同子串的个数
思路:
由于只有NC个字母,可以将字母编号,0 ~ NC - 1,转换成数字,就可以将字符串表示成NC进制的数字,这样所有字串代表的数字都是唯一的,转换成10进制的数也是唯一的!
就像10的二进制表示只有1010
例如
3 4 daababac
d = 3
a = 0
b = 1
c = 2
daa = 3 * 4 ^ 2 + 0 * 4 ^ 1 + 0 * 4 ^ 0 = 48
//vs1.0 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 16000000char str[MAX]; bool hash[MAX]; int ancii[128];int main() {int N, NC;while (scanf("%d%d%s", &N, &NC, str) != EOF) {memset(hash, true, sizeof(hash));memset(ancii, 0, sizeof(ancii));int cnt = 0;for (char *s=str; *s; ++s) {if (!ancii[*s]) {ancii[*s] = ++cnt;if (NC == cnt) break;}}int sum;int ans = 0;int len = strlen(str) - N + 1;for (int i=0; i<len; ++i) {sum = 0;for (int j=0; j<N; ++j) sum = sum * NC + (ancii[str[i+j]] - 1);if (hash[sum]) {++ans;hash[sum] = false;}}printf ("%d\n", ans);}return 0; }//vs2.0 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 16000000char str[MAX]; bool hash[MAX]; int ancii[128];int main() {int N, NC;while (scanf("%d%d%s", &N, &NC, str) != EOF) {memset(hash, true, sizeof(hash));memset(ancii, 0, sizeof(ancii));int cnt = 0;for (char *s=str; *s; ++s) {if (!ancii[*s]) {ancii[*s] = ++cnt;if (NC == cnt) break;}}int sum = 0;int tmp = 1;for (int i=0; i<N; ++i) {tmp *= NC;sum = sum * NC + ancii[str[i]] - 1; }tmp /= NC;hash[sum] = false;int ans = 1;int len = strlen(str);for (int i=N; i<len; ++i) {sum = (sum - tmp * (ancii[str[i-N]]-1)) * NC + ancii[str[i]] - 1;if (hash[sum]) {++ans;hash[sum] = false;}}printf ("%d\n", ans);}return 0; }