Programmers 연습 문제_이상한 문자 만들기
출처: 프로그래머스 코딩 테스트 연습, https://programmers.co.kr/learn/challenges
요지
이 문제의 요지는
- 문자열을 공백을 기준으로 잘라 번호 붙이기
- 어떤 문자를 대문자, 소문자 화 하기
cctype
의std::toupper
,std::tolower
을 사용하는 방법- 비트 연산을 사용하는 방법
이다.
해결
요지 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]
을 대문자, 홀수이면 소문자로 바꾸면 해결된다.
cctype
의 std::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