Programmers 연습 문제_이상한 문자 만들기

1 minute read

출처: 프로그래머스 코딩 테스트 연습, https://programmers.co.kr/learn/challenges

문제 바로가기

요지

이 문제의 요지는

  1. 문자열을 공백을 기준으로 잘라 번호 붙이기
  2. 어떤 문자를 대문자, 소문자 화 하기
    1. cctypestd::toupper, std::tolower을 사용하는 방법
    2. 비트 연산을 사용하는 방법

이다.

해결

요지 1

먼저 요지 1의 해결 방법은 항상 번호 idx을 1 씩 증가하되, 문자열 전체를 처리하는 과정에서 공백이 나오면 번호 idx을 0으로 바꾸고 건너뛰면 해결된다.

for(i = 0; i < len; i++) {
    if(answer[i] == ' ') { // 매개변수 s는 answer에 복사됨
        idx = 0;
        continue;
    }
    // TODO: 대문자, 소문자 변경 코드 작성하기
    idx++;
}

요지 2

다음, 요지 2는 번호 idx 이 짝수이면 answer[i]을 대문자, 홀수이면 소문자로 바꾸면 해결된다.

cctypestd::toupper, std::tolower을 사용하는 방법

어떤 문자를 대문자로 바꾸는 방법은 std::toupper을 사용하면 된다. 소문자도 마찬가지이다. 코드는 다음과 같다:

answer[i] = idx & 1 ? answer[i] = tolower(answer[i]) : answer[i] = toupper(answer[i]);

비트 연산을 사용하는 방법

동일한 문자의 대문자와 소문자의 차이는 32(00100000: 이진 수)이므로 대문자에 32를 더한다는 것은 5 번째 비트를 1로 바꿔 소문자로 바꾼다는 의미이며, 소문자도 마찬가지이다. 이에 따라 어떤 문자의 5 번째 비트를 항상 0 또는 1로 바꿀 수 있는 연산자를 찾으면 된다.

대문자

먼저 다음 AND 진리표를 보자(일부):

answer[i] 상수 결괏값
0(대문자) 0 0(대문자)
1(소문자) 0 0(대문자)

이를 보면 0(대문자) 또는 1(소문자)와 0을 & 연산자를 이용해 연산하면 항상 0(대문자)이 나온다. 예를 들어 'a' & 11011111'A'가 된다.

소문자

OR 진리표(일부):

answer[i] 상수 결괏값
0(대문자) 1 1(소문자)
1(소문자) 1 1(소문자)

이를 보면 0(대문자) 또는 1(소문자)와 1을 | 연산자를 이용해 연산하면 항상 1(소문자)이 나온다. 예를 들어 'A' | 00100000'a'가 된다.

완성된 코드는 다음과 같다:

answer[i] = idx & 1 ? answer[i] | 0x20 : answer[i] & 0xDF;

이 글에 잘못된 내용이 있을 경우 알려주시기 바랍니다.

Leave a comment