7-59 字符串关键字的散列映射
给定一系列由大写英文字母组成的字符串关键字和素数P,用移位法定义的散列函数H(Key)将关键字Key中的最后3个字符映射为整数,每个字符占5位;再用除留余数法将整数映射到长度为P的散列表中。例如将字符串AZDEG插入长度为1009的散列表中,我们首先将26个大写英文字母顺序映射到整数0~25;再通过移位将其映射为3×32
2
+4×32+6=3206;然后根据表长得到,即是该字符串的散列映射位置。
发生冲突时请用平方探测法解决。
输入格式:
输入第一行首先给出两个正整数N(≤500)和P(≥2N的最小素数),分别为待插入的关键字总数、以及散列表的长度。第二行给出N个字符串关键字,每个长度不超过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
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n= scan.nextInt();
int p=scan.nextInt();
HashMap<String ,Integer> hm = new HashMap<String, Integer>();
int maxn = (int) 1e6;
Boolean[] bo = new Boolean[maxn];
Arrays.fill(bo, false);
String s = null;
for(int y=0;y<n;y++) {
s=scan.next();
int x=0;
if(s.length()==1) {
x=s.charAt(0)-'A';
}else if(s.length()==2) {
x=32*(s.charAt(1)-'A')+(s.charAt(0)-'A');
}else {
for (int j = 3; j >= 1; j--) {
int t = s.length() - j;
x = x * 32 + s.charAt(t) - 'A';
}
}
x=x%p;
//System.out.println("\n"+s+x);
if(hm.containsKey(s)||!bo[x]) {
hm.put(s, x);
bo[x]=true;
System.out.print(x);
}
else {
int y1;
for(int j=1;j*j<maxn;j++) {
y1=(x+j*j)%p;
//System.out.println("y1"+y1);
if(!bo[y1]) {
bo[y1]=true;
hm.put(s, y1);
System.out.print(y1);
break;
}
y1=(x-j*j+p)%p;
if(!bo[y1]) {
bo[y1]=true;
hm.put(s, y1);
System.out.print(y1);
break;
}
}
}
if(y<n-1) {
System.out.print(" ");
}
else
System.out.println();
}
}
}