uva10887
来源:互联网 发布:linux wpa supplicant 编辑:程序博客网 时间:2024/06/05 01:15
hash实在无爱。。。。。看的云里雾里的。。。。。。。
思路:
1. 计算出字符串的三个哈希值(一个用来确定位置,另外两个用来校验)
2. 察看哈希表中的这个位置
3. 哈希表中这个位置为空吗?如果为空,则肯定该字符串不存在,返回
4. 如果存在,则检查其他两个哈希值是否也匹配,如果匹配,则表示找到了该字符串,返回
5. 移到下一个位置,如果已经越界,则表示没有找到,返回
6. 看看是不是又回到了原来的位置,如果是,则返回没找到
7. 回到3
2. 察看哈希表中的这个位置
3. 哈希表中这个位置为空吗?如果为空,则肯定该字符串不存在,返回
4. 如果存在,则检查其他两个哈希值是否也匹配,如果匹配,则表示找到了该字符串,返回
5. 移到下一个位置,如果已经越界,则表示没有找到,返回
6. 看看是不是又回到了原来的位置,如果是,则返回没找到
7. 回到3
三个hash值重复的可能性大约就很小很小了吧。。。。
#include <iostream>#include <string>#include <cstdio>#include <cstring>using namespace std;int cryptTable[0x500];void prepareCryptTable(){ unsigned long seed = 0x00100001, index1 = 0, index2 = 0, i; for( index1 = 0; index1 < 0x100; index1++ ) { for( index2 = index1, i = 0; i < 5; i++, index2 += 0x100 ) { unsigned long temp1, temp2; seed = (seed * 125 + 3) % 0x2AAAAB; temp1 = (seed & 0xFFFF) << 0x10; seed = (seed * 125 + 3) % 0x2AAAAB; temp2 = (seed & 0xFFFF); cryptTable[index2] = ( temp1 | temp2 ); } }}unsigned long HashString( const char *lpszFileName, unsigned long dwHashType ){ unsigned char *key = (unsigned char *)lpszFileName; unsigned long seed1 = 0x7FED7FED; unsigned long seed2 = 0xEEEEEEEE; int ch; while( *key != 0 ) { ch = toupper(*key++); seed1 = cryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2); seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3; } return seed1;}bool vis [10000000];int num2 [10000000];int num3 [10000000];int main(){ prepareCryptTable(); int T,t=0; cin>>T; while(T--) { memset(vis,false,sizeof(vis)); memset(num2,0,sizeof(num2)); memset(num3,0,sizeof(num3)); int num_a,num_b; cin>>num_a>>num_b; getchar(); string a[num_a],b[num_b]; for(int i=0;i<num_a;i++) getline(cin,a[i]); for(int j=0;j<num_b;j++) getline(cin,b[j]); int sum=0; for(int i=0;i<num_a;i++) for(int j=0;j<num_b;j++) { string s=a[i]+b[j]; unsigned long n1=HashString(s.c_str(),0)%10000000; unsigned long n2=HashString(s.c_str(),1)%10000000; unsigned long n3=HashString(s.c_str(),2)%10000000; if(vis[n1]) { if(n2==num2[n1]&&n3==num3[n1]) continue; else { bool exist=false; int k; for(k=n1+1;k<10000000&&vis[k]&&k!=n1;k++) if(n2==num2[k]&&n3==num3[k]) { exist=true; break; } if(exist) continue; else vis[k]=true,num2[k]=n2,num3[k]=n3,sum+=1; } } else vis[n1]=true,num2[n1]=n2,num3[n1]=n3,sum+=1; } cout << "Case " << ++t << ": " << sum << endl; }}
0 0
- uva10887
- UVA10887
- UVa10887 - Concatenation of Languages
- UVA10887--Trie--哈希
- Trie|STL|hash+uva10887
- uva10887 Concatenation of Languages
- [哈希]Concatenation of Languages uva10887
- 关于opencv图像类型的转换
- 搭建个人wiki站点
- Conscription 最小生成树
- HDU解题报告——1016
- POJ-3349 Snowflake Snow Snowflakes
- uva10887
- java中基本数据类型与对象引用类型的默认初始化值学习
- 会话管理
- using System.Drawing;是否缺少程序集引用?的解决办法
- 虚拟机Hyper-V, VMware, VPC使用及比较
- MVC架构在iOS中
- ZOJ-2414
- 数据的插入与删除
- [Bzoj3223]Tyvj 1729 文艺平衡树