문자열 알고리즘
Date:
N 길이의 문장에서 M 길이의 패턴을 찾는다고 생각할 때 다음과 같이 3가지 방법이 있다.
1. Brute-Force 탐색
- 가장 단순한 탐색 방법이다.
- O(MN)의 시간복잡도를 갖는다.
word = input()
sentence = input()
len1 = len(word)
len2 = len(sentence)
ans = 0
for i in range(len2 - len1 + 1):
match = True
for j in range(len1):
if word[j] != sentence[i + j]:
match = False
break
if match:
ans += 1
print(ans)
2. KMP 알고리즘
- 불일치하더라도 탐색했던 정보를 활용하는 방법이다.
- 불일치 얼마나 건너뛰어야 할지(skip) 기록해놓은 pi 배열을 만들어서 활용한다.
- 패턴의 왼쪽에서 오른쪽으로 비교한다.
- O(M + N)의 시간 복잡도를 갖는다.
M = 0
N = 0
def getPi(p):
pi = [0] * M
cnt = 0 # 일치하는 문자 개수
for i in range(1, M):
while cnt > 0 and p[i] != p[cnt]: # 일치하지 않으면 계속 건너뜀
cnt = pi[cnt - 1]
if p[i] == p[cnt]:
cnt = cnt + 1
pi[i] = cnt
return pi
p = input()
s = input()
M = len(p)
N = len(s)
pi = getPi(p)
cnt = 0
match = 0
for i in range(N):
while cnt > 0 and s[i] != p[cnt]: # 일치하지 않으면 계속 건너뜀
cnt = pi[cnt - 1]
if s[i] == p[cnt]:
cnt = cnt + 1
if cnt == M:
match = 1
break
print(match)
3. 보이어-무어 알고리즘
- 패턴의 끝부분부터 비교한다.
- 끝부분이 앞부분보다 불일치 확률이 높아 실용적이다.
- 상용 제품에서 가장 많이 쓰이는 문자열 알고리즘이다.
- 일반적으로 O(N) 이하의 시간복잡도이지만, 최악의 경우 O(MN) 시간복잡도를 갖는다.
- 평균적으로 KMP 알고리즘보다 우수한 성능을 가진다.
댓글