hash模板
来源:互联网 发布:大数据的前沿技术培训 编辑:程序博客网 时间:2024/06/01 17:22
一维hash
//求原串中有多少个模式串//Seed[i]是seed的i次幂//hash[j]-hash[i-1] * Seed[len]是区间[i,j]的hash值,len是区间长度typedef long long ll;typedef unsigned long long ull;const int N = 1000000 + 10, M = 10000 + 10, INF = 0x3f3f3f3f;const int seed = 31;//31,131,1313,13131,131313...char pat[M], ori[N];ull Seed[N], hash_ori[N];ull BKDRhash(char *str){ ull h = 0; for(int i = 0; str[i]; i++) h = h * seed + str[i]; return h;}int main(){ Seed[0] = 1; for(int i = 1; i < N; i++) Seed[i] = Seed[i-1] * seed; int t; scanf("%d", &t); while(t--) { scanf("%s%s", pat+1, ori+1); ull hash_pat = BKDRhash(pat+1); int len_pat = strlen(pat+1); hash_ori[0] = 0; int ans = 0; for(int i = 1; ori[i]; i++) { hash_ori[i] = hash_ori[i-1] * seed + ori[i];//也是BKDRhash int j = i - len_pat + 1; if(j >= 1) {hash_ori[i] - hash_ori[j-1] * Seed[len_pat]是区间[j,i]的hash值,len_pat是区间长度 if(hash_ori[i] - hash_ori[j-1]*Seed[len_pat] == hash_pat) ans++; } } printf("%d\n", ans); } return 0;}
二维hash:
//给定一个n*m的字符矩阵,找到两个内容一样的正方形,输出这个正方形的最大边长//二维hash,先对每一行hash一次,然后在此基础上对每一列hash一次typedef unsigned long long ull;const int N = 500 + 10, INF = 0x3f3f3f3f;const int seed = 131, Seed = 1789;char ori[N][N];ull hash1[N][N], seed_pow[N];ull hash2[N][N], Seed_pow[N];ull a[N*N];int n, m;bool check(int k){ int tot = 0; for(int i = k; i <= n; i++) { for(int j = k; j <= m; j++) { ull tmp = hash2[i][j] - hash2[i-k][j] * Seed_pow[k] - hash2[i][j-k] * seed_pow[k] + hash2[i-k][j-k] * Seed_pow[k] * seed_pow[k]; //ull tmp = hash2[i][j] - hash2[i-k][j] * Seed_pow[k] - (hash2[i][j-k] - hash2[i-k][j-k] * Seed_pow[k]) * seed_pow[k]; a[++tot] = tmp; } } sort(a + 1, a + 1 + tot); for(int i = 1; i <= tot-1; i++) if(a[i] == a[i+1]) return true; return false;}int main(){ seed_pow[0] = Seed_pow[0] = 1; for(int i = 1; i < N; i++) { seed_pow[i] = seed_pow[i-1] * seed; Seed_pow[i] = Seed_pow[i-1] * Seed; } scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) scanf(" %s", ori[i] + 1); for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) hash1[i][j] = hash1[i][j-1] * seed + ori[i][j]; for(int i = 1; i <= m; i++) for(int j = 1; j <= n; j++) hash2[j][i] = hash2[j-1][i] * Seed + hash1[j][i]; int ans = 0; int l = 0, r = min(n, m); while(l <= r) { int mid = (l + r) >> 1; if(check(mid)) ans = mid, l = mid + 1; else r = mid - 1; } printf("%d\n", ans); return 0;}
ELFhash:
给出一些数字,求出这些数字中出现次数,输出最多的那个次数。其中数字不超过30位#include <bits/stdc++.h>using namespace std;typedef unsigned int ui;const int N = 7003, MOD = 7003;int Hash[N], num[N];int res;int ELFhash(char *str)//思想就是一直杂糅,使字符之间互相影响{ ui h = 0, g; while(*str) { h = (h<<4) + *str++; //h左移4位,当前字符占8位,加到h中进行杂糅 if((g = h & 0xf0000000) != 0) //取h最左四位的值,若均为0,则括号中执行与否没区别,故不执行 { h ^= g>>24; //用h的最左四位的值对h的右起5~8进行杂糅 h &= ~g;//清空h的最左四位 } } return h; //因为每次都清空了最左四位,最后结果最多也就是28位二进制整数,不会超int}void hash_table(char *str){ int k = ELFhash(str); int t = k % MOD; while(Hash[t] != k && Hash[t] != -1) t = (t + 1) % MOD;//开放地址法处理hash if(Hash[t] == -1) num[t] = 1, Hash[t] = k; else res = max(res, ++num[t]);}int main(){ int n; char str[100]; while(~ scanf("%d", &n)) { getchar(); res = 1; memset(Hash, -1, sizeof Hash); for(int i = 1; i <= n; i++) { scanf("%s", str); int j = 0; while(str[j] == '0') j++; hash_table(str + j); } printf("%d\n", res); } return 0;}
阅读全文
0 0
- hash 模板
- hash 模板
- hash模板
- hash小模板
- 字符串hash 函数模板
- hash表模板
- 字符串HASH模板
- hash + bsgs模板
- 字符串HASH模板
- 字符串HASH模板
- 【模板】字符串hash
- Hash 匹配字符串模板
- 字符串hash模板
- 洛谷 3370 hash模板
- [模板]字符串hash
- 字符串HASH 学习总结 && 模板
- HASH表的模板实现
- CTSC2014 企鹅QQ Hash模板
- 【POCO】POCO学习总结(三)——交叉编译
- jsp页面response重定向
- spring boot -- mysql断连
- chrome 下一段代码的理解
- gradle插件版本和gradle版本对应关系
- hash模板
- 快速接入环信
- codeforces 330B Road Construction
- python中的字典
- svn 日常
- dwg转dxf有什么好的操作方法
- centos访问Windows共享文件两种方式:
- Qualcomm Simlock——解锁流程
- Android属性动画个人小结