๋ฌธ์ œ

์ˆ˜์›์ด์™€ ์นœ๊ตฌ๋“ค์€ ์ €๋… ๋ฉ”๋‰ด๋ฅผ ์ž˜ ์„ ํƒํ•˜์ง€ ๋ชปํ•œ๋‹ค. ๋ฐฐ๊ฐ€ ๊ณ ํ”ˆ ์ˆ˜์›์ด๊ฐ€ ๋ณด๋‹ค ๋ชปํ•ด ๋ฉ”๋‰ด๋ฅผ ์ •ํ•˜๊ณค ํ•˜๋Š”๋ฐ ์ด๋งˆ์ €๋„ ๋ฐ˜๋Œ€์— ๋ถ€๋”ชํžˆ๋Š” ๊ฒฝ์šฐ์—๋Š” ์ˆ˜์›์ด๊ฐ€ ์›ํ˜• ๋ฃฐ๋ ›์„ ๋Œ๋ ค ๊ฒฐ์ •ํ•˜๊ณค ํ•œ๋‹ค. ์ด ์›ํ˜• ๋ฃฐ๋ ›์œผ๋กœ ๋ฉ”๋‰ด๋ฅผ ์„ ํƒํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋งค์šฐ ๋…ํŠนํ•œ๋ฐ, ์›ํ˜• ๋ฃฐ๋ ›์„ ๋Œ๋ฆฐ ๋’ค 12์‹œ๋ถ€ํ„ฐ ์‹œ๊ณ„๋ฐฉํ–ฅ์œผ๋กœ ์ฝ์–ด์„œ ๋‚˜์˜ค๋Š” ๋ชจ์–‘์œผ๋กœ ์ €๋… ๋ฉ”๋‰ด๋ฅผ ๊ฒฐ์ •ํ•œ๋‹ค. ์›ํ˜• ๋ฃฐ๋ ›์—๋Š” ์ •ํ™•ํžˆ N๊ฐœ๋กœ ๋‚˜๋ˆ„์–ด์ง„ ์นธ์ด ์กด์žฌํ•˜๊ณ , ๊ฐ ์นธ์—๋Š” ์•ŒํŒŒ๋ฒณ ๋Œ€๋ฌธ์ž ํ•˜๋‚˜๊ฐ€ ์จ์ ธ์žˆ๋‹ค. ๋˜ํ•œ ์›ํ˜• ๋ฃฐ๋ ›์˜ 12์‹œ ๋ฐฉํ–ฅ์— ์กด์žฌํ•˜๋Š” ํ™”์‚ดํ‘œ๋Š” ์นธ ์‚ฌ์ด์— ๊ฑธ์น˜๋Š” ์ผ์ด ์—†์ด ํ•ญ์ƒ ํ•˜๋‚˜์˜ ํŠน์ •ํ•œ ์นธ์„ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ๋˜๋ฉฐ, ์›ํ˜• ๋ฃฐ๋ ›์„ ๋Œ๋ ธ์„ ๋•Œ, N๊ฐœ์˜ ์นธ์ด 12์‹œ์— ์กด์žฌํ•˜๊ฒŒ ๋  ํ™•๋ฅ ์€ ๋ชจ๋‘ ๊ฐ™๋‹ค.

์˜ˆ์‹œ

์ž…๋ ฅ

์ฒซ ๋ฒˆ์งธ ์ค„์—๋Š” ์›ํ˜• ๋ฃฐ๋ ›์˜ ์นธ ์ˆ˜ N(1 โ‰ค N โ‰ค 1,000,000)์ด ์ฃผ์–ด์ง„๋‹ค. ๋‘ ๋ฒˆ์งธ ์ค„์—๋Š” ์ €๋… ๋ฉ”๋‰ด๋กœ ๊ณ ๊ธฐ๋ฅผ ์„ ํƒํ•˜๊ฒŒ ๋˜๋Š” ์›ํ˜• ๋ฃฐ๋ ›์˜ ๋ชจ์–‘์ด 12์‹œ ๋ฐฉํ–ฅ๋ถ€ํ„ฐ ์‹œ๊ณ„๋ฐฉํ–ฅ์œผ๋กœ ๊ณต๋ฐฑ์„ ๊ตฌ๋ถ„์œผ๋กœ ํ•œ ๊ธ€์ž์”ฉ N๊ฐœ ์ฃผ์–ด์ง„๋‹ค. ์„ธ ๋ฒˆ์งธ ์ค„์—๋Š” ํ˜„์žฌ์˜ ์›ํ˜• ๋ฃฐ๋ › ๋ชจ์–‘์ด 12์‹œ ๋ฐฉํ–ฅ์œผ๋กœ๋ถ€ํ„ฐ ์‹œ๊ณ„๋ฐฉํ–ฅ์œผ๋กœ ๊ณต๋ฐฑ์„ ๊ตฌ๋ถ„์œผ๋กœ ํ•œ ๊ธ€์ž์”ฉ N๊ฐœ ์ฃผ์–ด์ง„๋‹ค.

9
I W A N T M E A T
E A T I W A N T M

์ถœ๋ ฅ

์›ํ˜• ๋ฃฐ๋ ›์„ ๋Œ๋ ธ์„ ๋•Œ ์˜ค๋Š˜ ์ €๋…์œผ๋กœ ๊ณ ๊ธฐ๋ฅผ ์„ ํƒํ•˜๊ฒŒ ๋˜๋Š” ํ™•๋ฅ ์„ ๊ธฐ์•ฝ๋ถ„์ˆ˜ ํ˜•ํƒœ๋กœ ์ถœ๋ ฅํ•œ๋‹ค. ๊ธฐ์•ฝ๋ถ„์ˆ˜๋ž€ ๋ถ„์ž์™€ ๋ถ„๋ชจ๊ฐ€ ๋” ์ด์ƒ ์•ฝ๋ถ„์ด ์•ˆ ๋˜๋Š” ํ˜•ํƒœ๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ๋งŒ์•ฝ ๋ฃฐ๋ ›์ด ์–ด๋–ค ๊ณณ์— ๋ฉˆ์ถฐ๋„ ๊ณ ๊ธฐ๋ฅผ ๋จน์„ ์ˆ˜ ์žˆ๋‹ค๋ฉด 1/1 ์„ ์ถœ๋ ฅํ•œ๋‹ค. ์›ํ˜• ๋ฃฐ๋ ›์„ ๋Œ๋ ค ๊ณ ๊ธฐ๋ฅผ ๋จน์„ ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋Š” ์ ์–ด๋„ ํ•œ ๊ฐ€์ง€ ์ด์ƒ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ถ„์ž๊ฐ€ 0์ด ๋˜๋Š” ๊ฒฝ์šฐ๋Š” ์—†๋‹ค.

1/9

ํ‘ธ๋Š” ๋ฒ•

kmp ์•Œ๊ณ ๋ฆฌ์ฆ˜ : ๋ฌธ์ž์—ด(s) ์—์„œ ํŠน์ • ํŒจํ„ด(m) ์„ ํšจ๊ณผ์ ์œผ๋กœ (O(m+s) ๋งŒ์—) ์ฐพ์•„์ฃผ๋Š” ๋ฌธ์ž์—ด ์•Œ๊ณ ๋ฆฌ์ฆ˜ (ํŒจํ„ด์ด ์กด์žฌํ•œ๋‹ค๋ฉด) KMP ์•Œ๊ณ ๋ฆฌ์ฆ˜

์ตœ๋Œ€๊ณต์•ฝ์ˆ˜ ๊ตฌํ•˜๊ธฐ : a,b์˜ ์ตœ๋Œ€๊ณต์•ฝ์ˆ˜๋Š” a,b ์ค‘ ํฐ ์ˆ˜๋ฅผ ์ž‘์€ ์ˆ˜๋กœ ๋‚˜๋ˆˆ ๋‚˜๋จธ์ง€์™€ a,b ์ค‘ ์ž‘์€ ์ˆ˜์˜ ์ตœ๋Œ€๊ณต์•ฝ์ˆ˜์™€ ๊ฐ™๋‹ค ์ด์šฉ (์‚ฌ์‹ค ์ด ๋ฐฉ๋ฒ•์ด ์ฝ”๋“œ์น  ๋•Œ ๋„ˆ๋ฌด ๊ณต์‹์ฒ˜๋Ÿผ ์จ์„œ ๊ทธ๋ƒฅ ์™ธ์šฐ๋‹ค๊ฐ€ ์ด๋ฒˆ์— ์œ ํด๋ฆฌ๋“œ ํ˜ธ์ œ๋ฒ•์ด๋ผ๋Š” ๋ช…์นญ์„ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค)

I W A N T M E A T
E A T I W A N T M

์—์„œ I W A N T M E A T ์„ string ์œผ๋กœ ๋ณด๊ณ  E A T I W A N T M ์„ pattern ์œผ๋กœ ๋ณธ๋‹ค๋ฉด begin ์ด 1 ์ฆ๊ฐ€ํ•œ๋‹ค๋Š” ์˜๋ฏธ๋Š” ๋ฃฐ๋ ›์ด ํ•œ ๋ฒˆ ์•ŒํŒŒ๋ฒณ ์ธ๋ฑ์Šค๊ฐ€ ๋ฐ”๋€Œ์–ด์„œ ๋ฉˆ์ถœ๋งŒํผ ํšŒ์ „ํ–ˆ๋‹ค๋Š” ๋œป์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰ E A T I W A N T M ์—์„œ ์‹œ๊ณ„๋ฐฉํ–ฅ ํšŒ์ „์„ ์‹œ์ž‘ํ•œ ๋ฃฐ๋ ›์ด ๋ฉˆ์ถ”๋Š” ๊ฐ ์‹œ์ ์€ KMP ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ begin ์ด 1 ์ฆ๊ฐ€ํ•  ๋•Œ์ด๋‹ค.

kmp ์—ฐ์Šตํ•˜๊ธฐ ์œ„ํ•ด์„œ ์„ ํƒํ•œ ๋ฌธ์ œ์—ฌ์„œ ๋ฐฉ๋ฒ•์€ ์•Œ์•˜์ง€๋งŒ ์• ์ดˆ์— kmp ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์ดํ•ดํ•˜๋Š”๋ฐ ๋„ˆ๋ฌด๋„ˆ๋ฌด ์–ด๋ ค์› ๊ธฐ ๋•Œ๋ฌธ์— ๋งŽ์ด ํ—ค๋งธ๋‹ค.

๊ตฌํ˜„ ๋ฐฉ๋ฒ•์—์„œ ์ž˜๋ชป ์ƒ๊ฐํ–ˆ๋˜ ๋ถ€๋ถ„, ์ฃผ์˜ํ•  ๋ถ€๋ถ„์„ ์ •๋ฆฌํ•˜์ž๋ฉด

  • kmp ์— ๊ฑธ๋ฆฌ๋Š” while ์กฐ๊ฑด (ํ•ด๋‹น ๋ฌธ์ œ vs ์› kmp ์•Œ๊ณ ๋ฆฌ์ฆ˜)

๋ฐฑ์ค€ ๋ฌธ์ œ : while b<=๋ฌธ์ž์—ด ๊ธธ์ด(=ํŒจํ„ด ๊ธธ์ด)

์›๋ž˜ kmp ์•Œ๊ณ ๋ฆฌ์ฆ˜ : while b<=๋ฌธ์ž์—ด ๊ธธ์ด-ํŒจํ„ด ๊ธธ์ด

b๋„ ์ปค์ง€๊ณ  m๋„ ์ปค์ง€๋ฏ€๋กœ ์ œํ•œ์„ ํ•ด์ค˜์•ผ ํ•จ, b๋ž‘ m ํ•˜๋‚˜๋ผ๋„ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋ฉด while ์ข…๋ฃŒํ•ด์•ผํ•œ๋‹ค.

(์—ฌ๊ธฐ์„œ b๋Š” begin, m์€ match)

์› ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ๋Š” ํŒจํ„ด ๊ธธ์ด๊ฐ€ ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฌธ์ž์—ด ๊ธธ์ด๋ณด๋‹ค ์งง๊ณ  ํ•ด๋‹น ๋ฌธ์ž์—ด ๋ฒ”์ฃผ ๋‚ด์— ํŒจํ„ด์ด ์–ด๋””์— ์กด์žฌํ•˜๋Š”์ง€๋ฅผ ์ฐพ๋Š” ๋ฌธ์ œ์ด๊ธฐ ๋•Œ๋ฌธ์— ์• ์ดˆ์— ๋ฌธ์ž์—ด ๋‚ด ๋น„๊ต๋ฅผ ์‹œ์ž‘ํ•˜๋Š” begin ์˜ ์ธ๋ฑ์Šค๊ฐ€ ํŒจํ„ด์˜ ์ œ์ผ ๋ ์ธ๋ฑ์Šค๋ณด๋‹ค๋„ ๋„˜์–ด๊ฐ€๋ฒ„๋ฆฌ๋ฉด ๋ฌธ์ž์—ด์—์„œ ๋‚จ๋Š” ๋ถ€๋ถ„์€ ์• ์ดˆ์— ํŒจํ„ด๋ณด๋‹ค ์งง์œผ๋ฏ€๋กœ ๊ทธ ์ดํ›„๋ถ€ํ„ฐ๋Š” ํŒจํ„ด์„ ์•„์˜ˆ ์ฐพ์„ ์ˆ˜ ์—†๋Š” ์ธ๋ฑ์Šค๋กœ ๋ณด๊ณ  ์ข…๋ฃŒํ•ด์ฃผ๋ฉด ๋œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด ๋ฌธ์ œ์—์„œ๋Š” ๋ฃฐ๋ ›์ด ์‹œ๊ณ„ ๋ฐฉํ–ฅ ํ•œ ๋ฐ”ํ€ด ํšŒ์ „์„ ๋งˆ์น˜๊ณ  ์›๋ž˜ ์žˆ๋˜ ์ž๋ฆฌ๋กœ ๋Œ์•„์˜ฌ ๋•Œ๊นŒ์ง€ begin์ด ํ•˜๋‚˜ ์ฆ๊ฐ€ํ•  ๋•Œ๋งˆ๋‹ค ๋ฐ˜๋“œ์‹œ ์ €๋…๋ฉ”๋‰ด ๋ฌธ์ž์—ด์ด ๋‚˜์™”๋Š”์ง€ ๋งค๋ฒˆ ํ™•์ธํ•ด์ค˜์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ž์—ด ๊ธธ์ด ๋๊นŒ์ง€ ๊ฒ€์‚ฌํ•ด์•ผํ•œ๋‹ค. (๋‹จ kmp ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ฏ€๋กœ ๋งˆ์ง€๋ง‰ ์ธ๋ฑ์Šค๊นŒ์ง€ ๊ฒ€์‚ฌํ•ด์ฃผ๋˜ ๊ทธ ๊ณผ์ •์—์„œ ์‚ฌ์ด์‚ฌ์ด ๋›ฐ์–ด๋„˜์„ ๋ถ€๋ถ„์„ ๋›ฐ์–ด๋„˜๋Š” ๊ฒƒ ! ์ด˜์ด˜ํ•˜๊ฒŒ ๋ชจ๋“  ์ธ๋ฑ์Šค๋ฅผ ๊ฒ€์‚ฌํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด kmp ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ํ•ต์‹ฌ !)

๋˜ m ๋„ ๋์—†์ด ์ฆ๊ฐ€ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ m<=len(self.pattern) - 1 ์ด๋ ‡๊ฒŒ ์กฐ๊ฑด์„ ๊ฑธ์–ด์ค˜์•ผํ•˜์ง€๋งŒ ์•„์˜ˆ ์•ˆ์— ์ค‘์ฒฉ if ๋ฌธ์„ ๊ฑธ์–ด์„œ match ๊ฐ€ ํŒจํ„ด ๊ธธ์ด๋งŒํผ ๋„๋‹ฌํ–ˆ์„ ๋•Œ match๋ฅผ ๋‹ค์Œ ๊ฒ€์‚ฌ์— ๋งž๊ฒŒ๋” ์žฌ์„ธํŒ…ํ•ด์ฃผ์—ˆ๋‹ค.

  • failure ํ•จ์ˆ˜์—์„œ ๊ฐ’์ด 0์ธ ๊ฒƒ์€ ์•„๋ฌด ๋„์›€์ด ๋˜์ง€ ์•Š๋Š”๋‹ค

    ๊ฒฐ๊ตญ kmp ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ „์ฒด ๋ฌธ์ž์—ด์—์„œ ์ผ์ • ๊ธธ์ด์˜ prefix์™€ suffix๊ฐ€ ์ผ์น˜ํ•˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ž์—ด์ด ์žˆ์„ ๊ฒƒ์ด๊ณ  ์ด๋ฅผ ํ™œ์šฉํ•˜๊ฒ ๋‹ค๋Š”๊ฒŒ ์š”์ง€์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  prefix์™€ suffix๊ฐ€ ์ „์ฒด ๋ฌธ์ž์—ด์„ ์Šฌ๋ผ์ด์‹ฑํ•œ ๊ฐ ๋ถ€๋ถ„์—์„œ ์–ผ๋งˆ๋‚˜ ์ผ์น˜ํ•˜๋Š”์ง€๋Š” failure ํ•จ์ˆ˜์˜ ํ•ด๋‹น ์ธ๋ฑ์Šค์— ์ €์žฅ๋œ ๊ฐ’์œผ๋กœ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰ ๊ฐ’์ด 0์ธ failure ํ•จ์ˆ˜์˜ key ๋Š” ์• ์ดˆ์— kmp ์—์„œ ์ „ํ˜€ ํ™œ์šฉํ•  ์ˆ˜๊ฐ€ ์—†์œผ๋ฏ€๋กœ ์“ธ๋ชจ๊ฐ€ ์—†๋‹ค. failure ํ•จ์ˆ˜๋ฅผ ๊ตฌํ•  ๋•Œ ์ด ๋ถ€๋ถ„์„ ์ƒ๊ฐํ•œ๋‹ค๋ฉด failure ํ•จ์ˆ˜ ์ž์ฒด๊ฐ€ ๋ฌธ์ž์—ด๋„ ํŒจํ„ด,ํŒจํ„ด๋„ ํŒจํ„ด์œผ๋กœ ๋˜์–ด์žˆ๋Š” ๋˜ ํ•˜๋‚˜์˜ kmp ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ผ๋Š” ๊ฒƒ์„ ์œ ์ถ”ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ kmp ์—์„œ ์• ์ดˆ์— ํŒจํ„ด์ด ๋˜๊ธฐ ๊ทธ๋ฅธ ์• ๋“ค์€ ๋‹ค ๋›ฐ์–ด๋„˜๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ์ด๋“ฏ์ด failure ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ๋„ match๊ฐ€ 0์ด์–ด์„œ ์“ธ๋ชจ์—†๋Š” ์• ๋“ค์€ ๋›ฐ์–ด๋„˜์„ ์ˆ˜๊ฐ€ ์žˆ๋‹ค.

  • failure ํ•จ์ˆ˜์— ๊ฑธ๋ฆฌ๋Š” while ๋ฌธ์˜ ์กฐ๊ฑด

    ๋ฐฑ์ค€ ๋ฌธ์ œ, ์› kmp ์•Œ๊ณ ๋ฆฌ์ฆ˜ : while b+m<ํŒจํ„ด์˜ ๊ธธ์ด

    failure ํ•จ์ˆ˜ f(begin+match-1)=match ์—์„œ begin+match-1์€ ์–ด๋”” ์ธ๋ฑ์Šค๊นŒ์ง€ ์Šฌ๋ผ์ด์‹ฑํ•œ ๊ฒƒ์ธ์ง€๋ฅผ ๋งํ•ด์ค€๋‹ค. ์•„๋ฌด๋ฆฌ m ์ด ์ ์  ๋Š˜์–ด๋„ ๋ฌธ์ž์—ด ๋งจ ๋งˆ์ง€๋ง‰ ์ธ๋ฑ์Šค๊นŒ์ง€ ์Šฌ๋ผ์ด์‹ฑํ–ˆ์„ ๋•Œ (=์ฆ‰ ํ•˜๋‚˜๋„ ์Šฌ๋ผ์ด์‹ฑ ์•ˆ ํ•œ ์ „์ฒด ๋ฌธ์ž์—ด) ์—์„œ prefix์™€ suffix๊ฐ€ ์ผ์น˜ํ•˜๋Š” ์ตœ์žฅ prefix ๋ฅผ ๊ตฌํ•˜๋Š” ๋ฐ ๊ทธ์ณ์•ผํ•œ๋‹ค. ๊ทธ ์ด์ƒ์œผ๋กœ๋Š” m ์ด ์ฆ๊ฐ€ํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.

  • ํ•œ๋ฒˆ ํŒจํ„ด์ด ์กด์žฌํ•˜๋Š” ๋ถ€๋ถ„์„ ๋ฐœ๊ฒฌํ•œ ํ›„ ๊ทธ ํ›„์˜ ๊ฒ€์‚ฌ๋Š” ?

    ์ด ๋ถ€๋ถ„์ด ํฌ์ธํŠธ์ธ ๊ฒƒ ๊ฐ™๋‹ค. ์‚ฌ์‹ค ์—ฌ๊ธฐ๋ฅผ ์ž˜๋ชปํ•ด์„œ kmp ๋ฅผ ์ผ๋Š”๋ฐ๋„ 4๋ฒˆ์ด๋‚˜ ์‹œ๊ฐ„์ดˆ๊ณผ๊ฐ€ ๋–ด๋‹ค.

    ํŒจํ„ด์„ ๋ฐœ๊ฒฌํ•œ ํ›„์—๋„ failure ํ•จ์ˆ˜๋ฅผ ๊ทธ๋Œ€๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Œ์„ ๊นจ๋‹ฌ์•˜๋‹ค.

    ๊ฐ€๋ น ๋ฌธ์ž์—ด : p a n a m a b a n a n a , ํŒจํ„ด : a n a ๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•  ๋•Œ

    p โœ”๏ธa n a m a b a n a n a

    โœ”๏ธa n a

    ์ด๋ ‡๊ฒŒ begin 1 ์—์„œ ์ด๋ฏธ ํŒจํ„ด์„ ๋ฐœ๊ฒฌํ•ด์ฃผ์—ˆ์–ด๋„ ๋ฐ”๋กœ ๋‹ค์Œ ์ธ๋ฑ์Šค์ธ n ์„ ๊ฒ€์‚ฌํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ (kmp์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์›๋ฆฌ๋ฅผ ๊ทธ๋Œ€๋กœ ์ƒ๊ฐํ•ด๋ณด๋ฉด ์• ์ดˆ์— a๋กœ ์‹œ์ž‘ํ•˜์ง€๋„ ์•Š๋Š” ์• ๋ฅผ ๊ฒ€์‚ฌํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค) failure ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ 3๋ฒˆ์งธ a๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ถ€๋ถ„๋ถ€ํ„ฐ ๊ฒ€์‚ฌํ•˜๋ฉด ๋œ๋‹ค. ํŒจํ„ด ana ์˜ failure(2)=1 (โ€˜aโ€™) ์ด๋ฏ€๋กœ ๐Ÿ˜€

์ฝ”๋“œ 1 ) input ๊ฐ’ ์ €์žฅํ•˜๋Š” ๋ถ€๋ถ„

import sys
input=sys.stdin.readline
class Dinner:
    def read(self):
        self.move_n=int(input())
        self.string=list(map(str,input().split()))
        self.pattern=list(map(str,input().split()))
        self.failure={}
        self.count=0

์ฝ”๋“œ2) kmp ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ถ€๋ถ„

def kmp(self):
        self.Failure()
        b=1
        m=0
        while b<=self.move_n:
            if self.string[(b+m)%(self.move_n)]==self.pattern[m]:
                m+=1
                if m==len(self.pattern):
                    self.count+=1
                    try:
                        b=b+m-self.failure[m-1]
                        m=self.failure[m-1]
                    except KeyError:
                        b+=1
                        m=0
            else:
                #ํŒจํ„ด๊ณผ ํ•œ ๊ธ€์ž๋งŒ ์ผ์น˜ํ•˜๊ฑฐ๋‚˜ ์•„์˜ˆ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋ถˆ์ผ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ
                if m<=1:
                    b+=1
                    m=0
                #ํ˜น์‹œ ๋ชจ๋ฅด๋‹ˆ๊น try๋กœ
                else:
                    try:
                        b=b+m-self.failure[m-1]
                        m=self.failure[m-1]
                    except KeyError:
                        b+=1
                        m=0

failure ํ•จ์ˆ˜๋„ kmp ์•Œ๊ณ ๋ฆฌ์ฆ˜์ฒ˜๋Ÿผ ๊ฐ’์ด 0 ์ธ ์• ๋“ค์€ ์ €์žฅ ์•ˆ ํ•˜๊ณ  ๋‹ค ์Šคํ‚ตํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์• ์ดˆ์— ๊ฐ’์ด 0์ธ ์• ๋“ค์€ ์ €์žฅ๋˜์–ด์žˆ์ง€ ์•Š๋‹ค. ํ™œ์šฉํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ! ๊ทธ๋Ÿฐ๋ฐ match ๊ฐ€ 0์ธ ๋ถ€๋ถ„๋„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‚˜ failure ๋”•์…”๋„ˆ๋ฆฌ์— ์ ‘๊ทผํ•ด์„œ ์—๋Ÿฌ๊ฐ€ ๋‚˜๋Š” ๊ฒฝ์šฐ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ try ,except ๋กœ ํ•ด๊ฒฐํ•˜์˜€๋‹ค. ์ฆ‰ except ์— ๊ฑธ๋ฆฌ๋ฉด failure ๋กœ ๊ฒ€์‚ฌ ์Šคํ‚ตํ•˜์ง€ ๋ชปํ•˜๋Š” ๋ถ€๋ถ„์ด๋‹ˆ๊นŒ ๋น ์ง์—†์ด ๊ฒ€์‚ฌํ•ด๋ผ ! ๐Ÿค“ ์˜ ์˜๋ฏธ์ด๋‹ค.

์‚ฌ์‹ค ์ฝ”๋“œ ์ด๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๊ฐ€๋ณ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค. ๋” ์ข‹์€ ๋ฐฉ๋ฒ• ์žˆ์œผ๋ฉด ๊ณต์œ ํ•ด์ฃผ์‹œ๋ฉด ์ •๋ง ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค ๐Ÿ™†โ€โ™€๏ธ

์ฝ”๋“œ3) failure ํ•จ์ˆ˜ ๋ถ€๋ถ„

def Failure(self):
        b=1
        m=0
        twin=self.pattern
        while b+m<len(self.pattern):
            if self.pattern[b+m]==twin[m]:
                m+=1
                self.failure[b+m-1]=m
            else:
                if m<=1:
                    b+=1
                    m=0
                #ํ˜น์‹œ ๋ชจ๋ฅด๋‹ˆ๊น 
                else:
                    try:
                        b=b+m-self.failure[m-1]
                        m=self.failure[m-1]
                    except KeyError:
                        b+=1
                        m=0

failure ํ•จ์ˆ˜๋„ ๊ฒฐ๊ตญ match ๊ฐ’์„ ์ด์šฉํ•˜๋Š” kmp ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ผ๋Š” ๊ฒƒ์„ ์ƒ๊ฐํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ while ๋ฌธ ์กฐ๊ฑด ๊ฑธ๋ฆฌ๋Š” ๋ถ€๋ถ„ ๋นผ๋ฉด ๊ฑฐ์˜ ์œ ์‚ฌํ•˜๋‹ค.

์ฝ”๋“œ4) gcd ๋ถ€๋ถ„

def gcd(self,x,y):
        while y:
            x,y=y,x%y
        return x

์ฝ”๋“œ5)์ •๋‹ต ๋„์ถœ ๋ถ€๋ถ„

def Answer(self):
        if self.pattern.count(self.pattern[0])==len(self.pattern):
            print('1/1')
            return
        else:
            self.kmp()
            d=self.gcd(self.move_n,self.count)
            Answer=str(self.count//d)+'/'+str((self.move_n)//d)
            print(Answer)

์• ์ดˆ์— ๋ฃฐ๋ ›์˜ ๋ชจ๋“  ๊ธ€์ž๊ฐ€ ๋™์ผํ•˜๋‹ค๋ฉด ๋‹น์—ฐํžˆ ๋ฃฐ๋ ›์ด ์–ผ๋งŒํผ ํšŒ์ „ํ•ด๋„ 100% ๊ทธ ๋ฉ”๋‰ด๋ฅผ ๋จน๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ์‹œ๊ฐ„ ๋‹จ์ถ•ํ•˜๋ ค๊ณ  if ๋ฌธ์„ ์ถ”๊ฐ€ํ•˜์˜€๋‹ค.

์ „์ฒด ์ฝ”๋“œ

import sys
input=sys.stdin.readline
class Dinner:
    def read(self):
        self.move_n=int(input())
        self.string=list(map(str,input().split()))
        self.pattern=list(map(str,input().split()))
        self.failure={}
        self.count=0
    
    def kmp(self):
        self.Failure()
        b=1
        m=0
        #b๋„ ์ปค์ง€๊ณ  m๋„ ์ปค์ง€๋ฏ€๋กœ ์ œํ•œ์„ ํ•ด์ค˜์•ผ ํ•จ, b๋ž‘ m ํ•˜๋‚˜๋ผ๋„ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋ฉด while ์ข…๋ฃŒ
        #begin ์€ pattern ์ด string ๋ชจ๋“  index๋ฅผ ๋Œ๋ฉด์„œ ์ผ์น˜ ๊ฐฏ์ˆ˜๋ฅผ ์„ธ์–ด์•ผ ํ•จ
        #pattern ์ค‘ ์–ผ๋งˆ๋‚˜ ์ผ์น˜ํ•˜๋Š”์ง€ ๋ณด๋Š”๊ฒŒ m์ด๊ธฐ ๋•Œ๋ฌธ์— m๋„ pattern ๊ธธ์ด๋ฅผ ๋„˜์„ ์ˆ˜๊ฐ€ ์—†์Œ
        while b<=self.move_n:
            if self.string[(b+m)%(self.move_n)]==self.pattern[m]:
                m+=1
                if m==len(self.pattern):
                    self.count+=1
                    try:
                        b=b+m-self.failure[m-1]
                        m=self.failure[m-1]
                    except KeyError:
                        b+=1
                        m=0
            else:
                #ํŒจํ„ด๊ณผ ํ•œ ๊ธ€์ž๋งŒ ์ผ์น˜ํ•˜๊ฑฐ๋‚˜ ์•„์˜ˆ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋ถˆ์ผ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ
                if m<=1:
                    b+=1
                    m=0
                #ํ˜น์‹œ ๋ชจ๋ฅด๋‹ˆ๊น try๋กœ
                else:
                    try:
                        b=b+m-self.failure[m-1]
                        m=self.failure[m-1]
                    except KeyError:
                        b+=1
                        m=0
    
    def Failure(self):
        b=1
        m=0
        twin=self.pattern
        while b+m<len(self.pattern):
            if self.pattern[b+m]==twin[m]:
                m+=1
                self.failure[b+m-1]=m
            else:
                if m<=1:
                    b+=1
                    m=0
                #ํ˜น์‹œ ๋ชจ๋ฅด๋‹ˆ๊น 
                else:
                    try:
                        b=b+m-self.failure[m-1]
                        m=self.failure[m-1]
                    except KeyError:
                        b+=1
                        m=0
                    
    def gcd(self,x,y):
        while y:
            x,y=y,x%y
        return x
    
    def Answer(self):
        if self.pattern.count(self.pattern[0])==len(self.pattern):
            print('1/1')
            return
        else:
            self.kmp()
            d=self.gcd(self.move_n,self.count)
            Answer=str(self.count//d)+'/'+str((self.move_n)//d)
            print(Answer)
    
    
    
    
dinner=Dinner()
dinner.read()
dinner.Answer()

ํ•ด๋‹น ๋ฌธ์ž์—ด ๋‚ด ์ธ๋ฑ์Šค ํ•˜๋‚˜ํ•˜๋‚˜๋ฅผ ๊ฒ€์‚ฌํ•ด์„œ ํŒจํ„ด์ด ์žˆ๋Š”์ง€๋ฅผ ์ฐพ๋Š”๋‹ค๋ฉด ์ด์ค‘ for ๋ฌธ์„ ์จ์•ผํ•˜๋ฏ€๋กœ ์‹œ๊ฐ„ ๋ณต์žก๋„๊ฐ€ O(ํŒจํ„ด ๊ธธ์ด*๋ฌธ์ž์—ด ๊ธธ์ด) ๊ฐ€ ๋‚˜์˜จ๋‹ค. ๋ฐ˜๋ฉด kmp ์—์„œ๋Š” while ๋ฌธ ๊ฐ๊ฐ ํŒจํ„ด ๊ธธ์ด,๋ฌธ์ž์—ด ๊ธธ์ด๋งŒ ๊ณ ๋ คํ•ด์ฃผ๋ฉด ๋˜๋ฏ€๋กœ O(ํŒจํ„ด ๊ธธ์ด + ๋ฌธ์ž์—ด ๊ธธ์ด) ์ด๋‹ค. ๐Ÿ™‚

๋งˆ๋ฌด์œผ๋ฆฌ

์‚ฌ์‹ค kmp ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ด๋ ‡๊ฒŒ ๋ณต์žกํ•œ ๊ฑฐ๋ฅผ ๋‚ด๊ฐ€ ๋‹จ๋ฒˆ์— ๊ตฌํ˜„ํ–ˆ์„๋ฆฌ๊ฐ€ ์—†๋‹ค ใ…‹ใ…‹ใ…‹ ๋‹น์—ฐํžˆ ์˜ˆ์ „์— kmp ์ฒ˜์Œ ๊ณต๋ถ€ํ•  ๋•Œ ๊ตฌ๊ธ€๋ง๋„ ํ•ด๋ณด๊ณ  ์ด๊ฒƒ์ €๊ฒƒ ๋จธ๋ฆฌ๋ฅผ ์‹ธ๋งค๊ณ  ๋งŒ๋“  ๋ถ€๋ถ„ ๊บผ๋‚ด๋‹ค๊ฐ€ ๊ฑฐ์˜ ๋ฐ”๊ฟ”์„œ ์ผ๋‹ค. ์ตœ๋Œ€๊ณต์•ฝ์ˆ˜๋„ ๊ทธ๋ƒฅ ์ž˜ ์•Œ๋ ค์ง„ ์ฝ”๋“œ ๊ณต์‹์ฒ˜๋Ÿผ ์™ธ์›Œ์„œ ์‚ฌ์šฉํ•˜์˜€๋‹ค ! ํ•˜์ง€๋งŒ ๋ฌธ์ž์—ด ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œ์—์„œ kmp ๊ฐ€ ๊ฑฐ์˜ ์น˜ํŠธํ‚ค (๋งž๋‚˜?!) ๋ผ๊ณ  ์ƒ๊ฐ์ด ๋“ค์–ด์„œ ์ด๋ ‡๊ฒŒ ์ต์ˆ™ํ•ด์ง€๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค :)

์‚ฌ์‹ค ์˜ค๋Š˜ ์ด์ง„ํƒ์ƒ‰ํŠธ๋ฆฌ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ๊ณต๋ถ€ํ•  ์ˆœ์„œ์˜€๋Š”๋ฐ ์• ์ดˆ์— ๋„ˆ๋ฌด ๊ณต๋ถ€๋ฅผ ๋Šฆ๊ฒŒ ์‹œ์ž‘ํ•ด์„œ ํ•˜๋ฃจ ๋ฃจํ‹ด์ด ๋ง๊ฐ€์กŒ๋‹ค. ๊ทธ๋ž˜์„œ ๋ฌธ์ œ ํ•˜๋‚˜๋ผ๋„ ํ’€๊ณ  ์‰ฌ์ž๋ผ๋Š” ์ƒ๊ฐ์œผ๋กœ ์ด ๋ฌธ์ œ๋ฅผ ํ’€๊ฒŒ ๋˜์—ˆ๋‹ค. bfs,dfs ๋ณต์Šตํ•˜๊ณ  ์•ž๋ถ€๋ถ„ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ณต์Šตํ•  ๊ฒƒ๋ถ€ํ„ฐ ์ฐจ๊ทผ์ฐจ๊ทผ ํ•ด์•ผํ•˜๋Š”๋ฐ ์˜ค๋Š˜ ์–ด๋–ป๊ฒŒ ํ•˜๋‹ค๋ณด๋‹ˆ๊นŒ ๋ฌธ์ž์—ด์„ ํ’€๊ฒŒ ๋œ ๊ฒƒ ๊ฐ™๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋“œ๋””์–ด ๋ฐฑ์ค€ 10๋ฌธ์ œ ํ’€์—ˆ๋‹น ๐Ÿ˜† ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ์ผ์š”์ผ์€ ๋ญํ•˜๊ณ  ๋†€๊นŒ ํํ

TMI

KakaoTalk_20210312_231910602

๋งฅ๋ถ„ํˆฌ ํ•˜๋ ค๋‹ค๊ฐ€ ๋‹ค๋ฅธ ์•„์ด์ฝ˜๋“ค๋กœ ์šฐ๋ถ„ํˆฌ๋ฅผ ๊พธ๋ฉฐ๋ดค๋Š”๋ฐ ์ข€ ์œ ์น˜ํ•œ ๊ฒƒ ๊ฐ™๊ธฐ๋„ ํ•˜๋‹ค. ๋ถ„๋ช… ์ปดํ“จํ„ฐ์ธ๋ฐ ์•„์ด์ฝ˜ ์ด๋ ‡๊ฒŒ ํ•˜๋‹ˆ๊นŒ ํ•ธ๋“œํฐ ๋Š๋‚Œ์ด ๋‚œ๋‹ค. ๋ฆฌ๋ˆ…์Šค ๊ณต๋ถ€ํ•˜๋ฉด ํ•  ์ˆ˜๋ก ๋งค๋ ฅ์žˆ๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ๋งฅย ยป๋ฆฌ๋ˆ…์Šค>์œˆ๋„์šฐ ์ˆœ์œผ๋กœ ์ข‹๋‹ค. ์ด๊ฑฐ๋ž‘ ํ•œ๊ธ€ ์ž…๋ ฅ ํ—ค๋งค๋Š๋ผ๊ณ  ์˜ค์ „ ์‹œ๊ฐ„์„ ๋‹ค ๊นŒ๋จน์—ˆ์ง€๋งŒ ๐Ÿ˜ฃ ๋ฟŒ๋“ฏํ•˜๋‹น