๊ฒ์๊ธ ์ญ์
์ ๋ง ์ญ์ ํ์๊ฒ ์ต๋๊น?
๐ฅ๋๋ผ๋ง๋ก ๋ณด๋ ์ฝ๋ฉ #1 - ๐ฑ๋ฌธ์์ด ์ฐพ๊ธฐ ์๊ณ ๋ฆฌ์ฆ
[์ฃผ์ ๋ชฉ์ฐจ]
๋ฌธ์์ด ์ฐพ๊ธฐ ์๊ณ ๋ฆฌ์ฆ์ ๋งค๋ ฅ
Brute Force: ๊ฐ๋จํ์ง๋ง ๋๋ฆฐ ๋ฐฉ๋ฒ
KMP ์๊ณ ๋ฆฌ์ฆ: ์ค๋งํธํ๊ฒ ๋ฌธ์์ด ์ฐพ๊ธฐ
์ฝ๋ฉ์ ์ฒ์ ์์ํ์๋ ๋ถ๋ค, ์๊ณ ๋ฆฌ์ฆ ๊ณต๋ถ๊ฐ ์ข ์ด๋ ต๊ฒ ๋๊ปด์ง์๋์? ํ๊ต๋ ์ฑ ์์ ๋ฐฐ์ด ์ด๋ก ์ด ์ค์ ๋ฌธ์ ์ ์ ์ฉ๋ ๋, ๋ง๋งํจ์ด ๋ค ๋๊ฐ ๋ง์์. ํนํ ๋ฌธ์์ด ์ฐพ๊ธฐ ์๊ณ ๋ฆฌ์ฆ์ฒ๋ผ ์ผ์์์ ์์ฃผ ์ฐ์ด๋ ๊ฑธ ์ฒ์ ์ ํ๋ฉด, "์ด๊ฒ ์ ํ์ํ ๊น?" ์ถ์ผ์ค ๊ฑฐ์์. ๊ทธ๋ฐ๋ฐ ์ด ์๊ณ ๋ฆฌ์ฆ์ PDF ๊ฒ์ ๊ธฐ๋ฅ๋ถํฐ DNA ๋ถ์, ์ฌ์ง์ด ๊ฒ์ ์์ง์ ํต์ฌ๊น์ง ์ฐ๊ฒฐ๋๋, ์ ๋๋ก ์ดํดํ๋ฉด ์ฝ๋ฉ ์ค๋ ฅ์ด ์ฅ์ฅ ์ฌ๋ผ๊ฐ ๊ฑฐ์์. ์ด ๊ธ์ ์ ํ๋ธ ์์ "๋๋ผ๋ง๋ก ๋ณด๋ ์ฝ๋ฉ #1 - ๋ฌธ์์ด ์ฐพ๊ธฐ ์๊ณ ๋ฆฌ์ฆ"์ ๊ธฐ๋ฐ์ผ๋ก, ์์์ ์ ๋ณด์ ๋ถ๋ค๋ ์๋ฒฝํ ๋ฐ๋ผ์ฌ ์ ์๊ฒ ์ฌ๊ตฌ์ฑํ์ด์. ๋๋ผ๋ง์ฒ๋ผ ์ฌ๋ฏธ์๊ฒ ํ์ด๋ธ ์์์ ํต์ฌ์ ์ด๋ณด์ ๋๋์ด์ ๋ง์ถฐ ์ค๋ช ํ๊ณ , ๋ฐฐ๊ฒฝ ์ง์๊ณผ ์ค์ ํ๊น์ง ๋ํ์ด์. ๋ฌธ์์ด ์ฐพ๊ธฐ ์๊ณ ๋ฆฌ์ฆ์ ๋ฐฐ์ฐ๋ฉด, ๋จ์ํ ์ฝ๋๋ฅผ ์ง๋ ๊ฒ ์๋๋ผ ํจ์จ์ ์ผ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๊ฐ๊ฐ์ด ์๊ธธ ๊ฑฐ์์. ์๋ฅผ ๋ค์ด, ๊ธด ํ ์คํธ์์ ํน์ ๋จ์ด๋ฅผ ๋น ๋ฅด๊ฒ ์ฐพ๋ ๋ฒ์ ์๊ฒ ๋๋, ํ๋ก๊ทธ๋๋ฐ ํ๋ก์ ํธ์์ ์๊ฐ๊ณผ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์๋ ์ ์์ด์. ์์์ฒ๋ผ ์ฌ๋ฏธ์๋ ๋น์ ๋ฅผ ๋ํด ์ค๋ช ํ ํ ๋, ๋ถ๋ด ์์ด ๋ฐ๋ผ์ ๋ณด์ธ์. ์ด ๊ธ์ ๋๊น์ง ์ฝ์ผ๋ฉด, ๋ฌธ์์ด ์ฐพ๊ธฐ ์๊ณ ๋ฆฌ์ฆ์ ๊ธฐ๋ณธ๋ถํฐ ๊ณ ๊ธ KMP ๊ธฐ๋ฒ๊น์ง ์ดํดํ๊ณ , ๋ฐ๋ก ์ฝ๋ฉ์ผ๋ก ํ ์คํธํ ์ ์์ ๊ฑฐ์์. ์ฝ๋ฉ ์ด๋ณด์ ์ฌ๋ฌ๋ถ, ํจ๊ป ์ฌ๋ฏธ์๊ฒ ํํํด ๋ณผ๊น์? ๋ฌธ์์ด ์ฐพ๊ธฐ ์๊ณ ๋ฆฌ์ฆ ํ๋๋ก ์ฝ๋ฉ ์ธ๊ณ๊ฐ ๋ ๋์ด์ง ํ ๋, ๊ธฐ๋ํ์ธ์!

๋ฌธ์์ด ์ฐพ๊ธฐ ์๊ณ ๋ฆฌ์ฆ์ ๋งค๋ ฅ
์ฝ๋ฉ์ ๊ณต๋ถํ๋ค ๋ณด๋ฉด, ์๊ณ ๋ฆฌ์ฆ์ด๋ผ๋ ๋จ์ด๊ฐ ์ข ๋ฌด์ญ๊ฒ ๋๊ปด์ง ์ ์์ด์. ๊ทธ๋ฐ๋ฐ ๋ฌธ์์ด ์ฐพ๊ธฐ ์๊ณ ๋ฆฌ์ฆ์ ์ ๋ง ์ค์ํ๊ณผ ๊ฐ๊น์์, ์ด๋ณด์๋ถ๋ค๋ ๊ธ๋ฐฉ ํฅ๋ฏธ๋ฅผ ๊ฐ์ง ๊ฑฐ์์. ์ฝ๊ฒ ๋งํ๋ฉด, ๊ธด ๋ฌธ์ฅ์ด๋ ํ ์คํธ ์์์ ํน์ ๋จ์ด๋ ํจํด์ ์ฐพ์๋ด๋ ๊ฑฐ์์. ์์์์์ฒ๋ผ "ํด๋น ๋ฌธ์ฅ์์ 'ํ๋ฒ'์ด๋ผ๋ ๋จ์ด๋ฅผ ๋ชจ๋ ์ฐพ์๋ผ" ๊ฐ์ ๋ฌธ์ ๊ฐ ๋์ค๋ฉด, PDF ํ์ผ์์ Ctrl+F๋ก ๊ฒ์ํ๋ ๊ธฐ๋ฅ์ด ๋ ์ค๋ฅด์์ฃ ? ์ด๊ฒ ๋ฐ๋ก ๋ฌธ์์ด ์ฐพ๊ธฐ ์๊ณ ๋ฆฌ์ฆ์ ๊ธฐ๋ณธ์ด์์.
๋จผ์ , ์ ์ด ์๊ณ ๋ฆฌ์ฆ์ด ์ค์ํ์ง ์์๋ณผ๊ฒ์. ์์ํด ๋ณด์ธ์. ์ฌ๋ฌ๋ถ์ด DNA ์ฐ๊ตฌ์๋ฅผ ์ด์ํ๋ค๋ฉด, ์์ต ๊ฐ์ ์ผ๊ธฐ์์ด(A, T, G, C) ์ค ํน์ ์ ์ ์๋ฅผ ์ฐพ์์ผ ํด์. ๋จ์ํ ๋์ผ๋ก ํ๋ ๊ฑด ๋ถ๊ฐ๋ฅํ๋, ์ปดํจํฐ๊ฐ ํจ์จ์ ์ผ๋ก ๊ฒ์ํด์ผ ํ์ฃ . ์ค์ ๋ก ๊ตฌ๊ธ ๊ฒ์ ์์ง์ด๋ ๋ฐ์ด์ค ์ธํฌ๋งคํฑ์ค์์ ์ด ์๊ณ ๋ฆฌ์ฆ์ ์จ์. ์ด๋ณด์๋ถ๋ค์ ์ํด ์ค๋ช ๋๋ฆฌ๋ฉด, ๋ฌธ์์ด์ ๊ทธ๋ฅ ๋ฌธ์๋ค์ ๋ฐฐ์ด(์: "hello world"๋ h-e-l-l-o- -w-o-r-l-d)๋ก ๋ณด์๋ฉด ๋ผ์. ์ฐพ์ ํจํด์ "hello"์ฒ๋ผ ์งง์ ๋ถ๋ถ์ด์์.
์ด ๋ฌธ์ ์ ๋งค๋ ฅ์ ๋ํ๋ ๊ฑด, ๋ค์ํ ๋์ด๋์์. ์์์์ ๋๋ผ๋ง์ฒ๋ผ "์, ๋ค๋ฒผ๋ผ!" ํ๋ฉฐ ๋์ ํ๋ ์ฅ๋ฉด์ด ๋์ค๋๋ฐ, ์ค์ ์ฝ๋ฉ ์ธํฐ๋ทฐ๋ ์ฝํ (์ฝ๋ฉ ํ ์คํธ)์์ ์์ฃผ ๋์์. ์๋ฅผ ๋ค์ด, "ababcabcabababd"๋ผ๋ ๋ฌธ์์ด์์ "abab" ํจํด์ ์ฐพ๋๋ค๋ฉด, ์์น 0, 2, 6์์ ๋งค์น๋ผ์. ์ด๊ฑธ ์๋์ผ๋ก ํ๋ฉด ํผ๊ณคํ์ง๋ง, ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ํ๋ฉด ์ปดํจํฐ๊ฐ ์์๊ฐ์ ํด์ค์. ๋ฐฐ๊ฒฝ ์ง์์ผ๋ก, ์ด ๊ฐ๋ ์ 1970๋ ๋๋ถํฐ ์ฐ๊ตฌ๋์ด์. ์ปดํจํฐ ๊ณผํ์ ๊ณ ์ ๋ฌธ์ ๋ผ์, ๋ฐฐ์ฐ๋ฉด ์๋ถ์ฌ์ด ์๊ธธ ๊ฑฐ์์.
์ด์ ๊ธฐ๋ณธ ์์๋ฅผ ๋ค์ด๋ณผ๊ฒ์. ๋ฌธ์ฅ: "์ ๋ง ์ฌ๋ฏธ์๋ ์ฝ๋ฉ ์ธ๊ณ์์." ํจํด: "์ฌ๋ฏธ". ์ด๊ฑธ ์ฐพ๋๋ค๋ฉด, "์ฌ๋ฏธ์๋" ๋ถ๋ถ์์ ๋งค์น๋ผ์. ์ด๋ณด์ ํ์ผ๋ก, ํ์ด์ฌ์์ str.find() ๋ฉ์๋๋ฅผ ์จ๋ณด์ธ์. ์ฝ๋: text = "์ ๋ง ์ฌ๋ฏธ์๋ ์ฝ๋ฉ ์ธ๊ณ์์"; pattern = "์ฌ๋ฏธ"; position = text.find(pattern); print(position) โ ๊ฒฐ๊ณผ๋ 3(0๋ถํฐ ์ธ๋ฉด)์ด ๋์์. ์ด๊ฑธ ์คํํด ๋ณด์๋ฉด ๋ฐ๋ก ๋๊ปด์ง ๊ฑฐ์์. ํ์ง๋ง ์ด๊ฑด ๋ด์ฅ ํจ์๋ผ์, ์ง์ ๊ตฌํํด์ผ ํ ๋๊ฐ ๋ง์์. ์ ์ง์ ์ง์ผ ํ๋๋ฉด, ์ฝํ ์์ "O(nm) ์๊ฐ ๋ณต์ก๋"๋ฅผ ์๊ตฌํ๊ฑฐ๋ ์. n์ ๋ฌธ์ฅ ๊ธธ์ด, m์ ํจํด ๊ธธ์ด์์. brute force๋ nm ๋น๊ต๋ฅผ ํ๋, n=100๋ง, m=100์ด๋ฉด 1์ต ๋ฒ ๋น๊ต โ ๋๋ ค์!
๋น๊ตํด ๋ณด์๋ฉด, ๋จ์ ๊ฒ์ vs. ์๊ณ ๋ฆฌ์ฆ: ๋จ์์ ๋งค๋ฒ ์ฒ์๋ถํฐ ๋น๊ตํ์ง๋ง, ์ค๋งํธํ ๊ฑด ๋ถํ์ํ ๋น๊ต๋ฅผ ๊ฑด๋๋ฐ์ด์. ์์น๋ก ๋ณด๋ฉด, 1MB ํ ์คํธ์์ ํจํด ์ฐพ์ ๋ brute force๋ 1์ด ๊ฑธ๋ฆด ์ ์์ง๋ง, ๊ณ ๊ธ ์๊ณ ๋ฆฌ์ฆ์ 0.1์ด๋ก ์ค์ด์. ์ค์ ํ: VS Code์์ ์ ํ์ผ ๋ง๋ค์ด ์ ์ฝ๋ ์ ๋ ฅํ๊ณ F5 ๋๋ฅด์ธ์. ์๋ฌ ๋๋ฉด print("Hello")๋ถํฐ ํ ์คํธํด ๋ณด์ธ์. ์ด ์น์ ์์ ์ป๋ ๊ฑด, ๋ฌธ์์ด ์ฐพ๊ธฐ ์๊ณ ๋ฆฌ์ฆ์ด ์ฝ๋ฉ์ ๋ฌธ์ ์ฌ๋ ํค๋ผ๋ ๊ฑฐ์์. ๋ค์์ผ๋ก, ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ brute force ๋ฐฉ๋ฒ์ ์์ธํ ํ๋ณด์ฃ . ์ด๊ฑธ ์๋ฉด ๊ณ ๊ธ ๊ธฐ๋ฒ์ด ์ ํ์ํ์ง ์ดํด๊ฐ ์ ๋ ๊ฑฐ์์.

Brute Force: ๊ฐ๋จํ์ง๋ง ๋๋ฆฐ ๋ฐฉ๋ฒ
Brute force, ํ๊ตญ์ด๋ก "๋ฌด์ํ ํ" ๋ฐฉ๋ฒ์ด๋ผ๊ณ ํด์. ์์์์ "ํ ์นธ์ฉ ์ด๋ํ๋ฉฐ ๋น๊ต"ํ๋ ์ฅ๋ฉด์ฒ๋ผ, ์ง๊ด์ ์ด์์. ์ด๋ณด์๋ถ๋ค์ ์ํด ์ค๋ช ๋๋ฆฌ๋ฉด, ๋ฌธ์ฅ์ ๋ฐฐ์ด๋ก ๋ณด๊ณ , ํจํด์ ์์ ์์น๋ฅผ 0๋ถํฐ n-m+1๊น์ง ํ๋์ฉ ์ฎ๊ธฐ๋ฉด์ ๋งค๋ฒ ๋ชจ๋ ๋ฌธ์๋ฅผ ๋น๊ตํ๋ ๊ฑฐ์์. ์: ๋ฌธ์ฅ "abcde", ํจํด "bc"๋ผ๋ฉด, ์์น 0: a==b? No. ์์น 1: b==b, c==c Yes. ์์น 2: c==b? No. ์ด๋ ๊ฒ์.
์ด ๋ฐฉ๋ฒ์ ์ฅ์ ์ ๊ตฌํ์ด ์ฝ๋ค๋ ๊ฑฐ์์. ์ฝ๋๋ก ๋ณด์๋ฉด, for i in range(len(text) - len(pattern) + 1): if text[i:i+len(pattern)] == pattern: print(i). ํ์ด์ฌ์์ ๋ฐ๋ก ์จ๋ณด์ธ์. ์์์ฒ๋ผ "์ฌ๊ธฐ์ ํ๋ฒ, ์ ๊ธฐ์ ํ๋ฒ" ํ๋ฉฐ ๋ชจ๋ ๊ฐ๋ฅ์ฑ์ ์ฒดํฌํ๋, ๋์น๋ ๊ฒ ์์ด์. ํ์ง๋ง ๋จ์ ๋ ์ปค์. ๋น๊ต ํ์๊ฐ n*m์ด๋ผ, ํฐ ๋ฐ์ดํฐ์์ ๋๋ ค์. ์๋ฅผ ๋ค์ด, 1000์ ๋ฌธ์ฅ๊ณผ 10์ ํจํด์ด๋ฉด ์ต๋ 9990๋ฒ ๋น๊ต โ ๊ด์ฐฎ์ง๋ง, 1์ต ์๋ฉด ํญ๋ฐํด์.
๊ฐ์ ์์ด๋์ด๋ฅผ ๋ํด ๋ณผ๊ฒ์. ์์์์ ASCII ์ฝ๋๋ก ์ซ์ ๋ณํํด ํฉ์ ๋ฏธ๋ฆฌ ๊ณ์ฐํ๋ ํ์ด ๋์์. ์ฝ๊ฒ ๋งํ๋ฉด, ํจํด "abc"๋ a=97, b=98, c=99๋ก ํฉ 294์์. ๋ฌธ์ฅ์ 3์ ์ฌ๋ผ์ด๋ฉ ์๋์ฐ ํฉ์ด 294๊ฐ ์๋๋ฉด ์คํต! ์ด๊ฑด ํด์ฑ(rabin-karp ์คํ์ผ)์ ๊ธฐ๋ณธ์ด์์. ์์น ๋น๊ต: brute force 100% ๋น๊ต vs. ํด์ฑ 10%๋ง ๋น๊ต โ 10๋ฐฐ ๋นจ๋ผ์. ์ค์ ์์: "banana"์์ "ana" ์ฐพ๊ธฐ. ์์น 1: b-a-n sum=98+97+110=305 != a+n+a=97+110+97=304 No. ์์น 2: a-n-a=304 Yes.
์ค์ ํ: ์ด๊ฑธ C++๋ก ๊ตฌํํด ๋ณด์ธ์. string text = "banana"; string pat = "ana"; for(int i=0; i<=text.size()-pat.size(); i++) { bool match=true; for(int j=0; j<pat.size(); j++) if(text[i+j]!=pat[j]) {match=false; break;} if(match) cout<<i; } ์ปดํ์ผ ํ ์คํํ๋ฉด ์์น 1,3 ์ถ๋ ฅ๋ผ์. ์ฃผ์: ์ค๋ฒํ๋ก์ฐ ํผํ์ธ์. ๋์์ผ๋ก, ์๋ฐ์ String.indexOf() ์จ๋ณด์ง๋ง, ์ง์ ์ง๋ ๊ฒ ํ์ต์ด์์. ์ ์ค์ํ๊ฐ? ์ด ๋ฐฉ๋ฒ ์๋ฉด, ์ ํจ์จ์ด ํ์ํ ์ง ๊นจ๋ฌ์์. ์์์์ "๋๋ฌด ์ฝ๋ค" ํ๋ฏ, ๊ณผ์ํ๊ฐ ๋ง๊ณ ํ ์คํธํด ๋ณด์ธ์. ๋ค์ ์น์ ์์ KMP๋ก ์ ๊ทธ๋ ์ด๋ํ ๊ฒ์.

KMP ์๊ณ ๋ฆฌ์ฆ: ์ค๋งํธํ๊ฒ ๋ฌธ์์ด ์ฐพ๊ธฐ
KMP(Knuth-Morris-Pratt) ์๊ณ ๋ฆฌ์ฆ์ ๋ฌธ์์ด ์ฐพ๊ธฐ์ ๊ณ ๊ธ ๋ฒ์ ์ด์์. ์์์์ "์ ๋ฏธ์ฌ ๋ถ์์ผ๋ก ์ ํ"ํ๋ ๋ถ๋ถ์ฒ๋ผ, ํจํด์ ์ค๋ณต์ ์ด์ฉํด ๋ถํ์ํ ๋ฐฑํธ๋ํน์ ํผํด์. ์ด๋ณด์๋ถ๋ค์ ์ํด ์ค๋ช ๋๋ฆฌ๋ฉด, ํจํด "abab"์ prefix table(๋ถ๋ถ ์ผ์น ํ ์ด๋ธ)์ ๋ฏธ๋ฆฌ ๋ง๋ค์ด์. ์: a b a b โ ์์น 0: '', 1: a (์ ๋์ฌ a์ ์ ๋ฏธ์ฌ a ๋งค์น, ๊ฐ 1? ์๋, ํ ์ด๋ธ [0,0,1,2]).
ํ ์ด๋ธ ๋ง๋๋ ๋ฒ: ํจํด ๊ธธ์ด m๋งํผ ๋ฐฐ์ด pi[0..m-1], pi[0]=0. i=1๋ถํฐ, len=0 ์์. ํจํด[i]==ํจํด[len]์ด๋ฉด len++, pi[i]=len. ์๋๋ฉด len=pi[len-1]๋ก ๋ฐฑํธ๋. "abab" ์: i=1 b!=a, len=0, pi[1]=0. i=2 a==a (len=0->1), pi[2]=1. i=3 b==b (len=1->2), pi[3]=2. ์ด ํ ์ด๋ธ๋ก ๊ฒ์ ์, ๋งค์น ์คํจํด๋ pi[j-1]๋งํผ ์ ํํด์. ์๊ฐ ๋ณต์ก๋ O(n+m) โ brute์ O(n*m)๋ณด๋ค ํจ์ฌ ๋นจ๋ผ์!
์์: ํ ์คํธ "ababababc", ํจํด "abab". ํ ์ด๋ธ [0,0,1,2]. ๊ฒ์: i=0~3 ๋งค์น, ์์น 0. ์คํจ ์ j=pi[3]=2๋ถํฐ ์ฌ์์ โ "ab"๋ถํฐ. ์์น 2: abab ๋งค์น. ์์น 4: abab ๋งค์น. ์์น 6: c ์คํจ. ์ด ๋น๊ต ์ ์ด์. ์์น: n=100๋ง, m=1000 brute 10์ต vs KMP 100๋ง1์ฒ โ 1000๋ฐฐ ์ฐจ์ด!
์ค์ ํ: ํ์ด์ฌ ๊ตฌํ. def compute_pi(pat): m=len(pat); pi=[0]*m; j=0; for i in range(1,m): while j>0 and pat[i]!=pat[j]: j=pi[j-1]; if pat[i]==pat[j]: j+=1; pi[i]=j; return pi. ๊ฒ์: def kmp(text, pat): pi=compute_pi(pat); n=len(text); m=len(pat); j=0; for i in range(n): while j>0 and text[i]!=pat[j]: j=pi[j-1]; if text[i]==pat[j]: j+=1; if j==m: print(i-m+1); j=pi[j-1]. "ababcabcabababd"์์ "abab" ํ๋ฉด 0,2,6 ์ถ๋ ฅ. ์ฃผ์: ํ ์ด๋ธ ์ค๋ฅ ์ ๋๋ฒ๊น ์ผ๋ก print(j) ์ถ๊ฐ. ๋์: Boyer-Moore (์ญ๋ฐฉํฅ ๊ฒ์, ๋ ๋น ๋ฅผ ์ ์์). ์ KMP? ๋์ฉ๋ ๋ฐ์ดํฐ(๋ก๊ทธ ํ์ผ ๋ถ์)์์ ํ์์์. ์์์ฒ๋ผ "O(n+m)" ์๋๋ก ๋ง์คํฐํ์ธ์!
[์์ฃผ ๋ฌป๋ ์ง๋ฌธ]
๋ฌธ์์ด ์ฐพ๊ธฐ ์๊ณ ๋ฆฌ์ฆ ์ด๋ณด์๊ฐ ๊ตฌํํ ๋ ๊ฐ์ฅ ํํ ์ค์๋ ๋ญ์์?
์ด๋ณด์๋ถ๋ค์ด ์์ฃผ ํ๋ ์ค์๋ ์ธ๋ฑ์ค ๋ฒ์๋ฅผ ๋๋ ๋ฒ๊ทธ์์. ์๋ฅผ ๋ค์ด, brute force์์ i + m > n ๋๋ฉด ํฌ๋์ ๋์ฃ . ํ์ผ๋ก, range(len(text) - len(pattern) + 1)์ฒ๋ผ ์กฐ์ฌํ์ธ์. KMP ํ ์ด๋ธ ๋ง๋ค ๋ while ๋ฃจํ๊ฐ ๋ฌดํ๋ ์ ์์ผ๋, j>0 ์กฐ๊ฑด ํ์ธํด์. ์ค์ ๋ก ํ ์คํธํ ๋ ์์ ๋ฌธ์์ด "aa" ํจํด์ผ๋ก ๋๋ฒ๊น ํ๋ฉด ์ข์์. ์ด ์ค์ ํผํ๋ฉด ์ฝ๋๊ฐ ์์ ์ ์ผ ๊ฑฐ์์. ์ฐ์ต์ผ๋ก LeetCode 28 ๋ฌธ์ ํ์ด๋ณด์ธ์ โ ๊ตฌํ๋ ฅ ์ฅ!
KMP ์๊ณ ๋ฆฌ์ฆ ๋์ ๋ค๋ฅธ ๋ฌธ์์ด ์ฐพ๊ธฐ ๋ฐฉ๋ฒ์ ๋ญ๊ฐ ์์ด์?
KMP ์ธ์ Rabin-Karp ํด์ฑ์ด ์ธ๊ธฐ์์. ํจํด๊ณผ ํ ์คํธ๋ฅผ ์ซ์๋ก ๋ณํํด ํด์ ๊ฐ ๋น๊ต โ ์ถฉ๋ ์ ์ผ๋ฉด O(n) ์๊ฐ์ด์์. ์: MOD 10^9+7 ์จ์ ์ค๋ฒํ๋ก์ฐ ํผํ์ธ์. Boyer-Moore๋ ํจํด ๋ ๋ฌธ์๋ถํฐ ๋น๊ตํด ๋ ๋น ๋ฅผ ์ ์์ด์. ์ ํ ํ: ์์ m์ KMP, ํฐ ๋ฐ์ดํฐ์ ํด์ฑ. ํ์ด์ฌ re ๋ชจ๋(์ ๊ท์)๋ ๋์์ด์ง๋ง, ํ์ต์ ์ง์ ๊ตฌํ์ด ์ข์์. ์์์ฒ๋ผ ํจ์จ ์ค์ํ๋ฉด KMP๋ถํฐ ๋ง์คํฐํ์ธ์.
๋ฌธ์์ด ์ฐพ๊ธฐ ์๊ณ ๋ฆฌ์ฆ์ ์ค๋ฌด์์ ์ด๋ป๊ฒ ์จ์?
์ค๋ฌด์์ ๊ฒ์ ์์ง, ์คํ ๊ฒ์ฌ, ๋ฐ์ด์ค ๋ฐ์ดํฐ ๋ถ์์ ์จ์. ์: ๋ก๊ทธ ํ์ผ์์ ์๋ฌ ํจํด ์ฐพ์ ๋ KMP๋ก 1TB ๋ฐ์ดํฐ 1๋ถ ๋ง ์ฒ๋ฆฌ. ํ: Java์ StringBuilder๋ C++ std::search ์จ๋ณด์ธ์. ์ด๋ณด์๋ผ๋ฉด, GitHub์ ์คํ์์ค ๊ฒ์ ๋๊ตฌ ํฌํฌํด ์์ ์ฐ์ต. ์ฃผ์: ์ ๋์ฝ๋(ํ๊ธ) ์ง์ ํ์ธ โ ASCII๋ง ์๋์์. ์ด๊ฑธ ์๋ฉด ํฌํธํด๋ฆฌ์ค์ ๋ฃ์ด ์ทจ์ ์ ๋ฆฌํ ๊ฑฐ์์. ์ฝํ ์์ ์์ฃผ ๋์ค๋, ๋งค์ผ 1๋ฌธ์ ํ๊ธฐ!