한글 조사 입력하기
- 입력된 한글 문자열의 받침 유무에 따라 '이' 또는 '가'를 입력하는 함수
한글 유니코드 이해하기
- 한글 음절에 대한 유니코드는
0xAC00(가)
부터 0xD7AF(힣)
까지 총 11172개의 코드 포인트가 있다.
음절 : 0xAC00 ~ 0xD7AF (가~힣)
- 각 음절은
초성 + 중성 + 종성(optional)
으로 이루어져 있다.
초성 : 0x1100 ~ 0x1112 (ㄱ~ㅎ)
중성 : 0x1161 ~ 0x1175 (ㅏ~ㅣ)
종성 : 0x11A8 ~ 0x11C2 (ㄱ~ㅎ)
- 한글은 초성, 중성, 종성의 조합으로 이루어져 있기 때문에, 하나의 문자를 바로 저장할 수도 있고, 분해해서 저장할 수도 있다.
let first = "\u{1100}\u{1161}"
let second = "\u{ac00}"
let third = "가"
first == second
second == third
third == first
- Swift에서 유니코드를 표현하기 위해서는
\u{ }
안에 해당 유니코드의 16진수 값을 입력하면 된다.
0x
는 16진수(hexadecimal)를 나타내는 접두사(prefix)이다.
- 한글의 유니코드는
0xAC00
부터 시작하기 때문에, 초성 19개, 중성 21개, 종성 28개를 조합하여 각각에 해당하는 인덱스값을 계산하면 최종적으로 만들어지는 글자의 코드를 생성할 수 있다.
((초성 인덱스 * 21) + 중성 인덱스) * 28 + 종성 인덱스 + 0xAC00 = 글자 코드
- 식을 역산하면 해당 글자 코드로부터 초성, 중성, 종성 인덱스값을 구할 수 있다.
초성 인덱스 = ((글자 코드 - 0xAC00) / 28) / 21
중성 인덱스 = ((글자 코드 - 0xAC00) / 28) % 21
종성 인덱스 = (글자 코드 - 0xAC00) % 28
한글 조사 입력하기
- 문자열에 따라 한글 조사를 판별하고 이를 입력하는 함수를 만들기 위해서는 다음 순서를 따른다.
1. 입력받은 문자열에서 판별할 마지막 문자를 분리한다.
2. 종성의 인덱스 계산을 위해 분리한 문자를 계산 가능한 값으로 변환한다.
3. 종성의 인덱스를 구하고 인덱스 0(종성 없음)의 조건에 따라 조사를 다르게 입력한다.
마지막 문자 분리하기
- 한글 문자열의 조사를 판별하기 위해서는 마지막 문자의 받침 유무를 확인해야한다.
- 입력 받은 한글 문자열에서
.last
메서드를 이용해서 마지막 문자를 분리한다.
input.last
는 옵셔널을 리턴하기 때문에 옵셔널 바인딩을 해준다.
func addKoreanParticle(_ input: String) -> String {
guard let text = input.last { return input }
}
10진수 유니코드 값으로 변환하기
- 종성의 인덱스 계산을 하기 위해서는 문자를 계산 가능한 값으로 변환해야 한다.
- 분리한 문자를 10진수의 유니코드 값으로 변환한다.
UnicodeScalar(String(text))?.value
는 옵셔널을 리턴하기 때문에 옵셔널 바인딩을 해준다.
func addKoreanParticle(_ input: String) -> String {
guard let text = input.last { return input }
let val = UnicodeScalar(String(text))?.value
guard let value = val else { return input }
}
종성 인덱스 계산하기
- 종성의 인덱스가
0
인지 아닌지 판별하고 값에 따라 조사를 다르게 입력한다.
- 위의 계산식에 따라 분리한 문자의 유니코드 값으로 종성의 인덱스 값을 계산한다.
- 인덱스가
0
일 경우(받침 없음) 조사 '가'를 입력하여 리턴하고, 0
이 아닐 경우(받침 있음) 조사 '이'를 입력하여 리턴한다.
func addKoreanParticle(_ input: String) -> String {
guard let text = input.last else { return input }
let val = UnicodeScalar(String(text))?.value
guard let value = val else { return input }
let index = (value - 0xac00) % 28
if index == 0 {
return input + "가"
} else {
return input + "이"
}
}