go手动实现哈希表
原理作用
哈希表的作用就是将一个较大范围或者较复杂的数据映射到一个较小的数据(0~N)
哈希算法
1、取模,x % y ,y一般取值为质数,并且要尽可能的离2的整次幂远,这样取值,发生冲突的概率最小
2、解决冲突,通常有两种方法,拉链法和开放寻址法
方法
题目:
维护一个集合,支持如下几种操作:
“I x”,插入一个数x;
“Q x”,询问数x是否在集合中出现过;
现在要进行N次操作,对于每个询问操作输出对应的结果。
输入格式
第一行包含整数N,表示操作数量。
接下来N行,每行包含一个操作指令,操作指令为”I x”,”Q x”中的一种。
输出格式
对于每个询问指令“Q x”,输出一个询问结果,如果x在集合中出现过,则输出“Yes”,否则输出“No”。
每个结果占一行。
数据范围
1≤N≤105
−109≤x≤109
输入样例:
5
I 1
I 2
I 3
Q 2
Q 5
输出样例:
Yes
No
*/
1、拉链法
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
const N = 100003
var (
idx int
h [N]int
ne [N]int
e [N]int
)
// 求质数
func primeNumber(i int) {
var tag bool
for {
for j := 2; j*j < i; j++ {
tag = true
if i%j == 0 {
tag = false
break
}
}
if tag {
fmt.Println(i)
break
}
i++
}
}
func insert(x int) {
k := (x%N + N) % N
e[idx] = x
ne[idx] = h[k]
h[k] = idx
idx++
}
func find(x int) {
k := (x%N + N) % N
// 遍历链表,找到上面与x相等的值
for i := h[k]; i != -1; i = ne[i] {
if e[i] == x {
fmt.Println("Yes")
return
}
}
fmt.Println("No")
}
func readline(r *bufio.Reader) []string {
s, _ := r.ReadString('\n')
ss := strings.Fields(s)
return ss
}
func main() {
//将哈希表的初始值设置为-1
for i := 0; i < N; i++ {
h[i] = -1
}
var n int
fmt.Scanf("%d", &n)
r := bufio.NewReader(os.Stdin)
for i := 0; i < n; i++ {
in := readline(r)
op := in[0]
switch op {
case "I":
x, _ := strconv.Atoi(in[1])
insert(x)
case "Q":
x, _ := strconv.Atoi(in[1])
find(x)
}
}
}
2、开放寻址法
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
//const N = 100003
const N = 200003 // 大概是需要的2-3倍
const null = 0x3f3f3f3f
var h[N]int
func find(x int)int {
k := (x%N + N) % N
for h[k]!=null && h[k]!=x{ // 说明该位置已经被占用了
k++ // 向后一位移动
if k==N{ // 如果看完最后一个位置,
k=0 //循环看第一个位置
}
}
//h[k]=x
return k // 返回下标,如果x在哈希数组h中,就返回x在h中的位置,
// 如果不在,就返回应该存储的位置
}
func insert(x int) {
//k := (x%N + N) % N
//for h[k]!=null{ // 说明该位置已经被占用了
// k++ // 向后一位移动
//}
k :=find(x)
h[k]=x
}
func query(x int) {
k :=find(x)
if h[k]!=null{
fmt.Println("Yes")
}else {
fmt.Println("No")
}
}
func readLine(r *bufio.Reader)[]string {
s,_ :=r.ReadString('\n')
sSlcie:=strings.Fields(s)
return sSlcie
}
func main() {
for i:=0;i<N;i++{
h[i] = null
}
var n int
fmt.Scan(&n)
r :=bufio.NewReader(os.Stdin)
for i:=0;i<n;i++{
in :=readLine(r)
op :=in[0]
x,_ :=strconv.Atoi(in[1])
k :=find(x)
switch op {
case "I":
//insert(x)
h[k] = x
case "Q":
//x,_ :=strconv.Atoi(in[1])
//query(x)
if h[k] == null{
fmt.Println("No")
}else {
fmt.Println("Yes")
}
}
}
}