머리가 돌아가며 날아가는 비둘기
자료구조 과제 중이었다. 과제의 핵심 내용은 대략 이렇다.
1. N개의 문장을 입력받는다.
2. 각 문장으로부터 오직 한글(공백, 숫자 제외)만 존재하는 문자열을 만든다. (총 N개의 문자열이 생성된다)
3. 각 문자열로부터 길이가 2인 부문자열을 추출하여 set에 담는다. (총 N개의 set이 생성된다)
4. N개의 set 중 2개의 set으로 이루어진 모든 pair에 대해, 교집합의 원소의 개수와 합집합의 원소의 개수를 구한다.
뚝딱뚝딱 만들고 Syntax Error가 없길래, 됐구나 싶었는데, 실행시켜보면 계속 오답을 도출했다. Logic Error가 있었고, 그건 바로 set에 담기는 부문자열이 한글로 되어있다는 점 때문이었다. UTF-8 방식의 한글을 담고 있는 string에 곧바로 substr 메소드를 사용하니, 상식적으로 나올 수가 없는 값이 나온 것이었다. 한글을 담을 수 있는 자료형을 찾거나, 한글을 적절한 형태로 변환할 수 있어야 했다.
교수님께서는 STL set의 이점을 맛보라고 내주신 과제였지만, 생전 C++에서 쪼개본 적이 없는 한글 문자열 때문에 가장 곤란했다. 시간과 정신의 방에 들어가서 구글링을 했고, 소득이 있었다. 아래와 같은 코드로 한글을 utf16_str으로, utf16_str을 wstring으로 변환하니 substr 메소드가 문제없이 작동했다. 소스코드 출처는 여기!
// https://gist.github.com/gchudnov/c1ba72d45e394180e22f
wstring utf8_to_utf16(const string& utf8) {
wstring_convert<codecvt_utf8_utf16<char16_t>, char16_t> convert;
u16string utf16 = convert.from_bytes(utf8);
wstring wstr(utf16.begin(), utf16.end());
return wstr;
}
<bits/stdc++.h> 안에 들어있지만 존재조차 몰랐던 <locale> 라이브러리, 그 안에 들어있지도 않은 <codecvt> 라이브러리를 사용해야 했다. 이 코드를 이해하기 위해 온갖 검색어들로 다 찾아봤지만, 만족스러운 설명을 찾을 수 없었다.
저 함수 자체는 깔끔하게 짜여진 것 같은데, 내 머릿속에 있는 상이 너저분했다. 이제 표준 라이브러리의 범위 바깥에서 기능을 구현해야 할 일이 많을텐데, 그때마다 내 프로그램을 '이게 왜 되지?' 프로그램으로 만들 수는 없을 것이다. 어떻게든 공부해서 내가 직접 함수의 작동원리와 의도를 구체적으로 설명할 수 있도록 해야겠다.
경제학과 전공 수업 중 어떤 교수님은 이런 말씀을 하셨다. "완벽하게 이해했다고 말하려면, 공부한 내용을 동네 할머니도 알아들으시도록 설명할 수 있어야 한다." 무서운 분이라 교수님께서도 실제로 사용하셨던 공부법인지 여쭤보지는 못했다. 할머니...까지는 무리인 것 같고, 오늘의 나처럼 특정 기능의 구현 방법을 찾아서 방문한, 개발자 준비생이 이해할 수 있을 만큼 상세한 설명을 제공하는, 공부 블로그를 따로 만들어야겠다.