Skip to content

Commit

Permalink
개별 체이닝 해시 테이블, 선형 탐지 해시 테이블 테스트 추가
Browse files Browse the repository at this point in the history
테스트 코드를 추가합니다.
  • Loading branch information
hannut91 committed Aug 29, 2023
1 parent 828ea80 commit 447c650
Show file tree
Hide file tree
Showing 3 changed files with 332 additions and 1 deletion.
169 changes: 169 additions & 0 deletions problem-5/LinearProbingHashTable.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
class LinearProbingHashTable {
#N = 0;
#M = 0;
#keys = [];
#values = [];

constructor(maxCount = 16) {
this.#M = maxCount;
this.#keys = new Array(this.#M);
this.#values = new Array(this.#M);
}

#hash(key) {
let hash = 0;
for (let i = 0; i < key.length; i++) {
hash = (31 * hash + key.charCodeAt(i)) % this.#M;
}
return hash;
}

hash(key) {
return this.#hash(key)
}

get(key) {
}

put(key, value) {
}

delete(key) {
}

contains(key) {
}

keys() {
}

#resize(capacity) {
}
}

const randomString = (max) => {
let result = '';
const characters = 'abcdefghijklmnopqrstuvwxyz';
const charactersLength = characters.length;
const length = Math.floor(Math.random() * max) + 1;

for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * charactersLength);
result += characters.charAt(randomIndex);
}

return result;
}

test('이미 있는 키 값에 값을 추가하면 이전 값을 덮어쓴다', () => {
const st = new LinearProbingHashTable();

st.put('foo', 'bar');

expect(st.get('foo')).toBe('bar');

st.put('foo', 'other');

expect(st.get('foo')).toBe('other');
});

test('삭제한 키를 조회하면 undefined를 반환한다', () => {
const st = new LinearProbingHashTable();

st.put('foo', 'bar');

expect(st.get('foo')).toBe('bar');

st.delete('foo');

expect(st.get('foo')).toBeUndefined();
});

test('없는 키를 조회하면 undefined를 반환한다', () => {
const st = new LinearProbingHashTable();

expect(st.get('foo')).toBeUndefined();
});

test('contains 해당하는 키와 값이 존재할 경우 true를 반환한다', () => {
const st = new LinearProbingHashTable();

st.put('foo', 'bar');

expect(st.contains('foo')).toBe(true);
});

test('contains 해당하는 키와 값이 없을 경우 false를 반환한다', () => {
const st = new LinearProbingHashTable();

expect(st.contains('foo')).toBe(false);
});

test('심볼 테이블은 키에 해당하는 값을 저장한다', () => {
const st = new LinearProbingHashTable();

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');

st.delete('this');
st.delete('something');
st.delete('foo');

expect(st.get('foo')).toBeUndefined();
expect(st.get('something')).toBeUndefined();
expect(st.get('this')).toBeUndefined();
});

test('해시의 결과 같더라도, 키에 해당하는 값이 저장된다.', () => {
const st = new LinearProbingHashTable();

let a;
let b;

while (true) {
a = randomString(10);
b = randomString(10);
if (st.hash(a) === st.hash(b) && a !== b) {
break;
}
}

st.put(a, '123');
st.put(b, '456');

expect(st.get(a)).toBe('123');
expect(st.get(b)).toBe('456');
});

test('keys는 모든 키 목록을 담은 배열을 반환한다', () => {
const st = new LinearProbingHashTable();

let a;
let b;

while (true) {
a = randomString(10);
b = randomString(10);
if (st.hash(a) === st.hash(b) && a !== b) {
break;
}
}

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);
});
3 changes: 2 additions & 1 deletion problem-5/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ E A S Y Q U T I O N
순서를 k라 할 때 해시 함수 11k % M을 이용하여 테이블의 인덱스로 변환해
주세요.

3. 테스트 요구사항에 맞는 개별 체이닝 해시 테이블과 선형 탐지 해싱 테이블을 구현해 주세요.
3. 테스트 요구사항에 맞는 개별 체이닝 해시 테이블과 선형 탐지 해싱 테이블을
구현해 주세요.
161 changes: 161 additions & 0 deletions problem-5/SeperateChainingHashTable.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
class SeperateChainingHashTable {
#M;

constructor(maxCount = 997) {
this.#M = maxCount;
}

#hash(key) {
let hash = 0;
for (let i = 0; i < key.length; i++) {
hash = (31 * hash + key.charCodeAt(i)) % this.#M;
}
return hash;
}

hash(key) {
return this.#hash(key)
}

get(key) {
}

put(key, value) {
}

delete(key, value) {
}

contains(key) {
}

keys() {
}
}

const randomString = (max) => {
let result = '';
const characters = 'abcdefghijklmnopqrstuvwxyz';
const charactersLength = characters.length;
const length = Math.floor(Math.random() * max) + 1;

for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * charactersLength);
result += characters.charAt(randomIndex);
}

return result;
}

test('이미 있는 키 값에 값을 추가하면 이전 값을 덮어쓴다', () => {
const st = new SeperateChainingHashTable();

st.put('foo', 'bar');

expect(st.get('foo')).toBe('bar');

st.put('foo', 'other');

expect(st.get('foo')).toBe('other');
});

test('삭제한 키를 조회하면 undefined를 반환한다', () => {
const st = new SeperateChainingHashTable();

st.put('foo', 'bar');

expect(st.get('foo')).toBe('bar');

st.delete('foo');

expect(st.get('foo')).toBeUndefined();
});

test('없는 키를 조회하면 undefined를 반환한다', () => {
const st = new SeperateChainingHashTable();

expect(st.get('foo')).toBeUndefined();
});

test('contains 해당하는 키와 값이 존재할 경우 true를 반환한다', () => {
const st = new SeperateChainingHashTable();

st.put('foo', 'bar');

expect(st.contains('foo')).toBe(true);
});

test('contains 해당하는 키와 값이 없을 경우 false를 반환한다', () => {
const st = new SeperateChainingHashTable();

expect(st.contains('foo')).toBe(false);
});

test('심볼 테이블은 키에 해당하는 값을 저장한다', () => {
const st = new SeperateChainingHashTable();

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');

st.delete('this');
st.delete('something');
st.delete('foo');

expect(st.get('foo')).toBeUndefined();
expect(st.get('something')).toBeUndefined();
expect(st.get('this')).toBeUndefined();
});

test('해시의 결과 같더라도, 키에 해당하는 값이 저장된다.', () => {
const st = new SeperateChainingHashTable();

let a;
let b;

while (true) {
a = randomString(10);
b = randomString(10);
if (st.hash(a) === st.hash(b) && a !== b) {
break;
}
}

st.put(a, '123');
st.put(b, '456');

expect(st.get(a)).toBe('123');
expect(st.get(b)).toBe('456');
});

test('keys는 모든 키 목록을 담은 배열을 반환한다', () => {
const st = new SeperateChainingHashTable();

let a;
let b;

while (true) {
a = randomString(10);
b = randomString(10);
if (st.hash(a) === st.hash(b) && a !== b) {
break;
}
}

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);
});

0 comments on commit 447c650

Please sign in to comment.