대부분의 언어에서 이미 내장 함수를 가지지만 여기서는 직접 해시 테이블을 함수를 만들어 구현한다.!
JS에서는 Obj, Map을 가진다.
해시 테이블은 키-값 쌍을 저장하는데 사용된다.
해시 테이블의 키는 순서를 가지지 않는다.
값을 찾거나, 새로운 값을 추가하거나, 값을 제거하는데 아주 빠르다.
속도가 빠르다
일관된 방식으로 분배를 해서 다른 것들과 겹치지 않게 해야 한다.
특정 입력값을 입력할 때마다 같은 출력값이 나와야 한다.
충돌이 발생하면 다음 빈칸이 어디인지 확인하고 빈칸에 저장한다, 이렇게 하면 데이터가 같은 인덱스에 저장되는 것을 막을 수 있다.
배열의 길이가 소수 일경우 소수가 아닐때보다 충돌 횟수가 줄어든다.
class HashTable { constructor(size=53){ this.keyMap = new Array(size) } _hash(key){ let total = 0 let WEIRD_PRIME = 31 for(let i =0; i<Math.min(key.length,100); i++){ let char = key[i] let value = char.charCodeAt(0) - 96 total = (total * WEIRD_PRIME + value) % this.keyMap.length } return total } }
set(key,value){ let hashKey = this._hash(key) if(!this.keyMap[hashKey]){ this.keyMap[hashKey] = [] } this.keyMap[hashKey].push([key,value]) return this }
get(key) { let hashKey = this._hash(key) if(this.keyMap[hashKey]){ for(let i = 0; i<this.keyMap[hashKey].length; i++){ if(this.keyMap[hashKey][i][0] === key){ return this.keyMap[hashKey][i][1] } } } return undefined }
테이블에 있는 모든 키를 포함한 목록을 출력한다.
keys(){ let keysArr = [] for(let i = 0; i< this.keyMap.length; i++){ if(this.keyMap[i]){ for(let j = 0; j<this.keyMap[i].length; j++){ if(!keysArr.includes(this.keyMap[i][j][0])){ keysArr.push(this.keyMap[i][j][0]) } } } } return keysArr }
테이블에 있는 모든 값을 포함한 목록을 출력한다.
values(){ let valuesArr = [] for(let i = 0; i< this.keyMap.length; i++){ if(this.keyMap[i]){ for(let j = 0; j<this.keyMap[i].length; j++){ if(!valuesArr.includes(this.keyMap[i][j][1])){ valuesArr.push(this.keyMap[i][j][1]) } } } } return valuesArr }