해시(Hash)는 데이터를 저장하는 자료구조 중 하나로, 효율적인 데이터 검색을 위해 사용됩니다. 해시 테이블은 키(Key)와 값(Value)을 매핑하는 구조로, 각 키를 해시 함수를 사용하여 고유한 해시 코드(Hash code)로 변환하고, 해당 해시 코드에 대응되는 값을 저장합니다.
해시 함수(Hash function)는 입력 데이터를 고정 크기의 해시 코드(Hash code)로 변환하는 함수입니다. 해시 함수는 임의의 길이를 가진 입력 데이터를 고정된 길이의 해시 코드로 매핑하는 작업을 수행합니다.
특징
public int simpleHash(String input) {
int hash = 0;
for (char c : input.toCharArray()) {
hash += (int) c;
}
return hash % 100; // 100개의 버킷을 가지는 해시 테이블에서 사용하기 위해 100으로 나눈 나머지를 반환
}
키 값이 다른데, 해시 함수의 결과값이 동일한 경우
해결법으로 분리 연결법(Separate Chaining)과 개방 주소법(Open Addressing)등이 있다.
분리 연결법(separate Chaining)
체이닝은 저장소(Bucket)에서 충돌이 일어나면 기존 값과 새로운 값을 연결리스트로 연결하는 방법이다.
개방 주소법(Open Addressing)
MyLinkedHashTable
package com.example.datastructure.Hash;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class MyLinkedHashTable<K, V> {
private static final int DEFAULT_BUCKET_SIZE = 1024;
private List<Node>[] buckets;
private int size;
private int bucketSize;
public MyLinkedHashTable(){
this.buckets = new List[DEFAULT_BUCKET_SIZE];
this.bucketSize = DEFAULT_BUCKET_SIZE;
this.size = 0;
for(int i = 0; i< bucketSize; i++){
this.buckets[i] = new LinkedList<>();
}
}
// 사용자 사이즈 정의
public MyLinkedHashTable(int bucketSize){
this.buckets = new List[DEFAULT_BUCKET_SIZE];
this.bucketSize = DEFAULT_BUCKET_SIZE;
this.size = 0;
for(int i = 0; i< bucketSize; i++){
this.buckets[i] = new LinkedList<>();
}
}
public void put(K key, V value){
int idx = this.hash(key);
List<Node> bucket = this.buckets[idx];
for(Node node : bucket){
if(node.key.equals(key)){
node.data = value;
return;
}
}
Node node = new Node(key, value);
bucket.add(node);
size++;
}
public V get(K key){
int idx = this.hash(key);
List<Node> bucket = this.buckets[idx];
for(Node node : bucket){
if(node.key.equals(key)){
return node.data;
}
}
return null;
}
public boolean delete(K key){
int idx = this.hash(key);
List<Node> bucket = this.buckets[idx];
for(Iterator<Node> iter = bucket.iterator(); iter.hasNext();){
Node node = iter.next();
if(node.key.equals(key)){
iter.remove();
this.size--;
return true;
}
}
return false;
}
public boolean contains(K key){
int idx = this.hash(key);
List<Node> bucket = this.buckets[idx];
for(Node node : bucket){
if(node.key.equals(key)){
return true;
}
}
return false;
}
public int size(){
return this.size;
}
private int hash(K key) {
int hash = 0;
for(Character ch : key.toString().toCharArray()){
hash += (int) ch;
}
return hash % this.bucketSize;
}
private class Node{
K key;
V data;
Node(K key, V date){
this.key = key;
this.data = data;
}
}
}
List<Node>[]
백준 1920. 수 찾기
package com.example.datastructure.Hash;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
/*
1920. 수 찾기
*/
public class Baekjoon_1920 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
Set<Integer> A = new HashSet<>();
for(int i = 0; i < N; i++){
int n = sc.nextInt();
A.add(n);
}
int M = sc.nextInt();
StringBuilder result = new StringBuilder();
for(int i = 0; i < M; i++){
int m = sc.nextInt();
if(A.contains(m)){
result.append(1 + "\n");
}else{
result.append(0 + "\n");
}
}
System.out.println(result);
}
}