# 数据结构---散列

### 输入样例:

4 5
24 15 61 88


### 输出样例:

4 0 1 3


#include <iostream>
#include <stdio.h>
using namespace std;
const int MAXN = 1009;
const int INF = -(1<<30);
long long num[MAXN], List[MAXN];
bool Index[MAXN] = {false};
int main()
{
int n, p;
scanf("%d%d",&n,&p);
for(int i = 0; i < p; ++i)
List[i] = INF;
for(int i = 0; i < n; ++i)
{
scanf("%d",&num[i]);
int index = num[i] % p;
if(index < 0) index = (index + p) % p; //除留余数法
for(int j = 0; Index[index] && List[index] != num[i]; ++j) //该循环是线性探测
index = (index + 1) % p;
List[index] = num[i];
Index[index] = true;
num[i] = index;
}
for(int i = 0; i < n; ++i)
{
if(i) printf(" ");
printf("%d", num[i]);
}
return 0;
} 

### 输入样例1:

4 11
HELLO ANNK ZOE LOLI


### 输出样例1:

3 10 4 0


### 输入样例2:

6 11
LLO ANNA NNK ZOJ INNK AAA


### 输出样例2:

3 0 10 9 6 1


#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int MAXN = 1009;
struct infi{
char str[9];
bool ishave;
}Hash[MAXN];
int location[MAXN];
int Move[3] = {0, 5, 10};
int main()
{
int n, p;
char str[8];
scanf("%d%d", &n, &p);
for(int i = 0; i < n; ++i)
{
scanf("%s", str);
int len = strlen(str);
int key = 0;
for(int j = 0; j < 3 && len - j - 1 >= 0; ++j) //映射到一个数字
{
key += (str[len - j - 1] - 'A') * (1 << Move[j]);
}
key = key % p; //除留余数法
for(int j = 0; true; ++j) //平方探测法
{
int di = (j * j) % p; //系数
int tmpkey = (key + di) %p; //正方向探测
if(!Hash[tmpkey].ishave)
{
location[i] = tmpkey, Hash[tmpkey].ishave = true;
strcpy(Hash[tmpkey].str, str);
break;
}
else if(strcmp(Hash[tmpkey].str, str) == 0)
{
location[i] = tmpkey;
break;
}
tmpkey = (key - di) % p; //负方向探测
if(tmpkey < 0) tmpkey = (tmpkey + p) % p;
if(!Hash[tmpkey].ishave)
{
location[i] = tmpkey, Hash[tmpkey].ishave = true;
strcpy(Hash[tmpkey].str, str);
break;
}
else if(strcmp(Hash[tmpkey].str, str) == 0)
{
location[i] = tmpkey;
break;
}
}
}
for(int i = 0; i < n; ++i)
{
if(i) printf(" ");
printf("%d", location[i]);
}
return 0;
}

### 输入样例:

4
13005711862 13588625832
13505711862 13088625832
13588625832 18087925832
15005713862 13588625832


### 输出样例:

13588625832 3


#include <iostream>
using namespace std;
const int MAXN = 100003;
typedef struct infi node;
struct infi{
long long num;
int cnt;
node * next;
};
node *L[MAXN];
int Find(long long n);
int main()
{
int n;
int peo = 0, cnt = 0;
long long n1, n2, Num = 0;
scanf("%d", &n);
for(int i = 0; i < n; ++i)
{
scanf("%lld %lld", &n1, &n2);
int cnt1 = Find(n1);
int cnt2 = Find(n2); //散列操作
if(cnt1 < cnt2) //一下两个if语句确定最大值
n1 = n2, cnt1 = cnt2;
if(cnt1 > cnt)
cnt = cnt1, Num = n1;
}
for(int i = 0; i < MAXN; ++i)
{
while(L[i])
{
if(L[i]->cnt == cnt)
{
peo++;
if(Num > L[i]->num)
Num = L[i]->num;
}
node *tmp = L[i];
L[i] = L[i]->next;
delete tmp;
}
}
if(peo <= 1) printf("%lld %d\n", Num, cnt);
else printf("%lld %d %d\n", Num, cnt, peo);
return 0;
}
int Find(long long n)
{
int index = n % MAXN, cnt = 0;
node *tmp = L[index];
if(tmp == NULL)
{
tmp = new node;
tmp->next = NULL;
tmp->cnt = 1;
tmp->num = n;
L[index] = tmp;
return 1;
}
while(tmp->next != NULL && tmp->num != n)
{
tmp = tmp->next;
}
if(tmp == NULL)
{
node *p = new node;
p->num = n;
p->next = NULL;
p->cnt = 1;
tmp->next = p;
cnt = 1;
}
else if(tmp->num == n)
{
tmp->cnt++;
cnt = tmp->cnt;
}
return cnt;
}

QQ帐户的申请与登陆   (25分)

### 输出格式:

1）若新申请帐户成功，则输出“New: OK”；
2）若新申请的号码已经存在，则输出“ERROR: Exist”；
4）若老帐户QQ号码不存在，则输出“ERROR: Not Exist”；
5）若老帐户密码错误，则输出“ERROR: Wrong PW”。

### 输入样例:

5
L 1234567890 myQQ@qq.com
N 1234567890 myQQ@qq.com
N 1234567890 myQQ@qq.com
L 1234567890 myQQ@qq
L 1234567890 myQQ@qq.com


### 输出样例:

ERROR: Not Exist
New: OK
ERROR: Exist
ERROR: Wrong PW


#include <iostream>
#include <string.h>
using namespace std;
const int MOD = 100005;
typedef struct infi info;
struct infi{
long long ID;
char pass[21];
info *next;
};
infi *count[MOD];
int cnt[MOD];
int main()
{
int n;
char com[3], pw[15];
long long num;
scanf("%d", &n);
for(int i = 0; i < n; ++i)
{
scanf("%s %lld %s", com, &num, pw);
int index = num % MOD; //除留余数法
if(com[0] == 'L')
{
info *tmp = count[index];
bool isexit = false;
bool islaw = true;
while(tmp && !isexit) //查找是否存在账号
{
if(tmp->ID == num) //检验用户名
{
isexit = true;
if(strcmp(tmp->pass, pw) != 0) //判断密码是否正确
islaw = false;
}
tmp = tmp->next;
}
if(!isexit) printf("ERROR: Not Exist\n"); //账号不存在
else
{
else printf("ERROR: Wrong PW\n"); //账号正确，密码错误
}
}
else
{
info *tmp = count[index];
bool isexit = false;
while(tmp && !isexit) //查找账号
{
if(tmp->ID == num)
isexit = true;
tmp = tmp->next;
}
if(isexit) printf("ERROR: Exist\n");
else //新建账号
{
info *p = new info;
p->ID = num;
strcpy(p->pass, pw);
p->next = NULL;
if(cnt[index])
{
tmp = count[index];
while(tmp->next)
tmp = tmp->next;
tmp->next = p;
}
else
count[index] = p;
cnt[index]++;
printf("New: OK\n");
}
}
}
return 0;
}

### 输入样例:

4 500
330106199010080419 499
110108198403100012 15000
120104195510156021 800
330106199010080419 1
4
120104195510156021
110108198403100012
330106199010080419
33010619901008041x


### 输出样例:

800
15000
1000
No Info


#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
const int MAXN = 100009;
typedef struct infi info;
struct infi{
char ID[21];
int totKM;
info *next;
};
info peo[MAXN];
long long getIndex(char *str); //将身份证映射为数字
int main()
{
int n, k, m;
int KM;
char ID[21];
scanf("%d %d", &n, &k);
for(int i = 0; i < n; ++i)
{
scanf("%s %d", ID, &KM);
if(KM < k) KM = k;
int index = (int) (getIndex(ID) % MAXN); //除留余数法
if(peo[index].next == NULL) //拉链法
{
info *tmp = new info;
tmp->next = NULL;
strcpy(tmp->ID, ID);
tmp->totKM = KM;
peo[index].next = tmp;
}
else
{
info *tmp = peo[index].next;
while(strcmp(tmp->ID, ID) && tmp->next)
tmp = tmp->next;
if(strcmp(tmp->ID, ID) == 0)
tmp->totKM += KM;
else
{
info *p = new info;
p->next = NULL;
p->totKM = KM;
strcpy(p->ID, ID);
tmp->next = p;
}
}
}
scanf("%d", &m); //查找
for(int i = 0; i < m; ++i)
{
scanf("%s", ID);
int index = (int)(getIndex(ID) % MAXN);
info *tmp = peo[index].next;
while(tmp)
{
if(strcmp(tmp->ID, ID) == 0)
break;
tmp = tmp->next;
}
if(tmp) printf("%d\n", tmp->totKM);
else printf("No Info\n");
}
return 0;
}
long long getIndex(char *str)
{
long long num = 0;
for(int i = 0; i < 17; ++i)
num = num * 10 + (str[i] - '0');
if(str[17] != 'x') num += (str[17] - '0');
else num += 10;
return num;
}

• 本文已收录于以下专栏：

## 数据结构：散列（hashing）

• u014613043
• 2016年02月26日 13:01
• 2236

## 数据结构之哈希表二（用开散列法实现哈希表）

• hj605635529
• 2017年04月25日 12:18
• 258

## 深入理解数据结构之散列表、散列、散列函数

• kiritor
• 2013年06月12日 12:08
• 5757

## 数据结构之（一）Hash（散列）

• Carol_1992
• 2017年08月05日 20:54
• 412

## 二次探测再散列散列表 源代码（数据结构）

/**********散列表**********/ #ifndef HashTable_ #define HashTable_   #include "Except.h"   template cla...
• zhanghong056
• 2014年08月05日 13:45
• 724

## java实现简单的散列数据结构

• qq1004642027
• 2015年04月29日 15:56
• 1067

## 什么是数据库散列存储？

• zhangqiang_accp
• 2017年06月22日 14:32
• 307

## 数据结构的几种存储方式

• ly_main
• 2016年03月25日 15:41
• 6033

## 一步步带你深入理解数据结构系列--散列表

• u011465808
• 2014年08月17日 19:21
• 648

## 数据结构——线性表——散列存储结构——哈希表知识点总结

• misayaaaaa
• 2017年05月14日 10:08
• 1720

举报原因： 您举报文章：数据结构---散列 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)