diff --git a/problem-1/SymbolTableWithArray.js b/problem-1/SymbolTableWithArray.js index 761c9ef..769b177 100644 --- a/problem-1/SymbolTableWithArray.js +++ b/problem-1/SymbolTableWithArray.js @@ -1,4 +1,58 @@ class SymbolTable { + #arr = []; + #size; + + constructor() { + this.#size = 0; + } + + size() { + return this.#size; + } + + isEmpty() { + return this.#size === 0; + } + + getKey(key) { + let idx; + this.#arr.forEach((item, arrIdx) => { + if (item.key === key) { + idx = arrIdx; + } + }); + return idx; + } + + put(key, value) { + if (this.#size === 0 || this.getKey(key) === undefined) { + const obj = { key: key, value: value }; + this.#arr.push(obj); + this.#size++; + } else if (this.#size > 0 && this.getKey(key) !== undefined) { + // 좀 더 조건식을 고칠 수 있을 거 같은데 널체크나 0 길이 체크 시 계속 || && 에러낸다.. + this.#arr[this.getKey(key)].value = value; + } + } + + get(key) { + const arrKey = this.getKey(key); + console.log(999, this.#arr); + return arrKey === undefined ? undefined : this.#arr[arrKey].value; + } + + delete(key) { + const arrKey = this.getKey(key); + if (arrKey !== undefined) { + delete this.#arr[arrKey]; + this.#size--; + } + } + + contains(key) { + const arrKey = this.getKey(key); + return arrKey !== undefined; + } } module.exports = { diff --git a/problem-1/problem-1.test.js b/problem-1/problem-1.test.js index 9f38cf6..91a973d 100644 --- a/problem-1/problem-1.test.js +++ b/problem-1/problem-1.test.js @@ -1,126 +1,126 @@ -const { SymbolTable } = require('./SymbolTableWithArray'); +const { SymbolTable } = require("./SymbolTableWithArray"); -test('심볼 테이블은 비어있다', () => { +test("심볼 테이블은 비어있다", () => { const st = new SymbolTable(); expect(st.size()).toBe(0); expect(st.isEmpty()).toBe(true); }); -test('심볼 테이블에 아이템을 추가하면 사이즈가 증가한다.', () => { +test("심볼 테이블에 아이템을 추가하면 사이즈가 증가한다.", () => { const st = new SymbolTable(); const oldSize = st.size(); - st.put('foo', 'bar'); + st.put("foo", "bar"); const newSize = st.size(); expect(newSize - oldSize).toBe(1); }); -test('이미 있는 키 값에 값을 추가하면 사이즈가 증가하지 않는다.', () => { +test("이미 있는 키 값에 값을 추가하면 사이즈가 증가하지 않는다.", () => { const st = new SymbolTable(); - st.put('foo', 'bar'); + st.put("foo", "bar"); const oldSize = st.size(); - st.put('foo', 'other'); + st.put("foo", "other"); const newSize = st.size(); expect(newSize - oldSize).toBe(0); }); -test('이미 있는 키 값에 값을 추가하면 이전 값을 덮어쓴다', () => { +test("이미 있는 키 값에 값을 추가하면 이전 값을 덮어쓴다", () => { const st = new SymbolTable(); - st.put('foo', 'bar'); + st.put("foo", "bar"); - expect(st.get('foo')).toBe('bar'); + expect(st.get("foo")).toBe("bar"); - st.put('foo', 'other'); + st.put("foo", "other"); - expect(st.get('foo')).toBe('other'); + expect(st.get("foo")).toBe("other"); }); -test('삭제한 키를 조회하면 undefined를 반환한다', () => { +test("삭제한 키를 조회하면 undefined를 반환한다", () => { const st = new SymbolTable(); - st.put('foo', 'bar'); + st.put("foo", "bar"); - expect(st.get('foo')).toBe('bar'); + expect(st.get("foo")).toBe("bar"); - st.delete('foo'); + st.delete("foo"); - expect(st.get('foo')).toBeUndefined(); + expect(st.get("foo")).toBeUndefined(); }); -test('없는 키를 조회하면 undefined를 반환한다', () => { +test("없는 키를 조회하면 undefined를 반환한다", () => { const st = new SymbolTable(); - expect(st.get('foo')).toBeUndefined(); + expect(st.get("foo")).toBeUndefined(); }); -test('키를 삭제하면 사이즈가 감소한다', () => { +test("키를 삭제하면 사이즈가 감소한다", () => { const st = new SymbolTable(); - st.put('foo', 'bar'); + st.put("foo", "bar"); const oldSize = st.size(); - st.delete('foo'); + st.delete("foo"); const newSize = st.size(); expect(newSize - oldSize).toBe(-1); }); -test('없는 키를 삭제하면 사이즈가 감소하지 않는다', () => { +test("없는 키를 삭제하면 사이즈가 감소하지 않는다", () => { const st = new SymbolTable(); - st.put('foo', 'bar'); + st.put("foo", "bar"); const oldSize = st.size(); - st.delete('other'); + st.delete("other"); const newSize = st.size(); expect(newSize - oldSize).toBe(0); }); -test('contains 해당하는 키와 값이 존재할 경우 true를 반환한다', () => { +test("contains 해당하는 키와 값이 존재할 경우 true를 반환한다", () => { const st = new SymbolTable(); - st.put('foo', 'bar'); + st.put("foo", "bar"); - expect(st.contains('foo')).toBe(true); + expect(st.contains("foo")).toBe(true); }); -test('contains 해당하는 키와 값이 없을 경우 false를 반환한다', () => { +test("contains 해당하는 키와 값이 없을 경우 false를 반환한다", () => { const st = new SymbolTable(); - expect(st.contains('foo')).toBe(false); + expect(st.contains("foo")).toBe(false); }); -test('심볼 테이블은 키에 해당하는 값을 저장한다', () => { +test("심볼 테이블은 키에 해당하는 값을 저장한다", () => { const st = new SymbolTable(); - st.put('foo', 'bar'); - st.put('something', 'that'); - st.put('this', 'is'); + st.put("foo", "bar"); + st.put("something", "that"); + st.put("this", "is"); - expect(st.get('foo')).toBe('bar'); - expect(st.get('something')).toBe('that'); - expect(st.get('this')).toBe('is'); + expect(st.get("foo")).toBe("bar"); + expect(st.get("something")).toBe("that"); + expect(st.get("this")).toBe("is"); - st.delete('this'); - st.delete('something'); - st.delete('foo'); + st.delete("this"); + st.delete("something"); + st.delete("foo"); - expect(st.get('foo')).toBeUndefined(); - expect(st.get('something')).toBeUndefined(); - expect(st.get('this')).toBeUndefined(); + expect(st.get("foo")).toBeUndefined(); + expect(st.get("something")).toBeUndefined(); + expect(st.get("this")).toBeUndefined(); }); diff --git a/problem-5/LinearProbingHashTable.test.js b/problem-5/LinearProbingHashTable.test.js index e4a1b2b..2ae537e 100644 --- a/problem-5/LinearProbingHashTable.test.js +++ b/problem-5/LinearProbingHashTable.test.js @@ -19,31 +19,59 @@ class LinearProbingHashTable { } hash(key) { - return this.#hash(key) + return this.#hash(key); + } + + // start + getEmptyIdx() { + const isEmpty = (elem) => elem === undefined; + return this.#keys.findIndex(isEmpty); } get(key) { + const keyIdx = this.getKeyIdx(key); + return keyIdx === -1 ? undefined : this.#values[keyIdx]; + } + + getKeyIdx(key) { + return this.#keys.indexOf(key); } put(key, value) { + const emptyIndex = this.getEmptyIdx(); + const keyIndex = this.getKeyIdx(key); + + if (keyIndex === -1) { + this.#keys[emptyIndex] = key; + this.#values[emptyIndex] = value; + } else { + this.#values[keyIndex] = value; + } } delete(key) { + const keyIndex = this.getKeyIdx(key); + if (keyIndex !== -1) { + delete this.#keys[keyIndex]; + delete this.#values[keyIndex]; + } } contains(key) { + return this.getKeyIdx(key) !== -1; } keys() { + const keyArr = this.#keys.splice(0, this.getEmptyIdx()); + return keyArr; } - #resize(capacity) { - } + #resize(capacity) {} } const randomString = (max) => { - let result = ''; - const characters = 'abcdefghijklmnopqrstuvwxyz'; + let result = ""; + const characters = "abcdefghijklmnopqrstuvwxyz"; const charactersLength = characters.length; const length = Math.floor(Math.random() * max) + 1; @@ -53,73 +81,73 @@ const randomString = (max) => { } return result; -} +}; -test('이미 있는 키 값에 값을 추가하면 이전 값을 덮어쓴다', () => { +test("이미 있는 키 값에 값을 추가하면 이전 값을 덮어쓴다", () => { const st = new LinearProbingHashTable(); - st.put('foo', 'bar'); + st.put("foo", "bar"); - expect(st.get('foo')).toBe('bar'); + expect(st.get("foo")).toBe("bar"); - st.put('foo', 'other'); + st.put("foo", "other"); - expect(st.get('foo')).toBe('other'); + expect(st.get("foo")).toBe("other"); }); -test('삭제한 키를 조회하면 undefined를 반환한다', () => { +test("삭제한 키를 조회하면 undefined를 반환한다", () => { const st = new LinearProbingHashTable(); - st.put('foo', 'bar'); + st.put("foo", "bar"); - expect(st.get('foo')).toBe('bar'); + expect(st.get("foo")).toBe("bar"); - st.delete('foo'); + st.delete("foo"); - expect(st.get('foo')).toBeUndefined(); + expect(st.get("foo")).toBeUndefined(); }); -test('없는 키를 조회하면 undefined를 반환한다', () => { +test("없는 키를 조회하면 undefined를 반환한다", () => { const st = new LinearProbingHashTable(); - expect(st.get('foo')).toBeUndefined(); + expect(st.get("foo")).toBeUndefined(); }); -test('contains 해당하는 키와 값이 존재할 경우 true를 반환한다', () => { +test("contains 해당하는 키와 값이 존재할 경우 true를 반환한다", () => { const st = new LinearProbingHashTable(); - st.put('foo', 'bar'); + st.put("foo", "bar"); - expect(st.contains('foo')).toBe(true); + expect(st.contains("foo")).toBe(true); }); -test('contains 해당하는 키와 값이 없을 경우 false를 반환한다', () => { +test("contains 해당하는 키와 값이 없을 경우 false를 반환한다", () => { const st = new LinearProbingHashTable(); - expect(st.contains('foo')).toBe(false); + expect(st.contains("foo")).toBe(false); }); -test('심볼 테이블은 키에 해당하는 값을 저장한다', () => { +test("심볼 테이블은 키에 해당하는 값을 저장한다", () => { const st = new LinearProbingHashTable(); - st.put('foo', 'bar'); - st.put('something', 'that'); - st.put('this', 'is'); + st.put("foo", "bar"); + st.put("something", "that"); + st.put("this", "is"); - expect(st.get('foo')).toBe('bar'); - expect(st.get('something')).toBe('that'); - expect(st.get('this')).toBe('is'); + expect(st.get("foo")).toBe("bar"); + expect(st.get("something")).toBe("that"); + expect(st.get("this")).toBe("is"); - st.delete('this'); - st.delete('something'); - st.delete('foo'); + st.delete("this"); + st.delete("something"); + st.delete("foo"); - expect(st.get('foo')).toBeUndefined(); - expect(st.get('something')).toBeUndefined(); - expect(st.get('this')).toBeUndefined(); + expect(st.get("foo")).toBeUndefined(); + expect(st.get("something")).toBeUndefined(); + expect(st.get("this")).toBeUndefined(); }); -test('해시의 결과 같더라도, 키에 해당하는 값이 저장된다.', () => { +test("해시의 결과 같더라도, 키에 해당하는 값이 저장된다.", () => { const st = new LinearProbingHashTable(); let a; @@ -133,14 +161,14 @@ test('해시의 결과 같더라도, 키에 해당하는 값이 저장된다.', } } - st.put(a, '123'); - st.put(b, '456'); + st.put(a, "123"); + st.put(b, "456"); - expect(st.get(a)).toBe('123'); - expect(st.get(b)).toBe('456'); + expect(st.get(a)).toBe("123"); + expect(st.get(b)).toBe("456"); }); -test('keys는 모든 키 목록을 담은 배열을 반환한다', () => { +test("keys는 모든 키 목록을 담은 배열을 반환한다", () => { const st = new LinearProbingHashTable(); let a; @@ -154,16 +182,16 @@ test('keys는 모든 키 목록을 담은 배열을 반환한다', () => { } } - st.put(a, '123'); - st.put(b, '456'); - st.put('FOO', 'bar'); - st.put('HELLO', 'world'); + st.put(a, "123"); + st.put(b, "456"); + st.put("FOO", "bar"); + st.put("HELLO", "world"); const keys = st.keys(); expect(keys.length).toBe(4); expect(keys.includes(a)).toBe(true); expect(keys.includes(b)).toBe(true); - expect(keys.includes('FOO')).toBe(true); - expect(keys.includes('HELLO')).toBe(true); + expect(keys.includes("FOO")).toBe(true); + expect(keys.includes("HELLO")).toBe(true); });