给定一系列由大写英文字母组成的字符串关键字和素数PPP,用移位法定义的散列函数H(Key)H(Key)H(Key)将关键字KeyKeyKey中的最后3个字符映射为整数,每个字符占5位;再用除留余数法将整数映射到长度为PPP的散列表中。例如将字符串AZDEG
插入长度为1009的散列表中,我们首先将26个大写英文字母顺序映射到整数0~25;再通过移位将其映射为3×322+4×32+6=32063\times 32^2 + 4 \times 32 + 6 = 32063×322+4×32+6=3206;然后根据表长得到,即是该字符串的散列映射位置。
发生冲突时请用平方探测法解决。
输入格式:
输入第一行首先给出两个正整数NNN(≤500\le 500≤500)和PPP(≥2N\ge 2N≥2N的最小素数),分别为待插入的关键字总数、以及散列表的长度。第二行给出NNN个字符串关键字,每个长度不超过8位,其间以空格分隔。
输出格式:
在一行内输出每个字符串关键字在散列表中的位置。数字间以空格分隔,但行末尾不得有多余空格。
输入样例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
这里有一个小坑,平方法解决冲突的时候,数值可能为负,需要通过素数p将其调整为正。
#include <stdio.h> #include <string> #include <math.h> #include <iostream> #include <cstring> #include <map> using namespace std; int chang_string_to_int(char *s); int main(void) { int n,p; scanf("%d %d",&n,&p); char a[9]; string *s = new string [n]; int *snum = new int [n]; int *index = new int [n]; int *container = new int [p]; for (int i=0;i<p;i++){ container[i]=-1; } for (int i=0;i<n;i++){ scanf("%s",a); s[i]=a; snum[i]=chang_string_to_int(a); } map<string, int> s_index; map<string, int>::iterator iter; /*for (int i=0;i<n;i++){ printf("%d ",snum[i]%p); } printf("\n");*/ int temp,temp1; int add=0; bool flag=true; for (int i=0;i<n;i++){ iter = s_index.find(s[i]); if (iter!=s_index.end()){ index[i]=iter->second; }else{ temp=snum[i]%p; temp1=temp; add=1; flag=true; while(container[temp1]!=-1){ temp1=temp; if (flag){ temp1+=add*add; flag=false; }else{ temp1-=add*add; while(temp1<0){ temp1+=p; } add++; flag=true; } //printf("***%d\n",temp1); temp1%=p; } temp=temp1; container[temp]=snum[i]; index[i]=temp; s_index.insert(pair<string,int>(s[i],index[i])); } } printf("%d",index[0]); for (int i=1;i<n;i++){ printf(" %d",index[i]); } printf("\n"); return 0; } int chang_string_to_int(char *a){ int l=strlen(a); int num=0; if (l>=3){ //printf("%s %d %c %c %c **%d %d %d\n",a,l,a[l-1],a[l-2],a[l-3],a[l-1]-'A',a[l-2]-'A',a[l-3]-'A'); num=a[l-1]-'A'+32*(a[l-2]-'A')+1024*(a[l-3]-'A'); }else if (l==2){ num=a[0]-'A'+32*(a[1]-'A'); }else if (l==1){ num=a[0]-'A'; } return num; }