728x90
반응형
해시 테이블 또는 해시 맵은 키를 값에 매핑할 수 있는 구조인, 연관 배열 추상 자료형을 구현하는 자료구조이다. 가장 큰 특징은 대부분의 연산이 분할 상환 분석에 따른 시간 복잡도가 O(1)이라는 점이다.
해시 함수와 해싱의 이해
- 해시 함수는 임의의 크기를 가진 데이터를 고정된 크기 값으로 변환하는 함수입니다.
- 예를 들어, 아래와 같이 다양한 길이의 문자열을 고정된 크기의 해시 값으로 매핑할 수 있습니다:
- ABC -> A1
- 12321F -> B1
- FSR4 -> C3
- 이처럼 입력값을 특정한 값으로 변환하는 역할을 하는 함수를 해시 함수라 합니다.
- 이러한 해시 함수의 결과를 사용해 해시 테이블을 인덱싱하고 데이터를 빠르게 저장하고 검색하는 기법을 해싱이라고 합니다.
- 해싱은 특히 최적의 검색 성능이 요구되는 분야나 심볼 테이블 등에서 유용하게 활용됩니다.
해싱의 활용 분야
해시 함수는 정보 검색 이외에도 다양한 분야에 쓰입니다:
- 체크섬(Checksum): 데이터의 무결성을 확인하는 데 사용
- 손실 압축: 대용량 데이터를 일정 크기로 줄이는 압축
- 무작위화 함수: 예측 불가능한 난수 생성
- 암호화: 안전한 데이터 저장과 통신
이와 같은 여러 용도로 해시 함수가 사용되며, 때로는 혼용되기도 합니다.
성능 좋은 해시 함수의 특징
- 충돌 최소화: 서로 다른 입력값이 같은 해시 값을 가질 확률이 낮아야 합니다.
- 빠른 연산: 해시 함수 계산이 간단하고 빠른 연산으로 이루어져야 합니다.
- 균일한 분포: 해시 테이블 전체에 걸쳐 해시 값이 고르게 분포되어야 합니다.
- 모든 키 정보 활용: 해싱할 때 키의 모든 정보를 효과적으로 사용해야 합니다.
- 효율적인 테이블 사용: 테이블의 공간을 잘 활용해 저장 효율을 높여야 합니다.
해시 충돌 예시 - 생일 문제
- 해시 충돌이 얼마나 쉽게 일어날 수 있는지를 잘 보여주는 예로 생일 문제가 있습니다.
- 사람들의 생일은 총 365가지로 한정되어 있지만, 여러 사람이 모이면 생일이 같은 사람들이 있을 확률이 높아집니다.
- 예를 들어, 23명만 모여도 두 사람의 생일이 같을 확률은 50%가 넘고, 57명이 모이면 그 확률은 99% 이상이 됩니다.
- 이는 파이썬을 통해 간단히 시뮬레이션할 수 있으며, 일상적인 예상과 달리 충돌이 매우 쉽게 발생할 수 있음을 보여줍니다.
import random
TRY = 100000 # 10만번 실행
same_birthdays = 0 # 생일이 같은 실험의 수
for _ in range(TRY):
birthdays = []
# 23명이 모였을 때, 생일이 같은 경우 same_birthdays +=1
for i in range(23):
birthday = random.randint(1,365)
if birthday in birthdays:
same_birthdays +=1
break
birthdays.append(birthday)
print(f'{same_birthdays / TRY * 100}%') # 50.73%
이처럼 해시 충돌은 예상보다 쉽게 발생하므로 충돌을 줄이는 것은 해시 함수 설계에서 가장 중요한 요소 중 하나입니다.
로드팩터
- 로드팩터(Load Factor)는 해시 테이블에 저장된 데이터의 개수 n을 버킷의 개수 k로 나눈 값으로, 해시 테이블의 채워진 정도를 나타내는 지표입니다.
- 로드 팩터 값에 따라 해시 함수를 재작성하거나 해시 테이블의 크기를 조정할지 결정하게 됩니다.
- 또한 로드 팩터는 해시 함수가 키를 얼마나 잘 분산시키는지를 평가하는 효율성 측정에도 사용됩니다.
- 일반적으로 로드 팩터가 높아질수록 해시 테이블의 성능은 점차 낮아지며, 예를 들어 자바 10에서는 로드 팩터가 0.75를 초과할 경우 동적 배열처럼 테이블 공간을 재할당해 성능 저하를 방지합니다.
해시 함수
- 해시 테이블의 인덱싱을 위해 해시 함수를 사용하는 것을 해싱(Hashing)이라 하며, 해싱에는 다양한 알고리즘이 존재합니다.
- 특정 데이터에 따라 최적의 분포를 제공하는 해시 방법이 다를 수 있습니다.
나눗셈 방식 해시 (Division Hashing)
- 가장 단순하면서도 널리 쓰이는 정수형 해싱 기법 중 하나는 나눗셈 방식(Division Method)입니다.
- 이 방법은 모듈로 연산을 사용하며, 다음과 같은 수식으로 정의됩니다:
$ h(x) = x mod(m) $
$ h(x) $: 입력값 x의 해시 함수를 통해 생성된 값
$ m $: 해시 테이블의 크기, 일반적으로 2의 멱수에 가깝지 않은 소수를 택하는 것이 좋다.
- 이 방법은 매우 단순하지만, 대부분의 키 세트가 충분히 랜덤한 상태이므로 실무에서도 효과적으로 사용됩니다.
728x90
반응형
'책 리뷰 > 파이썬 알고리즘 인터뷰' 카테고리의 다른 글
11장. 해시 테이블(6) - 예제(상위 K빈도 요소) (1) | 2024.11.10 |
---|---|
11장. 해시 테이블(5) - 예제(중복 문자 없는 가장 긴 부분 문자열) (0) | 2024.11.09 |
11장. 해시 테이블(4) - 예제(보석과 돌) (1) | 2024.11.08 |
11장. 해시 테이블 (3) - 충돌 처리 방식 (개별 체이닝 파이썬 구현) (2) | 2024.11.04 |
11장. 해시 테이블 (2) - 충돌 처리 방식 (개별 체이닝, 오픈 어드레싱) (0) | 2024.11.01 |
댓글