2024. 2. 20. 19:08ใCS - Roadmap.sh/4. String Search and Manipulations
CS - 4. String Search and Manipulations - 4.4. Knuth morris pratt
Knuth Morris Pratt
๐กKnuth morris pratt is a string searching algorithm that uses a precomputed array to find the substring in a string. This array is known as the prefix function. The prefix function is the longest prefix that is also a suffix of a substring. The prefix function is used to skip the characters that are already matched. The algorithm is as follows:
- Compute the prefix function of the substring.
- Traverse through the string and substring simultaneously.
- If the characters match, increment the index of both the string and substring.
- If the characters donโt match, increment the index of the string by the value of the prefix function at the index of the substring.
KMP ์๊ณ ๋ฆฌ์ฆ์ ๋ฏธ๋ฆฌ ๊ณ์ฐ๋ ๋ฐฐ์ด์ ์ฌ์ฉํ์ฌ ๋ฌธ์์ด์ ํ์ ๋ฌธ์์ด์ ์ฐพ๋ ๋ฌธ์์ด ๊ฒ์ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค. ์ด ๋ฐฐ์ด์ ์ ๋์ฌ ํจ์๋ผ๊ณ ํฉ๋๋ค. ์ ๋์ฌ ํจ์๋ ํ์ ๋ฌธ์์ด์ ์ ๋ฏธ์ฌ์ด๊ธฐ๋ ํ ๊ฐ์ฅ ๊ธด ์ ๋์ฌ์ ๋๋ค. ์ ๋์ฌ ํจ์๋ ์ด๋ฏธ ์ผ์นํ๋ ๋ฌธ์๋ฅผ ๊ฑด๋๋ฐ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ์๊ณ ๋ฆฌ์ฆ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ํ์ ๋ฌธ์์ด์ ์ ๋์ฌ ํจ์๋ฅผ ๊ณ์ฐํฉ๋๋ค.
- ๋ฌธ์์ด๊ณผ ๋ถ๋ถ ๋ฌธ์์ด์ ๋์์ ์ํํฉ๋๋ค.
- ๋ฌธ์๊ฐ ์ผ์นํ๋ฉด ๋ฌธ์์ด๊ณผ ๋ถ๋ถ ๋ฌธ์์ด์ ์ธ๋ฑ์ค๋ฅผ ๋ชจ๋ ์ฆ๊ฐ์ํต๋๋ค.
- ๋ฌธ์๊ฐ ์ผ์นํ์ง ์์ผ๋ฉด ๋ฌธ์์ด์ ์ธ๋ฑ์ค์์ ๋ถ๋ถ ๋ฌธ์์ด์ ์ธ๋ฑ์ค์ ์๋ ์ ๋์ฌ ํจ์์ ๊ฐ๋งํผ ๋ฌธ์์ด์ ์ธ๋ฑ์ค๋ฅผ ์ฆ๊ฐ์ํต๋๋ค.
Knuth-Morris-Pratt (KMP) ์๊ณ ๋ฆฌ์ฆ์ ๋ฌธ์์ด ๊ฒ์ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก, ์ฃผ์ด์ง ํ ์คํธ์์ ํจํด์ด ์ผ์นํ๋ ์์น๋ฅผ ์ฐพ๋๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ๊ธฐ๋ณธ์ ์ธ ์์ด๋์ด๋ ๊ฐ๋จํ ๋ฌธ์์ด ๊ฒ์ ์๊ณ ๋ฆฌ์ฆ๊ณผ ๋ค๋ฅด๊ฒ, ํจํด์ ๊ฐ ์์น์์ ๋ถ์ผ์น๊ฐ ๋ฐ์ํ๋ฉด ํจํด์ ๊ฐ๋ฅํ ํ ์ต๋ํ ์ด๋์ํค๋ ๊ฒ์ ๋๋ค. ์ด๋ฅผ ์ํด "๋ถ๋ถ ์ผ์น" ํ ์ด๋ธ(๋๋ "์คํจ ํจ์")์ ๋ฏธ๋ฆฌ ๊ณ์ฐํฉ๋๋ค.
์ด๋ ์๋ํ๋ก์ธ์๊ฐ์ ์์ฒ, ์๋ฐฑ๋ง ๋จ์ด์์ ํน์ ๋ฌธ์์ด ํจํด์ ์ฐพ์๋ ํจ์จ์ ์ผ๋ก ์ํํ ์ ์์ต๋๋ค. KMP ์๊ณ ๋ฆฌ์ฆ์ด ํ ์คํธ ๋ด์์ ๊ฐ์ฅ ๋น ๋ฅด๊ฒ ์ํ๋ ๋ฌธ์์ด์ ์ฐพ์๋ด๋ ์๊ณ ๋ฆฌ์ฆ ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
In Python
def kmp_search(text, pattern):
pattern_length = len(pattern)
text_length = len(text)
lps = [0]*pattern_length # ๋ถ๋ถ ์ผ์น ํ
์ด๋ธ ์ด๊ธฐํ
j = 0 # ํจํด ๋ฌธ์์ด์ ์ธ๋ฑ์ค
# ๋ถ๋ถ ์ผ์น ํ
์ด๋ธ ๊ณ์ฐ(์๋ ํจ์์ ์ ์ํจ)
compute_lps_array(pattern, pattern_length, lps)
i = 0 # ํ
์คํธ ๋ฌธ์์ด์ ์ธ๋ฑ์ค
while i < text_length:
if pattern[j] == text[i]: # ๋ฌธ์๊ฐ ์ผ์นํ๋ฉด ๋ ๋ค ์ฆ๊ฐ
i += 1
j += 1
if j == pattern_length: # ํจํด ๋ฌธ์์ด์ ๋๊น์ง ๋น๊ตํ์ผ๋ฉด ํจํด ๋ฐ๊ฒฌ
print("ํจํด์ด ๋ฐ๊ฒฌ๋ ์์น: " + str(i-j))
j = lps[j-1] # ๋ค์ ๋น๊ต๋ฅผ ์ํด ์ธ๋ฑ์ค ๊ฐ์
# ํจํด์ด ๋ถ์ผ์นํ๊ณ ํ
์คํธ๊ฐ ์์ง ๋๋์ง ์์๋ค๋ฉด
elif i < text_length and pattern[j] != text[i]:
if j != 0: # ํจํด์ ์ค๊ฐ์์ ๋ถ์ผ์น๊ฐ ๋ฐ์ํ๋ฉด
j = lps[j-1] # lps๊ฐ์ ์ด์ฉํ์ฌ j๋ฅผ ๊ฐ์
else: # ํจํด์ ์ฒซ ๋ฒ์งธ ๋ฌธ์์์ ๋ถ์ผ์น๊ฐ ๋ฐ์ํ๋ฉด
i += 1 # ํ
์คํธ ๋ฌธ์์ด์ ์ธ๋ฑ์ค๋ง ์ฆ๊ฐ
# ๋ถ๋ถ ์ผ์น ํ
์ด๋ธ(LPS ๋ฐฐ์ด) ๊ณ์ฐ ํจ์
def compute_lps_array(pattern, pattern_length, lps):
length = 0 # ์ด์ ์ ๊ณ์ฐ๋ ๊ฐ์ฅ ๊ธด ์ ๋์ฌ/์ ๋ฏธ์ฌ์ ๊ธธ์ด
lps[0] = 0 # lps[0]์ ํญ์ 0
i = 1 # lps ์ธ๋ฑ์ค
# ํจํด์ ๋ ๋ฒ์งธ ๋ฌธ์๋ถํฐ lps ๋ฐฐ์ด์ ์ฑ์๋๊ฐ
while i < pattern_length:
if pattern[i] == pattern[length]: # ํจํด์ ๋ฌธ์๊ฐ ์ผ์นํ๋ฉด
length += 1 # ๊ธธ์ด ์ฆ๊ฐ
lps[i] = length # lps ๋ฐฐ์ด์ ๊ธธ์ด ๊ฐ ํ ๋น
i += 1
else:
if length != 0: # ์ด์ ์ธ๋ฑ์ค์์ ์ผ์น๊ฐ ๋ฐ์ํ์ผ๋ฉด
length = lps[length-1] # ์ด์ lps ๊ฐ์ ์ฌ์ฉ
else: # ์ด์ ์ธ๋ฑ์ค์์ ์ผ์น๊ฐ ์์์ผ๋ฉด
lps[i] = 0 # lps ๊ฐ์ 0
i += 1
๋ฐฉ๊ธ ์์ ์ด ๊ธ์ ๊ฐ์ง๊ณ KMP ์๊ณ ๋ฆฌ์ฆ์ ์ ์ฉํด๋ณด๊ฒ ์ต๋๋ค.

ํ์ฉ
https://www.acmicpc.net/problem/1786(๋ฐฑ์ค 1786 ์ฐพ๊ธฐ)
์ค์ ๋ก ctrl + F ๋ฅผ ํตํด์ ์ฐพ๊ธฐ๋ฅผ ํ๋ ๋ฐฉ๋ฒ์ ๊ตฌํํ๋ ๋ฌธ์ .
'CS - Roadmap.sh > 4. String Search and Manipulations' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
4.6 Rabin-Karpโs algorithm(๋ผ๋น-์นดํ ์๊ณ ๋ฆฌ์ฆ) (0) | 2024.02.22 |
---|---|
4.5 Boyer Moore Algorithm(๋ณด์ด์ด-๋ฌด์ด ์๊ณ ๋ฆฌ์ฆ) (0) | 2024.02.21 |
4.3 Brute Force Search(์์ ํ์) (0) | 2024.02.17 |
4.2 Suffix Arrays(์ ๋ฏธ์ฌ ๋ฐฐ์ด) (0) | 2024.02.15 |
4. String Search and Manipulations - 4.1 Search Pattern in Text(๋ฌธ์์ด ๊ฒ์ ๋ฐ ์กฐ์) (ํ ์คํธ ํจํด ๊ฒ์) (0) | 2024.02.14 |