๐ KMP ์๊ณ ๋ฆฌ์ฆ
๐ KMP ์๊ณ ๋ฆฌ์ฆ
- ๋ฌธ์์ด ๊ฒ์ ์๊ณ ๋ฆฌ์ฆ
- ํ ์คํธ ๋ด์์ ํจํด ๋ฌธ์์ด์ ๋น ๋ฅด๊ฒ ์ฐพ๋ ์๊ณ ๋ฆฌ์ฆ
- ์ผ๋ฐ์ ์ธ ๋ฌธ์์ด ํ์(๋ธ๋ฃจํธํฌ์ค)์ด (O(n*m)) ์ธ ๋ฐ๋ฉด KMP๋ (O(n+m)) ์๊ฐ์ ์ํํ๋ค.(n = ํ ์คํธ ๊ธธ์ด, m = ํจํด ๊ธธ์ด)
- KMP๋ฅผ ์ ์ ๋ฆฌํด์ค ์ฌ์ดํธ
๐ KMP ํต์ฌ ์์ด๋์ด
- ํจํด ๋ด์์ ์คํจํ ๋ ๋ค์ ์ฒ์๋ถํฐ ๋น๊ตํ์ง ์๊ณ , ์ด๋ฏธ ์ผ์นํ๋ ๋ถ๋ถ์ ํ์ฉํด ๊ฑด๋๋ด๋ค.
- ์ด๋ฅผ ์ํด ์ ๋์ฌ-์ ๋ฏธ์ฌ ์ผ์น ์ ๋ณด ๋ฅผ ๋ฏธ๋ฆฌ ๊ณ์ฐํ๋ ๊ณผ์ ์ด ํ์ํ๋ค.
- ์ด๋ฅผ lps[] ๋ฐฐ์ด์ด๋ผ ๋ถ๋ฅธ๋ค(Longest Prefix Seffix)
๐ KMP ๋จ๊ณ๋ณ ์ค๋ช
- lps ๋ฐฐ์ด ๋ฐ๋ค๊ธฐ
- lps[i]๋ ํจํด์ 0 ~ i ๊น์ง ๋ถ๋ถ ๋ฌธ์์ด์์ ์ ๋์ฌ์ ์ ๋ฏธ์ฌ๊ฐ ์ผ์นํ๋ ๊ฐ์ฅ ๊ธด ๊ธธ์ด๋ฅผ ๋ปํ๋ค.
- ex) ํจํด : โABABCโ, lps ๋ฐฐ์ด : [0, 0, 1, 2, 0]
- ๋ฌธ์์ด ํ์
- ํ ์คํธ์ ํจํด์ ์ํํ๋ฉฐ ์ผ์น ์ฌ๋ถ ๊ฒ์ฌ
- ๋ถ์ผ์น๊ฐ ๋ฐ์ํ๋ฉด ํจํด์์ ๋ฐ๋ก ์ด์ lps๊ฐ์ ์ฐธ์กฐํด ๋น๊ต๋ฅผ ๊ณ์ํจ์ผ๋ก์จ ๋ถํ์ํ ๋ฐ๋ณต ๋ฐฉ์ง
๐ป KMP ๊ตฌํ
#include <iostream>
#include <vector>
#include <string>
using namespace std;
// 1. lps ๋ฐฐ์ด ๊ณ์ฐ ํจ์
vector<int> computeLps(const string& pattern) {
int m = pattern.size();
vector<int> lps(m, 0);
int len = 0; // ํ์ฌ๊น์ง์ ์ ๋์ฌ - ์ ๋ฏธ์ฌ ์ต๋ ๊ธธ์ด
int i = 1; // lps[0]์ ํญ์ 0์ด๋ฏ๋ก i = 1๋ถํฐ ์์
while(i < m)
{
if(pattern[i] == patter[len])
{
len++;
lps[i] = len;
i++;
}
else
{
if(len != 0)
{
len = lps[len-1]; // len์ lps[len-1]๋ก ์ค์ฌ์ ๋ค์ ๋น๊ต
}
else
{
lps[i] = 0;
i++;
}
}
}return lps;
}
// 2. KMP ๊ฒ์ ํจ์ : ํจํด์ด ํ
์คํธ์ ์๋์ง ํ์ธ
bool KMP(const string& text, const string& pattern) {
int n = text.size();
int m = pattern.size();
if(m == 0) return true; // ๋น ํจํด์ ํญ์ ์กด์ฌํจ
vector<int> lps = coputeLps(pattern);
int i = 0; // ํ
์คํธ ์ธ๋ฑ์ค
int j = 0; // ํจํด ์ธ๋ฑ์ค
while(i < n)
{
if(text[i] == pattern[j])
{
i++;
j++;
if(j == m)
{
// ํจํด ์ ๋ถ ์ผ์น
return true;
// j = lps[j-1]; // ์ฌ๋ฌ๊ฐ ์ฐพ์ผ๋ ค๋ฉด ์ฌ๊ธฐ์ ๊ณ์ ์งํ
}
}
else
{
if(j != 0)
{
j = lps[j-1];
}
else
{
i++;
}
}
}
return false; // ํจํด์์
}
๐ ์์ฝ
- KMP ์๊ณ ๋ฆฌ์ฆ ์์ฑ์๋ 2๊ฐ์ง ๋จ๊ณ๊ฐ ์กด์ฌํ๋ค.
- computeLps - ํจํด์์ ์ ๋์ฌ-์ ๋ฏธ์ฌ ์ผ์น ๊ธธ์ด ๊ณ์ฐ
- KMP - ํ ์คํธ ๋ด์์ ํจํด ๊ฒ์
- lps ๋ฐฐ์ด์ ๋ถ์ผ์น ์ ์ด๋ํ ์์น๋ฅผ ๋ฏธ๋ฆฌ ๊ณ์ฐํด ์๊ฐ ๋ญ๋น๋ฅผ ๋ฐฉ์งํ๋ค.
- ์ ์ฒด ํ์์ด (O(n+m)) ์ ์ํ๋๋ค.