#021 코드 처리하기

Hyejin Kim·2023년 5월 4일
0

문제

문자열 code가 주어집니다.
code를 앞에서부터 읽으면서 만약 문자가 "1"이면 mode를 바꿉니다. mode에 따라 code를 읽어가면서 문자열 ret을 만들어냅니다.
mode는 0과 1이 있으며, idx를 0 부터 code의 길이 - 1 까지 1씩 키워나가면서 code[idx]의 값에 따라 다음과 같이 행동합니다.
mode가 0일 때
code[idx]가 "1"이 아니면 idx가 짝수일 때만 ret의 code[idx]를 추가합니다.
code[idx]가 "1"이면 mode를 0에서 1로 바꿉니다.
mode가 1일 때
code[idx]가 "1"이 아니면 idx가 홀수일 때만 ret의 맨 뒤에 code[idx]를 추가합니다.
code[idx]가 "1"이면 mode를 1에서 0으로 바꿉니다.
문자열 code를 통해 만들어진 문자열 ret를 return 하는 solution 함수를 완성해 주세요.
단, 시작할 때 mode는 0이며, return 하려는 ret가 만약 빈 문자열이라면 대신 "EMPTY"를 return 합니다.

제한사항

1 ≤ code의 길이 ≤ 100,000
code는 알파벳 소문자 또는 "1"로 이루어진 문자열입니다.

입출력 예

code	         result
"abc1abc1abc"	 "acbac"

입출력 예 설명

입출력 예 #1

code의 각 인덱스 i에 따라 다음과 같이 mode와 ret가 변합니다.

i	code[i]	mode	ret
0	"a"	0	"a"
1	"b"	0	"a"
2	"c"	0	"ac"
3	"1"	1	"ac"
4	"a"	1	"ac"
5	"b"	1	"acb"
6	"c"	1	"acb"
7	"1"	0	"acb"
8	"a"	0	"acba"
9	"b"	0	"acba"
10	"c"	0	"acbac"

따라서 "acbac"를 return 합니다.

베스트 해법

char *solution2(const char *code) {
  int idx = 0, mode = 0, len = strlen(code);
  char *answer = (char *)malloc(100001);
  for (int i = 0; i < len; i++) {
    if (code[i] == '1')
      mode = 1 - mode;
    else {
      if (mode) {
        if (i & 1) 
          answer[idx++] = code[i];
      } else {
        if (!(i & 1))
          answer[idx++] = code[i];
      }
    }
  }
  answer[idx] = '\0';
  if (!idx)
    strcpy(answer, "EMPTY");
  return answer;
}

코드 설명

  • 먼저 idx 변수는 가공된 문자열의 인덱스, mode 변수는 현재 짝수/홀수 모드를 나타내며, len 변수는 주어진 문자열의 길이를 저장합니다. 그리고 answer 변수는 가공된 문자열을 저장할 메모리를 동적으로 할당합니다.

  • 그리고 반복문을 통해 주어진 문자열을 한 글자씩 순회합니다. 만약 현재 글자가 '1'인 경우에는 mode 변수를 뒤집어주어 짝수/홀수 모드를 변경합니다.

  • 만약 현재 글자가 '1'이 아닌 경우에는 현재 짝수/홀수 모드에 따라서 해당 글자를 선택하고, answer 변수에 저장합니다. i & 1은 현재 인덱스 i가 짝수인지 홀수인지를 판단하는 비트 연산입니다. 이 비트 연산 결과가 1인 경우에는 현재 인덱스가 홀수이므로, 홀수 모드일 때 선택해야 하는 글자입니다.

  • 마지막으로, 가공된 문자열에 null 문자를 추가하고, 만약 가공된 문자열이 비어있는 경우에는 "EMPTY"라는 문자열을 복사하여 answer 변수에 저장합니다. 그리고 가공된 문자열을 반환합니다.

비트연산에 대해

  • &는 비트 AND 연산자이며, 두 비트의 대응되는 자리를 비교하여 둘 다 1인 경우에만 결과값이 1이 됩니다. i & 1은 i와 1의 비트 AND 연산을 수행한 결과를 반환합니다.

  • 이 비트 AND 연산은 주로 짝수/홀수 판별에 사용되는데, 2로 나눈 나머지가 0이면 짝수, 1이면 홀수이기 때문입니다. 이를 비트 연산으로 표현하면, 짝수인 경우에는 이진수로 표현했을 때 가장 오른쪽 비트가 0이 되므로, i & 1 연산 결과는 항상 0이 됩니다. 반면 홀수인 경우에는 가장 오른쪽 비트가 1이 되므로, i & 1 연산 결과는 항상 1이 됩니다.

  • 따라서 i & 1은 i가 짝수인지 홀수인지를 판별하는 데에 매우 편리한 비트 연산입니다.

나의 풀이

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

char* solution1(const char* code) {
    int len = strlen(code); // sizeof() 가 아닌 strlen()를 사용하여 문자열의 길이를 알아낸다
  char *answer = (char *)malloc(len + 1); // +1 해주는거 잊지마.

  int mode = 0;
  int index = 0;
  for (int i = 0; i < len; i++) {
    if (mode == 0) {
      if (code[i] != '1' && i % 2 == 0)
        answer[index++] = code[i]; // 이 문장을 실행 후 index 의 값에 +1을 한다.
      else if (code[i] == '1')
        mode = 1;
    } else if (mode == 1) {
      if (code[i] != '1' && i % 2 != 0)
        answer[index++] = code[i];
      else if (code[i] == '1')
        mode = 0;
    }
  }

  if (index == 0) {
    strcpy(answer, "EMPTY");
    index = 5;
  }
  answer[index] = '\0'; // 문장의 마침표 같은 역할

  printf("%s", answer);
  return answer;
  // free(answer); 해주어야 하는데.. 
  // *answer = NULL;
}

문제출처

코딩테스트

profile
Hello. I am a developer who is still developing.

0개의 댓글