[210702]
예시
O(n)
시간이 걸림O(log n)
시간이 걸림O(1)
시간 만에 즉시 가격을 알려줄 수 있다.해시 함수 hash function
: 해시 함수는 문자열(string)을 받아 숫자를 반환하는 함수이다.
즉, 문자열에 대해 숫자를 맵핑(mapping, 할당)한다.
위 예제에 적용하자면..
가격을 배열에 저장한다.
O(1)
)위 예제처럼, 해시 함수와 배열을 합치면 해시 테이블이라는 자료구조가 된다.
해시 테이블의 동의어 = 해시 맵 hash maps, 맵 maps, 딕셔너리 dictionaries, 연관 배열 associative arrays
해시 테이블 (파이썬에서는 딕셔너리) 사용 예제 코드
book = dict() # 빈 해시 테이블 만들기 (1)
book = {} # 빈 해시 테이블 만들기 (2)
book["apple"] = 0.67 # apple의 가격 = 0.67달러
book["milk"] = 1.49 # milk의 가격 = 1.49달러
print book # {'apple': 0.67, 'milk': 1.49}
print book["avocado"] # 1.49
위와 같은 경우 해시테이블을 사용하면 좋다.
'표'로 항목-항목 간 관계를 모형화하고 싶은 경우 해시테이블이 적절하다.
예시 : DNS확인(DNS resolution) 작업 - 웹 주소에 대해 IP주소를 할당하는 작업
get()
: 해시테이블 내에 해당 키가 있으면 그 키에 해당하는 값을 반환하고, 없으면 None을 반환함.예시 : 선거에서 어떤 사람이 이미 투표한 사람이라면 돌려보내고, 투표한 적 없는 사람이라면 이름을 추가한 후 투표하게 한다.
voted = {}
def check_voter(name):
if voted.get(name):
print "돌려 보내세요!"
else:
voted[name] = True
print "투표하게 하세요."
캐싱 caching
: 정보를 매번 탐색/계산하지 않고, 미리 저장했다가 알려주는 것.
비유 : 지구에서 달까지의 거리를 처음 물어보면 구글링하느라 시간이 걸리지만, 10번 물어보면 외워서 바로 대답하게 된다.
이처럼 웹 페이지를 요청할 때마다 매번 서버에서 받아오는 게 아니라, (자주 쓰는) 어떤 페이지는 미리 저장해 두었다가 바로 보여주는 것이 캐싱이다.
캐싱의 장점
모든 대형 웹 사이트는 캐싱을 사용하고, 캐싱한 자료가 해시 테이블에 저장된다.
URL 호출 시 캐싱된 해시테이블에 저장되어 있는지 확인하고, 있다면 저장된 내용을 / 없다면 서버로붙어 받아온 내용을 보여준다.
cache = {}
def get_page(url):
if cache.get(url):
return cache[url] # 캐싱된 자료 전송
else:
data = get_data_from_server(url)
cache[url] = data # 캐시에 처음으로 자료를 저장
return data
: 두 개의 키가 같은 공간에 할당되는 것.
해시 테이블의 성능을 이해하기 위해 충돌을 이해해야 한다.
사실 첫 설명처럼 모든 데이터에 대한 배열 공간을 할당하는 해시함수를 만드는 것은 거의 불가능하다.
충돌이 발생해, 이미 할당된 공간에 또 할당하려 하면 기존 데이터에 덮어씌워지게 된다. -> 막아야 함!
해결1
: 배열의 한 공간에 여러 키를 링크드리스트로 만들어 넣는다.
결론1
좋은 해시 함수 = 충돌을 최소화시키는 함수.
평균적인 경우, 해시 테이블은 모든 항목에 대해 O(1)
(상수 시간) 이 걸린다.
상수 시간 constant time : 크기에 상관없이 항상 똑같은 시간이 걸린다.
but 최악의 경우, 해시 테이블은 모든 항목에 대해 O(n)
(선형 시간)이 걸린다.
-> 최악의 경우를 피하려면 충돌을 피해야 한다.
-> 충돌을 피하려면 아래와 같이 해야 한다.
해시 테이블의 로드팩터 = 해시 테이블에 있는 항목의 수 / 해시 테이블에 있는 공간의 수.
예를 들어 { , 2, , 4}
와 같은 배열에서 사용률은 50%이다. (2개/4칸)
로드팩터는 해시 테이블에 빈 공간이 얼마나 남아 있는지를 측정한다.
로드 팩터가 낮을수록 충돌이 적게 일어나고, 해시 테이블의 성능이 좋아진다.
O(1)
시간이 걸린다.: 배열에 값을 골고루 분포시키는 함수.
가능한 한 항목들을 넓게 할당해야 한다.
참고 : SHA함수. (11장 참조)
<-> 나쁜 해시 함수 : 값들이 뭉쳐져 있음. 충돌이 자주 발생함.