2024. 2. 21. 23:56ใCS - Roadmap.sh/4. String Search and Manipulations
CS - 4. String Search and Manipulations - 4.5. Boyer Moore Algorithm
Boyer Moore Algorithm
๐กBoyer Moore algorithm is a string searching algorithm that is used to find the index of a substring in a string. It is a very efficient algorithm that is used in many applications. It is used in text editors, compilers, and many other applications.
๋ณด์ด์ด ๋ฌด์ด ์๊ณ ๋ฆฌ์ฆ์ ๋ฌธ์์ด์์ ํ์ ๋ฌธ์์ด์ ์ธ๋ฑ์ค๋ฅผ ์ฐพ๋ ๋ฐ ์ฌ์ฉ๋๋ ๋ฌธ์์ด ๊ฒ์ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค. ๋ง์ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ฌ์ฉ๋๋ ๋งค์ฐ ํจ์จ์ ์ธ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค. ํ ์คํธ ํธ์ง๊ธฐ, ์ปดํ์ผ๋ฌ ๋ฐ ๊ธฐํ ์ฌ๋ฌ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ฌ์ฉ๋ฉ๋๋ค.
๋ณด์ด์ด-๋ฌด์ด ์๊ณ ๋ฆฌ์ฆ์ ๋ฌธ์์ด ๊ฒ์ ์๊ณ ๋ฆฌ์ฆ ์ค ํ๋๋ก, ํนํ ๊ธด ๋ฌธ์ฅ์์ ์งง์ ํจํด์ ์ฐพ์๋ด๋ ๋ฐ ๋งค์ฐ ํจ์จ์ ์
๋๋ค. 1977๋
์ Robert Boyer์ J Strother Moore์ ์ํด ๊ฐ๋ฐ๋์์ต๋๋ค.
๋ณด์ด์ด-๋ฌด์ด ์๊ณ ๋ฆฌ์ฆ์ ํต์ฌ ๊ฐ๋
์ '์ค๋ฅธ์ชฝ์์ ์ผ์ชฝ์ผ๋ก' ํ์ํ๋ ๊ฒ์ด๋ฉฐ, ์ด๋ ๋๋ถ๋ถ์ ๋ค๋ฅธ ๋ฌธ์์ด ๊ฒ์ ์๊ณ ๋ฆฌ์ฆ๊ณผ๋ ๋ฐ๋ ๋ฐฉํฅ์
๋๋ค. ๋ํ, ์ด ์๊ณ ๋ฆฌ์ฆ์ ๋ถ์ผ์น๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ์ต๋ํ ๋ง์ด ๊ฑด๋๋ฐ๋ ๊ฒ์ ๋ชฉํ๋ก ํ๋ฉฐ, ์ด๋ฅผ ํตํด ๊ฒ์ ์๋๋ฅผ ๋์
๋๋ค.
์ด ์๊ณ ๋ฆฌ์ฆ์ ๋ ๊ฐ์ง ์ฃผ์ ํด๋ฆฌ์คํฑ, ์ฆ '๋์ ๋ฌธ์ ํด๋ฆฌ์คํฑ'๊ณผ '์ข์ ์ ๋ฏธ์ฌ ํด๋ฆฌ์คํฑ'์ ์ฌ์ฉํฉ๋๋ค.
๋์ ๋ฌธ์ ํด๋ฆฌ์คํฑ: ํจํด์์ ๋ถ์ผ์น๊ฐ ๋ฐ์ํ ๋ฌธ์๊ฐ ํจํด ๋ด์ ์กด์ฌํ์ง ์์ผ๋ฉด ํจํด ์ ์ฒด๋ฅผ ์ค๋ฅธ์ชฝ์ผ๋ก ์ด๋ํฉ๋๋ค. ๋ง์ฝ ํจํด ๋ด์ ์กด์ฌํ๋ค๋ฉด, ๋ถ์ผ์น๊ฐ ๋ฐ์ํ ๋ฌธ์๋ฅผ ํจํด์ ๊ฐ์ฅ ์ค๋ฅธ์ชฝ์ ์๋ ๋์ผํ ๋ฌธ์์ ๋ง์ถ์ด ์ด๋ํฉ๋๋ค.
์ข์ ์ ๋ฏธ์ฌ ํด๋ฆฌ์คํฑ: ํจํด์์ ์ผ์นํ๋ ์ ๋ฏธ์ฌ๊ฐ ๋ฐ๊ฒฌ๋๋ฉด, ์ด ์ ๋ฏธ์ฌ๊ฐ ํจํด ๋ด์์ ๋ค์ ๋ฐ๊ฒฌ๋ ์์น๋ก ํจํด์ ์ด๋ํฉ๋๋ค.
์ด ๋ ๊ฐ์ง ํด๋ฆฌ์คํฑ์ ๊ฒฐํฉ๋์ด ์ฌ์ฉ๋๋ฉฐ, ๋ ์ด๋ ์ค์์ ๋ ๋ฉ๋ฆฌ ์ด๋ํ๋ ์ชฝ์ ์ ํํฉ๋๋ค. ์ด๋ฅผ ํตํด ๋ณด์ด์ด-๋ฌด์ด ์๊ณ ๋ฆฌ์ฆ์ ๋ฌธ์์ด ๊ฒ์ ๊ณผ์ ์ ๋งค์ฐ ๋น ๋ฅด๊ฒ ์ํํ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ ์ด ์๊ณ ๋ฆฌ์ฆ์ด ํจ์จ์ ์ด๊ธฐ ์ํด์๋ ์ ์ฒ๋ฆฌ ๊ณผ์ ์ด ํ์ํฉ๋๋ค. ์ด ์ ์ฒ๋ฆฌ ๊ณผ์ ์์ '๋์ ๋ฌธ์ ํ
์ด๋ธ'๊ณผ '์ข์ ์ ๋ฏธ์ฌ ํ
์ด๋ธ'์ ์์ฑํ๊ณ ์ด๋ฅผ ๋ฐํ์ผ๋ก ๋ฌธ์์ด ๊ฒ์์ ์ํํฉ๋๋ค. ์ด๋ฌํ ์ ์ฒ๋ฆฌ ๊ณผ์ ๋๋ฌธ์ ์งง์ ๋ฌธ์์ด์ด๋ ๋จ์ผ ๊ฒ์์๋ ๋ค๋ฅธ ์๊ณ ๋ฆฌ์ฆ๋ค์ด ๋ ํจ์จ์ ์ผ ์ ์์ต๋๋ค.
In Python
def generate_bad_char_shift(term):
skip_list = {}
for i in range(0, len(term)-1):
skip_list[term[i]] = len(term)-i-1
return skip_list
def search_boyer_moore(text, pattern):
bad_char_shift = generate_bad_char_shift(pattern)
i = 0
while i < len(text)-len(pattern)+1:
j = len(pattern)
while j > 0 and pattern[j-1] == text[i+j-1]:
j -= 1
if j > 0:
bad_char_shift_value = bad_char_shift.get(text[i+j-1], len(pattern))
i += bad_char_shift_value
else:
return i
return -1

ํ๋ ์ฐพ์์ ์๋๋ฐ, ์ด๊ฒ ์ข ์ฌ๋ฌ๊ฐ๋ฅผ ์ฐพ์ผ๋ ค๋ฉด ํจ์๋ฅผ ์์ ํด์ผํ๋ค.
def search_boyer_moore(text, pattern):
bad_char_shift = generate_bad_char_shift(pattern) # ๋์ ๋ฌธ์ ํด๋ฆฌ์คํฑ์ ์ฌ์ฉํ skip_list ์์ฑ
i = 0 # ๊ฒ์ ์์ ์์น
positions = [] # ํจํด์ด ๋ฐ๊ฒฌ๋ ์์น๋ฅผ ์ ์ฅํ ๋ฆฌ์คํธ
while i < len(text)-len(pattern)+1: # ํ
์คํธ๋ฅผ ์ค๋ฅธ์ชฝ์ผ๋ก ์ด๋ํ๋ฉด์
j = len(pattern) # ํจํด์ ๋ง์ง๋ง ๋ฌธ์๋ถํฐ ๋น๊ต ์์
while j > 0 and pattern[j-1] == text[i+j-1]: # ํจํด์ ๋ฌธ์์ ํ
์คํธ์ ๋ฌธ์๊ฐ ์ผ์นํ๋ ๋์
j -= 1 # ํจํด์ ์ผ์ชฝ์ผ๋ก ์ด๋
if j > 0: # ๋ถ์ผ์น ๋ฐ์ ์
# ๋์ ๋ฌธ์ ํด๋ฆฌ์คํฑ์ ๋ฐ๋ผ ํ
์คํธ์ ์ด๋ ๊ฑฐ๋ฆฌ ๊ณ์ฐ
bad_char_shift_value = bad_char_shift.get(text[i+j-1], len(pattern))
i += bad_char_shift_value # ํ
์คํธ๋ฅผ ์ค๋ฅธ์ชฝ์ผ๋ก ์ด๋
else: # ํจํด์ ๋ชจ๋ ๋ฌธ์๊ฐ ์ผ์นํ๋ ๊ฒฝ์ฐ
positions.append(i) # ํ์ฌ ์์น๋ฅผ ๋ฆฌ์คํธ์ ์ถ๊ฐ
i += 1 # ๋ค์ ์์น๋ก ์ด๋
return positions # ๋ชจ๋ ์์น ๋ฐํ

์ด๋ฐ์์ผ๋ก ๋ณด์ด์ด-๋ฌด์ด ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๋ฌธ์์ด์ ์ฐพ์์ ์๋ค.
Appendix
๋ณด์ด์ด-๋ฌด์ด ์๊ณ ๋ฆฌ์ฆ์ ๋ฌธ์์ด ํ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐ ํ์ฉ๋ฉ๋๋ค. ํนํ, ๊ธด ํ ์คํธ์์ ์งง์ ํจํด์ ์ฐพ๋ ๊ฒฝ์ฐ์ ํจ์จ์ ์ ๋๋ค. ์ด๋ ๋ณด์ด์ด-๋ฌด์ด ์๊ณ ๋ฆฌ์ฆ์ด ๋ถ์ผ์น๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ๊ฐ๋ฅํ ํ ๋ง์ด ๊ฑด๋๋ฐ์ด ํ์ ์๋๋ฅผ ๋์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
KMP ๋ ๋น๊ตํ๋ค๋ฉด.
๋ฐฉํฅ์ฑ
- KMP ์๊ณ ๋ฆฌ์ฆ์ ํ ์คํธ๋ฅผ ์ผ์ชฝ์์ ์ค๋ฅธ์ชฝ์ผ๋ก ์ค์บํฉ๋๋ค.
- ๋ณด์ด์ด-๋ฌด์ด ์๊ณ ๋ฆฌ์ฆ์ ์ค๋ฅธ์ชฝ์์ ์ผ์ชฝ์ผ๋ก ์ค์บํฉ๋๋ค.
ํจ์จ์ฑ
๋ณด์ด์ด-๋ฌด์ด ์๊ณ ๋ฆฌ์ฆ์ ์ผ๋ฐ์ ์ผ๋ก KMP ์๊ณ ๋ฆฌ์ฆ๋ณด๋ค ๋ ๋น ๋ฅด๋ฉฐ, ํนํ ๋์ ํ ์คํธ๊ฐ ์์ฃผ ํด ๋ ๋์ฑ ํจ์จ์ ์ ๋๋ค. ์ด๋ ๋ณด์ด์ด-๋ฌด์ด ์๊ณ ๋ฆฌ์ฆ์ด ๋ถ์ผ์น๋ฅผ ๋ฐ๊ฒฌํ๋ฉด ์ต๋ํ ๋ง์ด ๊ฑด๋๋ฐ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ฐ๋ฉด, KMP ์๊ณ ๋ฆฌ์ฆ์ ํ ์คํธ๋ฅผ ํ ๋ฒ๋ง ํต๊ณผํ๋ฉฐ, ํจํด์ ๋ํ ๋ถ๋ถ์ ์ธ ์ผ์น๋ฅผ ํ์ฉํ๊ธฐ ๋๋ฌธ์ ๋ถํ์ํ ๋น๊ต๋ฅผ ์ต์ํํฉ๋๋ค.
์ ์ฒ๋ฆฌ
๋ ์๊ณ ๋ฆฌ์ฆ ๋ชจ๋ ํจํด์ ์ ์ฒ๋ฆฌํ๋ ๋จ๊ณ๋ฅผ ํฌํจํฉ๋๋ค. KMP ์๊ณ ๋ฆฌ์ฆ์ ํจํด์ ์ ๋์ฌ์ ์ ๋ฏธ์ฌ๊ฐ ์ผ์นํ๋ ๊ธธ์ด๋ฅผ ๊ณ์ฐํ๋ ์ ์ฒ๋ฆฌ ํ ์ด๋ธ์ ๋ง๋ญ๋๋ค. ๋ฐ๋ฉด์ ๋ณด์ด์ด-๋ฌด์ด ์๊ณ ๋ฆฌ์ฆ์ '๋์ ๋ฌธ์ ํด๋ฆฌ์คํฑ'๊ณผ '์ข์ ์ ๋ฏธ์ฌ ํด๋ฆฌ์คํฑ'์ ์ด์ฉํ ์ ์ฒ๋ฆฌ ํ ์ด๋ธ์ ๋ง๋ญ๋๋ค.
'CS - Roadmap.sh > 4. String Search and Manipulations' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
4.6 Rabin-Karpโs algorithm(๋ผ๋น-์นดํ ์๊ณ ๋ฆฌ์ฆ) (0) | 2024.02.22 |
---|---|
4.4. Knuth Morris Pratt (KMP ์๊ณ ๋ฆฌ์ฆ) (2) | 2024.02.20 |
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 |