▶패턴 매칭
본문에서 특정 string(패턴)을 찾아야 하는 경우에 유용하게 쓰일 수 있다.
예시)
"asdgsadf" "a"를 찾아서 "AAA"로 변경하라.
위와 같은 문제가 있을 때, 문제 해결을 위해서 우선 "a"의 위치를 찾아야한다.
이 때 본문이 되는 "asdgsadf"에서 "a"라는 패턴을 찾는 방법을 패턴 매칭이라고 한다.
▶패턴 매칭 알고리즘
- 고지식한 패턴 검색 알고리즘(Brute Force)
본문 string을 처음부터 끝까지 차례대로 순회하면서 패턴 내의 문자들을 일일이 비교하는 방식으로 동작한다.
(길이가 10000인 string에서 길이 80의 패턴을 찾는다면 10000*80 = 800000번의 비교가 일어남)
- KMP 알고리즘
: 불일치가 발생한 텍스트 스트링의 앞 부분에 어떤 문자가 있는지를 미리 알고 있으므로,
불일치가 발생한 앞 부분에 대하여 다시 비교하지 않고 매칭을 수행함
- 패턴을 전처리하여 배열 next[M]을 구해서 잘못된 시작을 최소화함
next[M] : 불일치가 발생했을 경우 이동할 다음 위치
- 시간복잡도 : O(M + N)
패턴의 각 위치에 대해 매칭에 실패했을 때 돌아갈 곳을 준비해둔다.
- 보이어-무어 알고리즘
대부분의 상용 소프트웨어에서 채택하고 있는 알고리즘이다.
뒷쪽에서 앞쪽으로 비교해야 한다는 특징이 있다.
문자열의 인덱스를 저장하는 포인터 역할을 할 변수는
본문에서 처음 비교할 패턴의 끝 문자를 가리키며 시작한다.
본문 : "abcdefghijk"
찾는 패턴 : "bcd"
위와 같은 경우에 포인터 변수는 인덱스 2로 시작한다.
WHILE ( true )
{
IF ( 포인터가 본문의 인덱스 범위를 초과 ) {
break;
}
IF ( 포인터가 가리키는 문자와 찾는 패턴의 끝 문자가 불일치 ) {
IF ( 포인터가 가리키는 문자가 찾는 패턴 내에 존재하지 않는 경우 ) {
포인터를 찾는 패턴의 길이만큼 이동시킨다.
}
IF ( 포인터가 가리키는 문자가 찾는 패턴 내에 존재할 경우 ) {
포인터를 찾는 패턴 내에서 일치하는 문자와의 거리만큼만 이동시킨다.
}
}
ELSE {
찾는 패턴의 나머지 문자들을 본문 패턴의 나머지 문자들과 비교한다.
IF ( 모두 일치하는 경우 ) {
패턴을 찾았으므로 원하는 작업을 수행
포인터를 찾는 패턴의 길이만큼 이동시킨다.
}
ELSE {
포인터를 찾는 패턴의 길이만큼 이동시킨다.
}
}
}
- 예시
▶시간 복잡도
찾고자 하는 String 패턴의 길이 : M
총 String 길이 : N
- 고지식한 패턴 검색 알고리즘 : 수행시간 O(MN)
- 카프 라빈 알고리즘 : 수행시간 O(N)
- KMP 알고리즘 : 수행시간 O(N)
- 보이어-무어 알고리즘 : 일반적으로 수행시간 O(N)보다 작음
(최악의 경우 O(MN))
2019. 04. 01. 11:56
'□ 이론 > 알고리즘' 카테고리의 다른 글
프림(Prim)과 크루스칼(Kruskal) 알고리즘 (0) | 2019.06.05 |
---|---|
계수 정렬(Counting sort) (0) | 2019.06.03 |
기수 정렬(Radix sort) (0) | 2019.06.03 |
조합 생성 알고리즘 (0) | 2019.03.01 |
순열 생성 알고리즘 (0) | 2019.01.17 |