初学哈希表
哈希表(也叫散列表 Hash Table)的思路是根据关键码值直接访问。任何一种数据结构都有它的优势,哈希表提供这么一种其他数据结构并不擅长的操作:在理想情况下,能用常量时间查找到指定值的数据。
题意:有n片雪花,问是否有两片完全相同呢? 雪花都是六棱的,如果六棱的长度对应完全相等,则认为两片雪花相同。
思路:如果两两比较的话,就是n^2算法,肯定要超时的,如果用hash的话,就可以将雪花分类,在同类里再两两比较,由于每一类的规模比较小,如果hash函数写的好的话,就可以很大程度上降低复杂度,这里我用的是六棱之和相等为一类(其实就是同义词),对应同一个散列地址,用的是开散列法。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1
#include
<
stdio.h
>
2 #include < string .h >
3 #include < string .h >
4 #include < stdlib.h >
5 #include < math.h >
6
7 #include < iostream >
8 using namespace std;
9
10 #define NN 15000 // 14997 + 3
11 #define NL 100
12 #define L 6
13 typedef struct {
14 int a[L];
15 }item;
16
17 item snow[NN][NL];
18 int m[NN];
19
20 int hash(item SNOW){
21 int i;
22 int key = 0 ;
23 for (i = 0 ; i < 6 ; i ++ ){
24 key += SNOW.a[i];
25 }
26 key %= 14997 ;
27 return key;
28 }
29
30 int cmp(item x, item y){
31 int st, i, j;
32 for (st = 0 ; st < 6 ; st ++ ){ // 右移
33 for (i = st, j = 0 ; j < 6 ; j ++ , i = (i + 1 ) % 6 ){
34 if (x.a[i] != y.a[j]) break ;
35 }
36 if (j == 6 ) return 1 ;
37 }
38 for (st = 0 ; st < 6 ; st ++ ){ // 左移
39 for (i = st, j = 0 ; j < 6 ; j ++ , i = (i + 5 ) % 6 ){
40 if (x.a[i] != y.a[j]) break ;
41 }
42 if (j == 6 ) return 1 ;
43 }
44 return 0 ;
45 }
46 int main() {
47 int i, j, pos, n;
48 item SNOW;
49 scanf( " %d " , & n);
50 memset(m, 0 , sizeof (m));
51 for (i = 1 ; i <= n; i ++ ){
52 for (j = 0 ; j < 6 ; j ++ ){
53 scanf( " %d " , & SNOW.a[j]);
54 }
55 pos = hash(SNOW);
56 for (j = 0 ; j < m[pos]; j ++ ){
57 if (cmp(SNOW, snow[pos][j])){
58 puts( " Twin snowflakes found. " );
59 return 0 ;
60 }
61 }
62 snow[pos][m[pos]] = SNOW;
63 m[pos] ++ ;
64 }
65 puts( " No two snowflakes are alike. " );
66 return 0 ;
67 }
68
2 #include < string .h >
3 #include < string .h >
4 #include < stdlib.h >
5 #include < math.h >
6
7 #include < iostream >
8 using namespace std;
9
10 #define NN 15000 // 14997 + 3
11 #define NL 100
12 #define L 6
13 typedef struct {
14 int a[L];
15 }item;
16
17 item snow[NN][NL];
18 int m[NN];
19
20 int hash(item SNOW){
21 int i;
22 int key = 0 ;
23 for (i = 0 ; i < 6 ; i ++ ){
24 key += SNOW.a[i];
25 }
26 key %= 14997 ;
27 return key;
28 }
29
30 int cmp(item x, item y){
31 int st, i, j;
32 for (st = 0 ; st < 6 ; st ++ ){ // 右移
33 for (i = st, j = 0 ; j < 6 ; j ++ , i = (i + 1 ) % 6 ){
34 if (x.a[i] != y.a[j]) break ;
35 }
36 if (j == 6 ) return 1 ;
37 }
38 for (st = 0 ; st < 6 ; st ++ ){ // 左移
39 for (i = st, j = 0 ; j < 6 ; j ++ , i = (i + 5 ) % 6 ){
40 if (x.a[i] != y.a[j]) break ;
41 }
42 if (j == 6 ) return 1 ;
43 }
44 return 0 ;
45 }
46 int main() {
47 int i, j, pos, n;
48 item SNOW;
49 scanf( " %d " , & n);
50 memset(m, 0 , sizeof (m));
51 for (i = 1 ; i <= n; i ++ ){
52 for (j = 0 ; j < 6 ; j ++ ){
53 scanf( " %d " , & SNOW.a[j]);
54 }
55 pos = hash(SNOW);
56 for (j = 0 ; j < m[pos]; j ++ ){
57 if (cmp(SNOW, snow[pos][j])){
58 puts( " Twin snowflakes found. " );
59 return 0 ;
60 }
61 }
62 snow[pos][m[pos]] = SNOW;
63 m[pos] ++ ;
64 }
65 puts( " No two snowflakes are alike. " );
66 return 0 ;
67 }
68