더북(TheBook)

그러나 이 방법은 다음과 같은 경우에 문제가 발생할 수 있습니다.

데이터가 실수인 경우

데이터가 숫자가 아닌 경우

데이터 범위가 너무 큰 경우. 예를 들어 10억 개의 숫자를 사용한다면 10억 크기의 부울 타입 배열이 필요한데, 이는 좋은 방법이 아닙니다.

이 문제를 해결하기 위해 어떤 데이터 타입의 값이든 원하는 범위의 정수로 매핑하는 함수를 만들어 사용할 수 있습니다. 이 경우 원하는 정수 범위를 적절히 설정하면 부울 타입 배열을 만드는 것이 전혀 부담이 되지 않을 것입니다. 이러한 역할을 하는 함수가 바로 앞에서 언급했던 해시 함수입니다. 이 함수는 데이터 원소를 인자로 받고 정해진 범위의 정수를 반환합니다.

가장 간단한 해시 함수는 큰 범위의 정수를 인자로 받아 정해진 정수(n)로 나눈 나머지를 반환하는 모듈로 함수(modulo function)이며, 보통 % 기호로 표시합니다. 이 경우 크기가 n인 배열을 사용할 수 있습니다.

만약 이 함수에 숫자 x를 입력으로 주면 (x % n) 연산의 결과가 반환되고, 이 값은 0부터 (n - 1) 사이의 정수입니다. 그럼 x를 배열에서 (x % n) 위치에 삽입하면 됩니다. 이처럼 해시 함수에 의해 반환되는 숫자 값을 해시 값(hash value)이라고 합니다.

모듈로 함수의 문제점은 이 함수가 서로 다른 데이터에 대해 같은 해시 값을 반환할 수 있다는 점입니다. 예를 들어 (9 % 7)과 (16 % 7)은 모두 해시 값으로 2를 반환합니다. 그러므로 해시 값 2에 해당하는 위치가 true(또는 1)로 채워져 있을 경우, 여기에 들어 있는 데이터가 9인지 혹은 16인지를 알 수 없습니다. 또는 x % 7 = 2를 만족하는 다른 정수 x가 저장되어 있을 수도 있습니다. 이러한 문제를 충돌(collision)이라고 합니다. 즉, 충돌이란 해시 함수가 서로 다른 키에 대해 같은 해시 값을 반환함으로써, 다수의 키가 같은 값을 갖게 되는 현상을 말합니다.

해시 테이블에 부울 값 대신 실제 데이터를 저장하면 해당 키에 어떤 데이터가 저장되어 있는지를 바로 알 수 있지만 여전히 여러 데이터를 저장할 수는 없습니다. 이러한 문제를 어떻게 해결할 수 있는지에 대해서는 다음 절에서 설명하겠습니다. 그 전에 연습 문제 13에서 정수 값을 저장하는 간단한 사전을 구현해보겠습니다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.