본문 바로가기
알고리즘/알고리즘

Rabin-Karp 알고리즘

by 프로그래밍 공부 2023. 4. 14.

 KMP 알고리즘과 더불어 문자열을 탐색하는 알고리즘 중 하나이다.

Rabin-Karp 알고리즘은 해싱을 이용해서 문자열을 비교하는 알고리즘으로,

최악의 경우 O(MN)이지만 평균적으로는 선형에 가까운 빠른 속도를 가진다.

Rabin-Karp 알고리즘은 다음과 같이 진행된다.

- 패턴의 해시값을 계산한다.

- 비교하려는 문자열에서 패턴의 길이만큼 잘라서 해시값을 계산한다.

- 해시값을 비교한다. (해시값이 같다면 정확히 일치하는 것이고, 다르다면 첫글자를 빼주고 다음 글자를 추가한다.)

- (문자열 - 패턴)의 길이만큼 반복하고 종료한다.

예를 들어 패턴은 ABAC

문자열은 CABABACD라고 하면

패턴의 해시값을 다음과 같이 구한다.

static int cal(String pattern){
	int sum=0;
    int idx= pattern.length()-1;
    for(int i=0;i<pattern.length();i++){
    	sum+=pattern.charAt(i)*Math.pow(2,idx);
        idx--;
    }
    return sum;
}

즉 첫번째 자리부터 자리수에 따라 2의 n승을 곱해주고 더해주는 것이다.

위의 결과로 ABAC의 해시값은 981이 나온다.

이를 바탕으로 문자열 CABABACD와 비교하면 우선 패턴의 길이만큼 똑 떼서 비교한다.

CABA의 해시값은 993. 다르기 때문에 다음으로 진행한다.

이때 C는 탈락되고 B가 추가되니 C*(2^pattern.length()-1)값을 빼준다.

뺀 값에서 2를 곱해주고, B의 값을 더한다.

이를 통해 도출된 ABAB의 해시값은 980이 된다. 이를 반복하다가 ABAC가 되었을 때,

같은 값이 나오게 되고, 이는 패턴과 완전히 같다.

비교할 패턴이 작다면 이렇게 할 수 있지만 패턴의 크기가 굉장히 크다면 해시값이 무수히 커질 수 있다.

이때는 mod연산을 통해 도출할 수 있는데,

mod 연산을 실행한 경우에는 해시값이 유니크하지 않을 수 있기 때문에 

mod연산 후 해시값을 비교한 뒤, 해시값이 같다면 패턴과 해당 부분을 비교해서 일치 여부를 확인한다.

 

라고 이해했다.

'알고리즘 > 알고리즘' 카테고리의 다른 글

KMP 알고리즘(2)  (0) 2023.04.14
KMP 알고리즘(1)  (0) 2023.04.14
위상정렬  (0) 2023.04.03
Dijkstra 알고리즘  (0) 2023.03.30
Prim 알고리즘  (0) 2023.03.30