-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathHashMap.ts
133 lines (115 loc) · 3.15 KB
/
HashMap.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import { ValuePair } from "../utils/dictionary-list-models";
import { defaultToString } from "../utils/Util";
import Map from "./Map";
export class HashMap<K, V> implements Map<K, V> {
protected table: { [key: number]: ValuePair<K, V> };
constructor(protected toStrFn: (key: K) => string = defaultToString) {
this.table = {};
}
put(key: K, value: V): boolean {
if (key != null && value != null) {
const position = this.hashCode(key);
this.table[position] = new ValuePair(key, value);
return true;
}
return false;
}
// 生成哈希码
hashCode(key: K): number {
return this.djb2HashCode(key);
}
// loselose实现哈希函数
loseloseHashCode(key: K): number {
if (typeof key === "number") {
return key;
}
const tableKey = this.toStrFn(key);
let hash = 0;
for (let i = 0; i < tableKey.length; i++) {
// 获取每个字符的ASCII码将其拼接至hash中
hash += tableKey.charCodeAt(i);
}
return hash % 37;
}
// djb2实现哈希函数
djb2HashCode(key: K): number {
if (typeof key === "number") {
return key;
}
// 将参数转为字符串
const tableKey = this.toStrFn(key);
let hash = 5381;
for (let i = 0; i < tableKey.length; i++) {
hash = hash * 33 + tableKey.charCodeAt(i);
}
return hash % 1013;
}
clear(): void {
this.table = {};
}
forEach(callbackFn: (key: K, value: V) => any): void {
const valuePairs = this.keyValues();
for (let i = 0; i < valuePairs.length; i++) {
const result = callbackFn(valuePairs[i].key, valuePairs[i].value);
if (result === false) {
break;
}
}
}
get(key: K): V | undefined {
const valuePair = this.table[this.hashCode(key)];
return valuePair == null ? undefined : valuePair.value;
}
hasKey(key: K): boolean {
return this.table[this.hashCode(key)] != null;
}
isEmpty(): boolean {
return this.values().length === 0;
}
keyValues(): ValuePair<K, V>[] {
const valuePairs = [];
// 获取对象中的所有key并将其转为int类型数组
const keys = Object.keys(this.table).map((item) => parseInt(item));
for (let i = 0; i < keys.length; i++) {
valuePairs.push(this.table[keys[i]]);
}
return valuePairs;
}
keys(): K[] {
const keys = [];
const valuePairs = this.keyValues();
for (let i = 0; i < valuePairs.length; i++) {
keys.push(valuePairs[i].key);
}
return keys;
}
remove(key: K): boolean {
if (this.hasKey(key)) {
delete this.table[this.hashCode(key)];
return true;
}
return false;
}
size(): number {
return this.keyValues().length;
}
values(): V[] {
const values = [];
const valuePairs = this.keyValues();
for (let i = 0; i < valuePairs.length; i++) {
values.push(valuePairs[i].value);
}
return values;
}
toString(): string {
if (this.isEmpty()) {
return ``;
}
const valuePairs = this.keyValues();
let objString = `${valuePairs[0].toString()}`;
for (let i = 1; i < valuePairs.length; i++) {
objString = `${objString},${valuePairs[i].toString()}`;
}
return objString;
}
}