본문 바로가기
오늘은 무얼해볼까

한글 자소분리 하기

by nr2p 2021. 8. 12.
반응형

백준 11283 문제는 charCodeAt 을 아는지만 물어보는 문제였는데

어쩌다보니 한글 자소분리하는 함수를 만들어보았다!

자소분리 : 한글을 초성, 중성, 종성으로 분리하는 것

1. 초성, 중성, 종성이 담긴 배열을 준비한다.

const [first, middle, last] = [[
        'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ', 'ㅁ',
        'ㅂ', 'ㅃ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ',
        'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'
    ], [
        'ㅏ', 'ㅐ', 'ㅑ', 'ㅒ', 'ㅓ', 'ㅔ', 'ㅕ',
        'ㅖ', 'ㅗ', 'ㅘ', 'ㅙ', 'ㅚ', 'ㅛ', 'ㅜ',
        'ㅝ', 'ㅞ', 'ㅟ', 'ㅠ', 'ㅡ', 'ㅢ', 'ㅣ'
    ], [
        '', 'ㄱ', 'ㄲ', 'ㄳ', 'ㄴ', 'ㄵ', 'ㄶ',
        'ㄷ', 'ㄹ', 'ㄺ', 'ㄻ', 'ㄼ', 'ㄽ', 'ㄾ',
        'ㄿ', 'ㅀ', 'ㅁ', 'ㅂ', 'ㅄ', 'ㅅ', 'ㅆ',
        'ㅇ', 'ㅈ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'
    ]]

 

 

2. 규칙을 찾는다.

이런식으로 하나하나 찍어보면서 규칙을 발견하는 것도 좋지만..!

중성과 종성의 갯수가 각각 21, 28 개 인데

가 → 까 로 변할 때 중성 한바퀴, 종성 한바퀴 돌아야하기 때문에

중성과 종성의 갯수를 곱한 588만큼 차이나는 것이다.

 

비슷하게 중성도

가 → 개 로 변할 때 종성 한 바퀴를 다 돌아야하기 때문에

종성의 갯수인 28만큼 차이나는 것이다.

 

 

3. 찾은 규칙을 적용한다.

const separateWord = cur => {
    const BASE = 44032;
    const [firstInterval, middleInterval] = [588, 28]
    const [first, middle, last] = [[
        'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ', 'ㅁ',
        'ㅂ', 'ㅃ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ',
        'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'
    ], [
        'ㅏ', 'ㅐ', 'ㅑ', 'ㅒ', 'ㅓ', 'ㅔ', 'ㅕ',
        'ㅖ', 'ㅗ', 'ㅘ', 'ㅙ', 'ㅚ', 'ㅛ', 'ㅜ',
        'ㅝ', 'ㅞ', 'ㅟ', 'ㅠ', 'ㅡ', 'ㅢ', 'ㅣ'
    ], [
        '', 'ㄱ', 'ㄲ', 'ㄳ', 'ㄴ', 'ㄵ', 'ㄶ',
        'ㄷ', 'ㄹ', 'ㄺ', 'ㄻ', 'ㄼ', 'ㄽ', 'ㄾ',
        'ㄿ', 'ㅀ', 'ㅁ', 'ㅂ', 'ㅄ', 'ㅅ', 'ㅆ',
        'ㅇ', 'ㅈ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'
    ]]

    const curMinusBase = cur - BASE
    const firstIdx = Math.floor(curMinusBase / firstInterval)
    const middleIdx = Math.floor((curMinusBase - firstInterval * firstIdx) / middleInterval)
    const lastIdx = (curMinusBase - firstInterval * firstIdx) % middleInterval

    console.log(first[firstIdx], middle[middleIdx], last[lastIdx] ?? '')
}

// cur 변수가 한글 한글자인 것만 가정했기 때문에
// 따로 분기 처리해주지 않았다.

 

 

사용된 함수
charCodeAt(index), Math.floor()
반응형