1. ๊ฐ๋ ๐ธ
๋ณด์ด์ด-๋ฌด์ด(Boyer-Moore) ์๊ณ ๋ฆฌ์ฆ์ skip์ด๋ผ๋ ๊ฒ์ ํ์ฉํ ๋ฌธ์์ด ๋งค์นญ ์๊ณ ๋ฆฌ์ฆ์ด๋ค. ์ฌ๊ธฐ์ skip์ด๋ ๋ฌธ์์ด์ ๋น๊ตํ ๋ ๋ถํ์ํ ๋น๊ต๊ฐ ์๋ค๋ฉด ๊ฑด๋๋ธ ์ ์๋๋ก ๋์์ฃผ๋ ๊ฒ์ด๋ค. (์ ํํ ๋ช ์นญ์ ์๋์ง๋ง ์๋์ ๋์๋ฐฉ์์ ๋ณธ๋ค๋ฉด ์ skip์ด๋ผ๊ณ ๋ถ๋ฆฌ๋์ง ์ ์ ์์ ๊ฒ์ด๋ค.)
๋ณด์ด์ด-๋ฌด์ด ์๊ณ ๋ฆฌ์ฆ์ ๋ฌธ์์ด์ ๋น๊ตํ ๋ ์ผ๋ฐ์ ์ผ๋ก ์๋ถ๋ถ๋ณด๋ค๋ ๋ท๋ถ๋ถ์์ ๋ถ์ผ์น๊ฐ ์ผ์ด๋ ํ๋ฅ ์ด ๋๋ค๋ ์ฑ์ง์ ํ์ฉํ๋ค. ๊ทธ๋์ ๋น๊ตํ ๋ฌธ์์ด๊ณผ ํจํด์ ์๋ถ๋ถ๋ถํฐ ํ์ธํ๋ ๊ฒ์ด ์๋ ๋ท๋ถ๋ถ๋ถํฐ ํ์ธํ๊ฒ ๋๋ค.
2. ๋์๋ฐฉ์ ๐ฌ
๊ธฐ๋ณธ์ ์ธ ๋์๋ฐฉ์์ ์ผ์นํ์ง ์์ ๋ฌธ์๋ฅผ ๋ง๋ ๊ฒฝ์ฐ ํจํด์์ ์ผ์นํ๋ ๋ฌธ์๋ฅผ ์ฐพ์์ ์ด๋ํ ํ ๋น๊ต๋ฅผ ๋ค์ ์์ํ๋ค๋ ๊ฒ์ด๋ค. ๋ณธ๋ฌธ์ 'abphone' ํจํด์ 'phone'๋ผ๊ณ ํ๋ฉด ์๋์ ๊ฐ์ด ๋์ํ๋ค.
์์ ๊ฐ์ด ๋ฌธ์๊ฐ ์ผ์นํ์ง ์๋ ๊ฒฝ์ฐ์(o != e) ํจํด์์ o์ ์ผ์นํ๋ ๋ฌธ์๋ฅผ ์ฐพ์์ ์ด๋ํ ํ ๋ค์ ๋น๊ต๋ฅผ ํ๋ ๊ฒ์ด๋ค. (ํจํด์ ์ผ์นํ๋ ๋ฌธ์๊ฐ ์๋ ๊ฒฝ์ฐ ํจํด์ ๊ธธ์ด๋งํผ ์ด๋ํด์ผ ํ๋ค.) ๊ฒฐ๊ตญ '๋ฌธ์๊ฐ ์ผ์นํ์ง ์๋ ๊ฒฝ์ฐ์ ์ผ๋ง๋งํผ ์ด๋ํด์ผ ํ๋์ง'์ '๋น๊ต ์ฐ์ฐ'๋ง ์ํํ๋ฉด ํด๋น ์๊ณ ๋ฆฌ์ฆ์ด ๋์ํ๋ค.
์ด๋, '์ผ๋ง๋งํผ ์ด๋ํด์ผ ํ๋์ง'๋ฅผ ์๊ธฐ ์ํด์ ์ฌ์ฉํ๋ ๊ฒ์ด skip ๋ฐฐ์ด์ด๋ค. skip๋ฐฐ์ด์ ํด๋น ๋ฌธ์๊ฐ ํจํด์์ ๋ค์์ ๋ช ๋ฒ์งธ์ ์์นํ๋์ง ์๋ ค์ค๋ค. skip์ ๊ฐ์ 'ํจํด ๋ฌธ์์ด์ ๊ธธ์ด - ๊ฐ ํจํด ๋ฌธ์์ ์ธ๋ฑ์ค - 1'์ ๊ฐ์ง๋ค.
๋ฌธ์ | p | h | o | n | e | ๋ค๋ฅธ ๋ชจ๋ ๋ฌธ์ |
skip ๊ฐ | 4 | 3 | 2 | 1 | 5 | 5 |
์ผ์นํ์ง ์๋ ๋ฌธ์๋ฅผ ๋ฐ๊ฒฌํ์ ๊ฒฝ์ฐ ์์ skip ๋ฐฐ์ด์ ํ์ฉํ๋ค๋ฉด ์ฆ์ ๋ช ์นธ์ ์ด๋ํด์ผ ํ๋์ง ์ ์ ์์ ๊ฒ์ด๋ค. phone์ ์ฌ์ฉํ ์์ ์์ o์ e๊ฐ ์ผ์นํ์ง ์์์ ๋ 2์นธ์ ์ด๋ํ ์ด์ ๊ฐ skip ๋ฐฐ์ด์์ 'o'์ ๊ฐ(=2)์ ์ฐธ๊ณ ํ์๊ธฐ ๋๋ฌธ์ด๋ค.
๋ค์์ skip ๋ฐฐ์ด์ ์ฌ์ฉํด์ ๋น ๋ฅด๊ฒ ํจํด๊ณผ ์ผ์นํ๋ ๋ฌธ์์ด์ ์ฐพ๋ ์์ ์ด๋ค.
์ฃผ์ํด์ ๋ด์ผ ํ ์ ์ skip๊ฐ๋งํผ ๋ณธ๋ฌธ ํฌ์ธํฐ๊ฐ ์์ง์ธ๋ค๋ ๊ฒ์ด๋ค. ํจํด์ด ์ด๋ํ๋ ์นธ์ ๊ฐ์๊ฐ ์๋๋ค.
3. ๊ตฌํ ๐ฅ
public class BoyerMoore {
static int BoyerMooreMatch(String str, String pattern) {
int strCursor = 0;
int patternCursor = 0;
int strLen = str.length();
int patternLen = pattern.length();
int[] skip = new int[Character.MAX_VALUE + 1];
// ํจํด์ ์กด์ฌํ์ง ์๋ ๊ฒฝ์ฐ = ํจํด์ ๊ธธ์ด
// ํจํด์ ์กด์ฌํ๋ ๊ฒฝ์ฐ = skipํด์ผ ํ๋ ์นธ์
// ์ ํด๋นํ๋๋ก skip ๋ฐฐ์ด ์ค์
for(strCursor = 0; strCursor <= Character.MAX_VALUE; strCursor++) {
skip[strCursor] = patternLen;
}
for(strCursor = 0; strCursor < patternLen - 1; strCursor++) {
skip[pattern.charAt(strCursor)] = patternLen - strCursor - 1;
System.out.println(pattern.charAt(strCursor) + " : " + (patternLen - strCursor - 1));
}
while(strCursor < strLen) {
patternCursor = patternLen - 1;
// ๋น๊ตํ๋ ๋ฌธ์์ด๊ณผ ํจํด์ด ๋ค์์๋ถํฐ ๊ณ์ ์ผ์นํ์ฌ
// cursor์ ๊ฐ์ ์ค์ด๋ฉด์ ๊ณ์ ๋น๊ตํ๋ ๊ณผ์
while(str.charAt(strCursor) == pattern.charAt(patternCursor)) {
if(patternCursor == 0) {
// ํจํด๊ณผ ์ผ์นํ๋ ๋ฌธ์์ด์ ์ฐพ์ ๊ฒฝ์ฐ ์์ ์ธ๋ฑ์ค๋ฅผ ๋ฐํ
return strCursor;
}
patternCursor--;
strCursor--;
}
strCursor += Math.max(skip[str.charAt(strCursor)], patternLen - patternCursor);
}
return -1;
}
public static void main(String[] args) {
String str = "abcaneczbphone";
String pattern = "phone";
}
}
4. ์๊ฐ๋ณต์ก๋ ๐ผ
์ฃผ์ด์ง ๋ฌธ์์ด์ ๊ธธ์ด๊ฐ N์ด๊ณ ํจํด์ ๊ธธ์ด๊ฐ M์ด๋ผ๊ณ ํ ๋, ์๊ฐ๋ณต์ก๋๋ O(NM)์ด๋ค. ๋ณธ๋ฌธ์ด AAAAAA์ด๊ณ ํจํด์ด BA์ผ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ํ์ง๋ง ์ผ๋ฐ์ ์ผ๋ก๋ O(N) ๋ณด๋ค ๋์ฒด๋ก ์๋ค.
ํ๊ท ์ ์ผ๋ก ๋ณด์ด์ด-๋ฌด์ด ์๊ณ ๋ฆฌ์ฆ์ KMP ์๊ณ ๋ฆฌ์ฆ๋ณด๋ค ๋น ๋ฅธ ์ฑ๋ฅ์ ๋ณด์ธ๋ค๊ณ ์๋ ค์ ธ ์๊ณ ๊ทธ๋ก ์ธํด ๊ฐ์ฅ ๋ง์ด ์ฐ์ด๋ ์๊ณ ๋ฆฌ์ฆ์ด๊ธฐ๋ ํ๋ค.
ํด๋น ๊ธ์
Chan ๋์ '์๊ณ ๋ฆฌ์ฆ - ๋ณด์ด์ด-๋ฌด์ด ์๊ณ ๋ฆฌ์ฆ : ๋ฌธ์์ด ๊ฒ์์ ์ํ ๋๋ค๋ฅธ ์๊ณ ๋ฆฌ์ฆ',
์ผ์ธ์ฝ๋ฉ ๋์ '๋ณด์ด์ด ๋ฌด์ด(Boyer-Moore) ๋ฌธ์์ด ๊ฒ์ ์๊ณ ๋ฆฌ์ฆ'
์ ์ฐธ๊ณ ํ์์ต๋๋ค.
'๐ ์๊ณ ๋ฆฌ์ฆ > ๋ฌธ์์ด' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋ผ๋น-์นดํ(Rabin-Karp) ์๊ณ ๋ฆฌ์ฆ (1) | 2023.04.09 |
---|