diff --git a/autotextcorrection/build.gradle.kts b/autotextcorrection/build.gradle.kts new file mode 100644 index 0000000..824d24e --- /dev/null +++ b/autotextcorrection/build.gradle.kts @@ -0,0 +1,13 @@ +plugins { + id("java-library") + id("org.jetbrains.kotlin.jvm") +} + +java { + sourceCompatibility = JavaVersion.VERSION_1_7 + targetCompatibility = JavaVersion.VERSION_1_7 +} + +dependencies { + implementation(UnitTest.JUNIT) +} diff --git a/autotextcorrection/src/main/java/com/konkuk/autotextcorrection/AutoTextCorrector.kt b/autotextcorrection/src/main/java/com/konkuk/autotextcorrection/AutoTextCorrector.kt new file mode 100644 index 0000000..fe0f5ce --- /dev/null +++ b/autotextcorrection/src/main/java/com/konkuk/autotextcorrection/AutoTextCorrector.kt @@ -0,0 +1,78 @@ +package com.konkuk.autotextcorrection + +class AutoTextCorrector( + targetTextList: List, + val errorCorrectionDistance: Int = 1, +) { + + private val targetWordsMap = mutableMapOf() + private val targetTextDestructedList = targetTextList.map { word -> + val destructedWord = destructWord(word) + targetWordsMap[destructedWord] = word + destructedWord + } + + fun destructWord(word: String): String { + var result = StringBuilder() + for (element in word) { + var uniVal = element + + if (uniVal.code >= 0xAC00) { + uniVal = (uniVal.code - 0xAC00).toChar() + val cho = (uniVal.code / 28 / 21).toChar() + val joong = (uniVal.code / 28 % 21).toChar() + val jong = (uniVal.code % 28).toChar() + result.append(INITIAL_CHARACTER[cho.code] + MID_CHARACTER[joong.code] + FINAL_CHARACTER[jong.code]) + } else { + result.append(element) + } + } + return String(result) + } + + fun correctWord(word: String): String { + if (word.isEmpty()) return word + val destructedWord = destructWord(word) + for (destructedChars in targetTextDestructedList) { + val dp = List(destructedChars.length + 1) { IntArray(destructedWord.length + 1) } + for (i in 1..destructedChars.length) { + for (j in 1..destructedWord.length) { + if (destructedChars[i - 1] == destructedWord[j - 1]) { + dp[i][j] = dp[i - 1][j - 1] + 1 + } else { + dp[i][j] = maxOf(dp[i - 1][j], dp[i][j - 1]) + } + } + } + if (abs(dp.last().last() - destructedChars.length) <= errorCorrectionDistance && + abs(dp.last().last() - destructedWord.length) <= errorCorrectionDistance + ) { + return targetWordsMap[destructedChars]!! + } + } + return word + } + + fun correctText(text: String): String { + return text.split(" ").map { word -> correctWord(word) }.joinToString(" ") + } + + private fun abs(n: Int) = if (n < 0) -n else n + + companion object { + private val INITIAL_CHARACTER = listOf( + "ㄱ", "ㄲ", "ㄴ", "ㄷ", "ㄸ", "ㄹ", "ㅁ", "ㅂ", "ㅃ", + "ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅉ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ", + ) + + private val MID_CHARACTER = listOf( + "ㅏ", "ㅐ", "ㅑ", "ㅒ", "ㅓ", "ㅔ", "ㅕ", "ㅖ", "ㅗ", "ㅘ", + "ㅙ", "ㅚ", "ㅛ", "ㅜ", "ㅝ", "ㅞ", "ㅟ", "ㅠ", "ㅡ", "ㅢ", "ㅣ", + ) + + private val FINAL_CHARACTER = listOf( + "", "ㄱ", "ㄲ", "ㄳ", "ㄴ", "ㄵ", "ㄶ", "ㄷ", "ㄹ", "ㄺ", "ㄻ", "ㄼ", + "ㄽ", "ㄾ", "ㄿ", "ㅀ", "ㅁ", "ㅂ", "ㅄ", "ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ", + ) + } +} diff --git a/autotextcorrection/src/test/java/com/konkuk/autotextcorrection/AutoTextCorrectorUnitTest.kt b/autotextcorrection/src/test/java/com/konkuk/autotextcorrection/AutoTextCorrectorUnitTest.kt new file mode 100644 index 0000000..ac1dfc1 --- /dev/null +++ b/autotextcorrection/src/test/java/com/konkuk/autotextcorrection/AutoTextCorrectorUnitTest.kt @@ -0,0 +1,47 @@ +package com.konkuk.autotextcorrection + +import org.junit.Assert +import org.junit.Test + +class AutoTextCorrectorUnitTest { + + private val targetTextList = listOf("칼로리", "나트륨", "단백질", "탄수화물") + private val corrector = AutoTextCorrector( + targetTextList = targetTextList, + errorCorrectionDistance = 2, + ) + + @Test + fun `destruct_corrector가 string을 char로 분해`() { + Assert.assertEquals( + targetTextList.map { corrector.destructWord(it) }, + listOf( + "ㅋㅏㄹㄹㅗㄹㅣ", + "ㄴㅏㅌㅡㄹㅠㅁ", + "ㄷㅏㄴㅂㅐㄱㅈㅣㄹ", + "ㅌㅏㄴㅅㅜㅎㅘㅁㅜㄹ", + ), + ) + } + + @Test + fun `correct_corrector가 word를 수정`() { + Assert.assertEquals( + "나트륨", + corrector.correctWord("니트륨"), + ) + + Assert.assertEquals( + "탄수화물", + corrector.correctWord("탐수화믈"), + ) + } + + @Test + fun `correct_corrector가 오류를 수정`() { + Assert.assertEquals( + "나트륨 정말 맛있어,ㅎㅎ 그리고 나는 탄수화물 매우 좋아하지!! 칼로리 너무 행복", + corrector.correctText("니트륨 정말 맛있어,ㅎㅎ 그리고 나는 탐수화믈 매우 좋아하지!! 칼로ㅏ 너무 행복"), + ) + } +} diff --git a/textautoconvert/build.gradle.kts b/textautoconvert/build.gradle.kts new file mode 100644 index 0000000..0d31ad5 --- /dev/null +++ b/textautoconvert/build.gradle.kts @@ -0,0 +1,9 @@ +plugins { + id("java-library") + id("org.jetbrains.kotlin.jvm") +} + +java { + sourceCompatibility = JavaVersion.VERSION_1_7 + targetCompatibility = JavaVersion.VERSION_1_7 +} \ No newline at end of file