๋ณธ ๋ด์ฉ์ ์ถ์ฒ๋ 262๊ฐ์ง ๋ฌธ์ ๋ก ์ ๋ณตํ๋ ์ฝ๋ฉ ์ธํฐ๋ทฐ in Java์ ์์ผ๋ฉฐ, ์ถ๊ฐํ ๋ด์ฉ์ด ์์ ์ ์์ต๋๋ค.
๋จผ์ , ๋ง์ถค๋ฒ ๊ฒ์ฌ ์์คํ ์ ์ค๊ณํ๋ ค๋ฉด ๋ ๋ฒค์ํ์ธ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ ์ ์์ด์ผ ํ๋ค.
Hint : ๋ฒ์๋ฅผ ์ขํ ๋ ๋ฌธ์์ด์ ์ ๋์ฌ๋ฅผ ๋์์ผ๋ก ๋์ผํ ๋ฌธ์ ํ์ด๋ณด๊ธฐ
Solution 02
a์ b๊ฐ ๊ฐ๊ฐ ๋ฌธ์์ด A์ B์ ๊ธธ์ด๋ผ๊ณ ํ์ ๋์ ๋ ๋ฒค์ํ์ธ ๊ฑฐ๋ฆฌ
์ฌ๊ธฐ์ ์ ์ ์๋ ์ฌ์ค
A์ ๋ง์ง๋ง ๋ฌธ์๊ฐ B์ ๋ง์ง๋ง ๋ฌธ์์ ๊ฐ๋ค๋ฉด
A์ ๋ง์ง๋ง ๋ฌธ์๊ฐ B์ ๋ง์ง๋ง ๋ฌธ์์ ๋ค๋ฅด๋ค๋ฉด
์ฝ๋๋ก ํ์ธํ๊ธฐ
public static int levenshteinDistance(String A, String B) {
int[][] distanceBetweenPrefixes = new int[A.length()][B.length()];
for(int[] row : distanceBetweenPrefixes) {
Arrays.fill(row, -1);
}
return computeDistanceBetweenPrefixes(A, A.length() - 1, B, B.length() - 1, distanceBetweenPrefixes);
}
private static int computeDistanceBetweenPrefixes(String A, int A_idx, String B, int B_idx, int[][] distanceBetweenPrefixes) {
if(A_idx < 0) {
// A๊ฐ ๋น์ด์์ผ๋ฏ๋ก B์ ๋ชจ๋ ๋ฌธ์๋ฅผ ์ถ๊ฐํ๋ค.
return B_idx + 1;
} else if (B_idx < 0) {
//B๊ฐ ๋น์ด์์ผ๋ฏ๋ก A์ ๋ชจ๋ ๋ฌธ์๋ฅผ ์ญ์ ํ๋ค.
return A_idx + 1;
}
if(distanceBetweenPrefixes[A_idx][B_idx] == -1) {
if(A.charAt(A_idx) == B.charAt(B_idx)) {
distanceBetweenPrefixes[A_idx][B_idx] = computeDistanceBetweenPrefixes(A, A_idx - 1, B, B_idx - 1, distanceBetweenPrefixes);
}
else {
int substituteLast = computDistanceBetweenPrefixes(A, A_idx - 1, B, B_idx - 1, distanceBetweenPrefixes);
int addLast = computDistanceBetweenPrefixes(A, A_idx - 1, B, B_idx, distanceBetweenPrefixes);
distanceBetweenPrefixes[A_idx][B_idx] = 1 + Math.min(substituteLast, Math.min(addList, deleteLast));
}
}
return distanceBetweenPrefixes[A_idx][B_idx];
}
๐ ์์ฉ 5๋ฌธ์
1. ๊ณต๊ฐ ๋ณต์ก๋์ ์๊ฐ ๋ณต์ก๋์ ๋ ๋ฒค์ํ์ธ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ๋ผ.
2. A์ B๊ฐ ์ฃผ์ด์ก์ ๋, ๊ฐ์ฅ ๊ธด A์ B์ ๋ถ๋ถ ์์ด์ ๊ตฌํ๋ผ. ์๋ฅผ ๋ค์ด ์ ๊ทธ๋ฆผ(ํ)์ ๋์จ ๋ฌธ์์ด์์ ๊ฐ์ฅ ๊ธด ๋ถ๋ถ ์์ด์ ์ด๋ค.
3. ๋ฌธ์์ด A๊ฐ ์ฃผ์ด์ก์ ๋, ํ๋ฌธ์ ๋ง๋ค๊ธฐ ์ํด ์ญ์ ํด์ผ ํ๋ ์ต์ ๋ฌธ์์ ๊ฐ์๋ฅผ ๊ตฌํ๋ผ.
4. ๋ฌธ์์ด A์ ์ ๊ทํํ์ ์ด ์ฃผ์ด์ก์ ๋, ๋ก ํํํ ์ ์๋ ๋ฌธ์์ด ์ค์์ A์ ๊ฐ์ฅ ๊ฐ๊น์ด ๋ฌธ์์ด์ ๋ฌด์์ธ๊ฐ? ๋ฌธ์์ด ์ฌ์ด์ ๊ฑฐ๋ฆฌ๋ ๋ ๋ฒค์ํ์ธ ๊ฑฐ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ค.
5. ๋ฌธ์์ด ๋ ๋ฌธ์์ด ๊ณผ ๋ฅผ ์ผ์ชฝ์์ ์ค๋ฅธ์ชฝ ์์๋๋ก ๋ฒ๊ฐ์ ๋ฐฐ์น์์ผ์ ๋ง๋ค ์ ์๋ ๋ฌธ์์ด์ ๋งํ๋ค.
์๋ฅผ ๋ค์ด, ์ด "gtaa"์ด๊ณ , ๊ฐ "atc"๋ผ๊ณ ํ์ ๋, "gattaca"์ "gtataac"๋ ๊ณผ ๋ฅผ ๋ฒ๊ฐ์ ๋ฐฐ์น์์ผ์ ๋ง๋ค ์ ์์ง๋ง, "gatacta"๋ ๋ง๋ค ์ ์๋ค.
๋ฌธ์์ด , , ๊ฐ ์ฃผ์ด์ก์ ๋, ๊ฐ ๋ฌธ์์ด , ๋ฅผ ๋ฒ๊ฐ์ ๋ฐฐ์น์์ผ์ ๋ง๋ค ์ ์๋์ง ํ์ธํ๋ ์๊ณ ๋ฆฌ์ฆ์ ์ค๊ณํ๋ผ.
Hint : ๋ ๋จ์ด ์ฌ์ด์ ๊ฑฐ๋ฆฌ์ ๋ํ ๊ฐ๋ ์ ๋จผ์ ์ ์ํ๊ธฐ
1๏ธโฃ ํ์ดํ ์ค๋ฅ ๋ชจ๋ธ
- ํ์ดํ ์ค๋ฅ๋ ํค๋ณด๋ ์ํ ๋ฐฐ์ด์ ๋ฐ๋ผ ๋ชจ๋ธ๋ง ๊ฐ๋ฅ
2๏ธโฃ ์์ฑ ๋ชจ๋ธ๋ง
- ๋จ์ด๋ฅผ ๋ค์ ๋์ ์ค์ ๋ง์ถค๋ฒ ์ฌ์ด์ ์ฐจ์ด์์ ์ค๋ ๊ฒฝ์ฐ์ ํด๋น
- ๋ฌธ์ฅ์ ์์์ ๊ฐ์ ์์ฑ์ ๋จ์ด ๋ฆฌ์คํธ๋ฅผ ๋งคํํ๊ธฐ
3๏ธโฃ ์์ ํ๋ ๊ธฐ๋ก
- ์ฌ์ฉ์๋ค์ ๊ฒฝ์ฐ, ์๋ชป ์ ๋ ฅํ ๋ค ์์ ํ๋ ๊ฒฝ์ฐ๋ ๋ง์.
- ์ด๋ฅผ ๋ชจ์์ -> ๊ฐ์ฅ ๋ง์ด ํ๋ฆฌ๋ ์ฒ ์์ ๋ํ ๋ฐฉ๋ํ ๋ฐ์ดํฐ๋ฅผ ์ป์ ์ ์์.
4๏ธโฃ stemming(์คํ ๋ฐ)
- ๊ฐ ๋จ์ด๋ฅผ ํํ์๋ณ๋ก ์ ์ฅ -> ์ฌ์ ํฌ๊ธฐ ์ค์ผ ์ ์์.
- ์ด ๊ฒฝ์ฐ, ์ ๋ ฅ์ผ๋ก ๋ค์ด์จ ๋ฌธ์ฅ์๋ ์คํ ๋ฐ์ ์ ์ฉํด์ผ ํจ.
์คํ ๋ฐ์ด๋?
- ์ฃผ์ด์ง ๋จ์ด์ ํ์ฉํ์ ์ฟผ๋ฆฌ ๋ฌธ์์ด๊ณผ ๋ฌธ์ ๋ชจ๋์์ ํ๋์ ๊ณตํต๋ ์ํ์ผ๋ก ์ค์ด๋ ๊ฒ
ex) {computers, computer, compute} -> compute๋ผ๋ ๋จ์ด๋ก ๋งคํ ๊ฐ๋ฅ
Hint : ์ฃผ์ด์ง ์์ ("computation, "computers", "compute", "computing")์ ํตํด ์ผ๋ฐ์ ์ธ ๊ท์น์ ์ฐพ๊ธฐ
1๏ธโฃ Symspell ์๊ณ ๋ฆฌ์ฆ
2๏ธโฃ Deep-speller
3๏ธโฃ ํ๊ธ ๋ง์ถค๋ฒ ๊ฒ์ฌ ๊ด๋ จ
4๏ธโฃ SymSpell ์๊ณ ๋ฆฌ์ฆ + ํ๊ธ
5๏ธโฃ ๊ฒ์ ์์คํ ์์์ ์คํ ๊ต์ ๋ฐ ๋ณด์ ๊ด๋ จ
๋ฒ์ธ) ๋ง์ถค๋ฒ ๊ด๋ จ ๋ ผ๋ฌธ ์ ๋ฆฌ
๋ด์ฉ ์ถ์ฒ
Symspell ์๊ณ ๋ฆฌ์ฆ์ด๋?
์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์? (Python ver.)
pip install symspellpy
Verbosity.ALL
์ ์ด์ฉํด ๊ฐ์ฅ ๊ฐ๊น์ด ํธ์ง ๊ฑฐ๋ฆฌ์ ๊ฐ์ฅ ํฐ ๋น๋์๋ฅผ ๊ฐ๋ ์ด์ ์ ๋ชจ๋ ๋ฐํhangul-utils
์ฌ์ฉword = split_syllables(word)
corrections = sym_spell.lookup(word, Verbosity.ALL, max_edit_distance=1)
for corr in corrections:
print(corr.term, join_jamos(corr.term), corr.distance, corr.count)
if corrections:
corrected_word = join_jamos(corrections[0].term)
word = corrected_word
print(f"์คํ ๊ต์ ๊ฒฐ๊ณผ: {word}")
else:
print("์คํ ๊ต์ ๊ฒฐ๊ณผ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.")