안녕하세요. 조경완입니다. 오랫만에 구현 카데고리로 돌아왔습니다. 문자열 뒤집기는 코테 뿐만이 아니라 면접에서도 물어볼 수 있는 내용입니다. 문제는, 이것입니다.

 

 한글 때문에 조심해야 합니다. 이는, 한글이 1byte로 표현되지 않기 때문입니다. 그리고, 어떤 방식으로 인코딩 된 문자열인지도 언급되지 않았으니, 이 부분도 질문하시는 게 좋겠습니다. 그리고 해당 인코딩으로 표현 가능한 문자 셋만 들어오는지도 질문 해 두면 좋겠습니다.


 아래 Solve 클래스 내에 있는 revGetByte를 생각해 보겠습니다. 이 함수는 EUC-KR로 b0a1 b3aa로 인코딩 된 바이트를 b3aa b0a1로 바꾸는 함수입니다. 그리고 이 결과물을 파일 b에다가 씁니다. 파일 a도 EUC-KR로, b도 EUC-KR로 인코딩 되어 있다고 해 보겠습니다. 어떻게 구현해야 할까요?

 

 

 이렇게 답변하기 쉽습니다. 이게 어떻게 수행되는지 봅시다.

 

 

 "가나"를 EUC-KR로 인코딩 하면 이렇게 들어옵니다. 크기가 4인 byte 배열입니다. 위에서 보시는 코드는 input의 역순으로 ans에 넣는 것인데요. 다 넣고 나면 ans에는 아래와 같이 들어갈 겁니다.

 

 

 그러면 이 바이트 배열은, 인풋을 EUC-KR로 디코딩 한 것을 뒤집어서 다시 EUC-KR로 인코딩 한 배열일까요?

 

 

 아닙니다. EUC-KR에서 한글은 1byte 단위로 표현이 되지 않기 때문입니다. 그렇기 때문에, 바이트 자체를 reverse 하는 것은 잘못된 풀이입니다. C언어에서 문자열을 뒤집을 때, 이 부분은 조심해야 합니다. char형의 크기가 1byte인 경우에, UTF-8로 인코딩된 문자열 안에 있는 한글은 char형 하나로 표현할 수 없기 때문입니다. 그러면 어떻게 해야 할까요? 유니 코드로 변환을 하던지, 혹은, 디코딩을 먼저 하시면 됩니다.

 

 


 byte 단위로 읽어냈다면, 혹은 인코딩 된 문자열이 byte 단위로 들어왔다면, 이것을 디코딩을 해야 할 겁니다.

 

 

 그 전에, 우리가 리턴해야 할 것이, byte 배열입니다. 그러니, ans에는 빈 byte 배열을 가리키게 해 보겠습니다. null을 리턴하면, 받은 쪽에서 귀찮은 처리가 들어가야 하니, 빈 배열을 리턴하게 하는 것은 나쁘지 않습니다.

 

 

 다음에, String을 하나 새로 생성한 것이 눈에 보이는데요. 인코딩 된 charset이 "EUC-KR"임을 알았다면, 디코드를 하면 됩니다. 저 문장은, 해당 byte 배열이 EUC-KR로 디코딩 하라는 정보를 넘겨줘서 적절히 String으로 변환하는 부분입니다.

 

 

 5번째 줄의 생성자는 위 코드를 호출합니다. 그리고 이것은 아래에 있는 생성자를 호출하는데요.

 

 

 여기서 중요한 것은 426번째 줄입니다. StringCoding.decode 부분입니다. 이 부분에서 charsetName 방식으로 디코딩을 하게 됩니다. 당연하게도, EUC-KR로 인코딩이 되었는데, UTF-8로 디코딩을 하라고 하면 안 될 겁니다. 인코딩, 디코딩 쌍이 다르기 때문입니다.

 

 다음에, StringBuilder를 선언합니다. 그리고 str의 맨 뒤에서부터 거꾸로 탐색하면서 sb에 append를 해 나갑니다. 물론, 동적 배열 말고 정적 배열로 처리하는 방법도 있습니다.

 

 

 우리는 string의 길이를 알고 있습니다. 원본 문자열을 뒤집은 것의 길이도 원본과 같기 때문에, str.length()만큼 미리 할당해 놓을 수 있습니다. 이제, 거꾸로 탐색하면서 sb에 채워넣으면 됩니다. 저는 이 방법으로 처리했습니다.

 


 다음에, 처리된 string을 리턴하라는 것이 아니라, 이 결과를 EUC-KR로 다시 인코딩을 해서 저장을 하라고 했으므로 아래와 같이 코딩을 하시면 됩니다.

 

 그러면 해당 String이 EUC-KR로 인코딩 된 결과가 byte 배열로 담깁니다. 우리는 ans 배열을 리턴하면 됩니다.

 

 

 이제, 이 문제를 풀어봅시다. 위에 나온 조건에서 우리가 써야 할 파일의 인코딩이 EUC-KR에서 UTF-8로 바뀌었을 뿐입니다. 그러면, 뒤집은 결과물에서 getBytes 메서드를 호출하는 부분만 살짝 바꾸시면 됩니다.

 

 

 "UTF-8"이 어디에 들어갔는지만 보시면 됩니다. 이모지까지 들어간 경우에는 어떻게 하면 좋을까요? 이 부분은 조금 더 생각해 봅시다.