[자료구조/알고리즘] 해시(Hash), 해시테이블(Hash Table), 해시함수 (Hash Function) 개념 및 예제

isitcake_yes·2023년 5월 12일
0
post-thumbnail

해시(Hash)?

1. 개념

  • Hash(Hash Table) : Key : Value의 형태를 가진 하나의 자료구조 (python에서는 dictionary 구조)
    모든 데이터 타입으로 접근이 가능하다.
  • Hash function: 임의 길이 데이터(input)를 암호화된 고정 길이(output)의 int데이터로 매핑(전환)하는 함수

왼쪽 그림: Hash Function의 역할. 임의 길이 데이터를 고정길이 데이터로 전환.
오른쪽 그림 : buckets라고 하는 칸에는 key인 사람의 전화번호(value)가 있다.
-> 즉, key값을 hash function에 넣어 얻은 hashes를 배열의 인덱스로 쓰는 테이블을 hash table이라고 한다.

  • [key] -> [hash func] -> [hash(==h(key))] - [value(in bucket)] 라는 네 단계를 거친다.

2. 충돌 Hash collision

충돌 : 서로 다른 key에 대해 동일한 hash값(index)이 부여된 상황

충돌 해결 1.개별체이닝 (Seperate Chaining)

: 충돌 발생 시 동일한 key에 다른 value를 연결리스트로 연결해 충돌을 해결하는 방법

충돌 해결 2.오픈 어드레싱 (Open Addressing)

: 충돌 발생 시 테이블 공간을 탐사해 빈 공간을 찾아나서는 방식

3. 시간복잡도 O(n) 속도 비교

  • 일반적인 경우(Collision이 없음) -> O(1)
  • 최악의 경우(Collision이 모두 발생) -> O(n)
  • 해시 테이블의 평균(충돌이 일어나지 않았을 경우) 시간복잡도는 O(1)로, 매우 빠르게 탐색, 삽입 삭제할 수 있다.

ex) 배열과 해시 테이블 비교
: 10개의 배열에 데이터를 저장하고, 검색할 때 O(10)
: 10개의 데이터 저장공간을 가진 해시 테이블에 데이터를 저장하고, 검색할 때 O(1)


4. 어떤 문제에서 해시를 사용해야 할까?

  • String을 기반으로 정보를 기록하고 관리해야 할 때 !
  • 데이터를 빠르게 넣거나 가져와야 할 때 !
  • 매우 긴 리스트, 리스트로 풀 경우 효율성 떨어지는 경우!

    ex) 문제예시 (프로그래머스)

    1. 완주하지 못한 선수 : 선수이름 (String key) -> 완주여부(Bool value)
    2. 신고결과 받기 : 게시판 사용자 (String key) -> 신고자들의 목록 (Array value)
    3. 위장 : 옷의 종류(String key) -> 옵션 개수 (integer value)

예제 - 완주하지 못한 선수

문제설명

수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.
마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.

제한사항

  • 마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.
  • completion의 길이는 participant의 길이보다 1 작습니다.
  • 참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.
  • 참가자 중에는 동명이인이 있을 수 있습니다.

입출력 예

participant, completion > return
["leo", "kiki", "eden"]["eden", "kiki"] > "leo"
["marina", "josipa", "nikola", "vinko", "filipa"]["josipa", "filipa", "marina", "nikola"] > "vinko"
["mislav", "stanko", "mislav", "ana"]["stanko", "ana", "mislav"] > "mislav"

입출력 예 설명

예제 #1
"leo"는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.
예제 #2
"vinko"는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.
예제 #3
"mislav"는 참여자 명단에는 두 명이 있지만, 완주자 명단에는 한 명밖에 없기 때문에 한명은 완주하지 못했습니다.

BEST CODE (해쉬사용)

def solution(participant, completion):
    answer = ''
    temp = 0
    dic = {}
    # participant의 hash구조 만들기, hash sum구하기
    for part in participant:
        dic[hash(part)] = part
        temp += int(hash(part))
    # completion의 hash값 빼기        
    for com in completion:
        temp -= hash(com)
    answer = dic[temp]

    return answer

참고

profile
주니어 개발자 주니어발록 주니어예티 주니어레이스

0개의 댓글