๐ŸŽฅ๋“œ๋ผ๋งˆ๋กœ ๋ณด๋Š” ์ฝ”๋”ฉ #1 - ๐Ÿฑ๋ฌธ์ž์—ด ์ฐพ๊ธฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜

| | ์กฐํšŒ 73


[์ฃผ์š” ๋ชฉ์ฐจ]

๋ฌธ์ž์—ด ์ฐพ๊ธฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๋งค๋ ฅ

Brute Force: ๊ฐ„๋‹จํ•˜์ง€๋งŒ ๋А๋ฆฐ ๋ฐฉ๋ฒ•

KMP ์•Œ๊ณ ๋ฆฌ์ฆ˜: ์Šค๋งˆํŠธํ•˜๊ฒŒ ๋ฌธ์ž์—ด ์ฐพ๊ธฐ


์ฝ”๋”ฉ์„ ์ฒ˜์Œ ์‹œ์ž‘ํ•˜์‹œ๋Š” ๋ถ„๋“ค, ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ณต๋ถ€๊ฐ€ ์ข€ ์–ด๋ ต๊ฒŒ ๋А๊ปด์ง€์‹œ๋‚˜์š”? ํ•™๊ต๋‚˜ ์ฑ…์—์„œ ๋ฐฐ์šด ์ด๋ก ์ด ์‹ค์ œ ๋ฌธ์ œ์— ์ ์šฉ๋  ๋•Œ, ๋ง‰๋ง‰ํ•จ์ด ๋“ค ๋•Œ๊ฐ€ ๋งŽ์•„์š”. ํŠนํžˆ ๋ฌธ์ž์—ด ์ฐพ๊ธฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ฒ˜๋Ÿผ ์ผ์ƒ์—์„œ ์ž์ฃผ ์“ฐ์ด๋Š” ๊ฑธ ์ฒ˜์Œ ์ ‘ํ•˜๋ฉด, "์ด๊ฒŒ ์™œ ํ•„์š”ํ• ๊นŒ?" ์‹ถ์œผ์‹ค ๊ฑฐ์˜ˆ์š”. ๊ทธ๋Ÿฐ๋ฐ ์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ PDF ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ๋ถ€ํ„ฐ DNA ๋ถ„์„, ์‹ฌ์ง€์–ด ๊ฒ€์ƒ‰ ์—”์ง„์˜ ํ•ต์‹ฌ๊นŒ์ง€ ์—ฐ๊ฒฐ๋˜๋‹ˆ, ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜๋ฉด ์ฝ”๋”ฉ ์‹ค๋ ฅ์ด ์‘ฅ์‘ฅ ์˜ฌ๋ผ๊ฐˆ ๊ฑฐ์˜ˆ์š”. ์ด ๊ธ€์€ ์œ ํŠœ๋ธŒ ์˜์ƒ "๋“œ๋ผ๋งˆ๋กœ ๋ณด๋Š” ์ฝ”๋”ฉ #1 - ๋ฌธ์ž์—ด ์ฐพ๊ธฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜"์„ ๊ธฐ๋ฐ˜์œผ๋กœ, ์˜์ƒ์„ ์•ˆ ๋ณด์‹  ๋ถ„๋“ค๋„ ์™„๋ฒฝํžˆ ๋”ฐ๋ผ์˜ฌ ์ˆ˜ ์žˆ๊ฒŒ ์žฌ๊ตฌ์„ฑํ–ˆ์–ด์š”. ๋“œ๋ผ๋งˆ์ฒ˜๋Ÿผ ์žฌ๋ฏธ์žˆ๊ฒŒ ํ’€์–ด๋‚ธ ์˜์ƒ์˜ ํ•ต์‹ฌ์„ ์ดˆ๋ณด์ž ๋ˆˆ๋†’์ด์— ๋งž์ถฐ ์„ค๋ช…ํ•˜๊ณ , ๋ฐฐ๊ฒฝ ์ง€์‹๊ณผ ์‹ค์ „ ํŒ๊นŒ์ง€ ๋”ํ–ˆ์–ด์š”. ๋ฌธ์ž์—ด ์ฐพ๊ธฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋ฐฐ์šฐ๋ฉด, ๋‹จ์ˆœํžˆ ์ฝ”๋“œ๋ฅผ ์งœ๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ํšจ์œจ์ ์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฐ๊ฐ์ด ์ƒ๊ธธ ๊ฑฐ์˜ˆ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ธด ํ…์ŠคํŠธ์—์„œ ํŠน์ • ๋‹จ์–ด๋ฅผ ๋น ๋ฅด๊ฒŒ ์ฐพ๋Š” ๋ฒ•์„ ์•Œ๊ฒŒ ๋˜๋‹ˆ, ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ”„๋กœ์ ํŠธ์—์„œ ์‹œ๊ฐ„๊ณผ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์•„๋‚„ ์ˆ˜ ์žˆ์–ด์š”. ์˜์ƒ์ฒ˜๋Ÿผ ์žฌ๋ฏธ์žˆ๋Š” ๋น„์œ ๋ฅผ ๋”ํ•ด ์„ค๋ช…ํ•  ํ…Œ๋‹ˆ, ๋ถ€๋‹ด ์—†์ด ๋”ฐ๋ผ์™€ ๋ณด์„ธ์š”. ์ด ๊ธ€์„ ๋๊นŒ์ง€ ์ฝ์œผ๋ฉด, ๋ฌธ์ž์—ด ์ฐพ๊ธฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ธฐ๋ณธ๋ถ€ํ„ฐ ๊ณ ๊ธ‰ KMP ๊ธฐ๋ฒ•๊นŒ์ง€ ์ดํ•ดํ•˜๊ณ , ๋ฐ”๋กœ ์ฝ”๋”ฉ์œผ๋กœ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”. ์ฝ”๋”ฉ ์ดˆ๋ณด์ž ์—ฌ๋Ÿฌ๋ถ„, ํ•จ๊ป˜ ์žฌ๋ฏธ์žˆ๊ฒŒ ํƒํ—˜ํ•ด ๋ณผ๊นŒ์š”? ๋ฌธ์ž์—ด ์ฐพ๊ธฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํ•˜๋‚˜๋กœ ์ฝ”๋”ฉ ์„ธ๊ณ„๊ฐ€ ๋” ๋„“์–ด์งˆ ํ…Œ๋‹ˆ, ๊ธฐ๋Œ€ํ•˜์„ธ์š”!


?๋“œ๋ผ๋งˆ๋กœ ๋ณด๋Š” ์ฝ”๋”ฉ #1 - ?๋ฌธ์ž์—ด ์ฐพ๊ธฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜ - ์ฃผ์š” ์žฅ๋ฉด 1

๋ฌธ์ž์—ด ์ฐพ๊ธฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๋งค๋ ฅ

์ฝ”๋”ฉ์„ ๊ณต๋ถ€ํ•˜๋‹ค ๋ณด๋ฉด, ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ผ๋Š” ๋‹จ์–ด๊ฐ€ ์ข€ ๋ฌด์„ญ๊ฒŒ ๋А๊ปด์งˆ ์ˆ˜ ์žˆ์–ด์š”. ๊ทธ๋Ÿฐ๋ฐ ๋ฌธ์ž์—ด ์ฐพ๊ธฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ •๋ง ์‹ค์ƒํ™œ๊ณผ ๊ฐ€๊นŒ์›Œ์„œ, ์ดˆ๋ณด์ž๋ถ„๋“ค๋„ ๊ธˆ๋ฐฉ ํฅ๋ฏธ๋ฅผ ๊ฐ€์งˆ ๊ฑฐ์˜ˆ์š”. ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด, ๊ธด ๋ฌธ์žฅ์ด๋‚˜ ํ…์ŠคํŠธ ์†์—์„œ ํŠน์ • ๋‹จ์–ด๋‚˜ ํŒจํ„ด์„ ์ฐพ์•„๋‚ด๋Š” ๊ฑฐ์˜ˆ์š”. ์˜์ƒ์—์„œ์ฒ˜๋Ÿผ "ํ•ด๋‹น ๋ฌธ์žฅ์—์„œ 'ํ•œ๋ฒˆ'์ด๋ผ๋Š” ๋‹จ์–ด๋ฅผ ๋ชจ๋‘ ์ฐพ์•„๋ผ" ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋‚˜์˜ค๋ฉด, 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 ๋ฐฉ๋ฒ•์„ ์ž์„ธํžˆ ํŒŒ๋ณด์ฃ . ์ด๊ฑธ ์•Œ๋ฉด ๊ณ ๊ธ‰ ๊ธฐ๋ฒ•์ด ์™œ ํ•„์š”ํ•œ์ง€ ์ดํ•ด๊ฐ€ ์™ ๋  ๊ฑฐ์˜ˆ์š”.

?๋“œ๋ผ๋งˆ๋กœ ๋ณด๋Š” ์ฝ”๋”ฉ #1 - ?๋ฌธ์ž์—ด ์ฐพ๊ธฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜ - ์ฃผ์š” ์žฅ๋ฉด 2

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๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ• ๊ฒŒ์š”.

?๋“œ๋ผ๋งˆ๋กœ ๋ณด๋Š” ์ฝ”๋”ฉ #1 - ?๋ฌธ์ž์—ด ์ฐพ๊ธฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜ - ์ฃผ์š” ์žฅ๋ฉด 3

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๋ฌธ์ œ ํ’€๊ธฐ!

๋ชฉ๋ก
๊ธ€์“ฐ๊ธฐ
ํ•œ๊ตญ ์„œ๋ฒ„ํ˜ธ์ŠคํŒ…
์ „์ฒด๋ณด๊ธฐ →

๋Œ“๊ธ€ 0