링크: https://school.programmers.co.kr/learn/courses/30/lessons/68935?language=cpp

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

1. 문제 접근

이 문제는 10진수를 3진법으로 바꾼 뒤, 그 값을 뒤집고 다시 10진수로 변환하는 문제이다.

핵심은 진법 변환 과정에서 나머지가 뒤에서부터 나온다는 점이다.

 

예를 들어 45를 3진법으로 바꾸면 다음과 같다.

45의 3진법 = 1200
뒤집은 값 = 0021
10진수 변환 = 7

따라서 10진수를 3으로 계속 나누면서 나머지를 저장(to_string()함수 활용)하면, 자연스럽게 뒤집힌 3진법 문자열을 만들 수 있다.

 

2. 풀이 (2개)

    • 1번 풀이 (reverse없이 바로 사용)
      #include <string>
      #include <cmath>
      
      using namespace std;
      
      int solution(int n) {
          string s;
          int answer = 0;
          
          // 먼저 while문에서 n % 3을 통해 3으로 나눈 나머지를 구한다.
          // 진법 변환 핵심 아이디어 코드(while문)
          while (n != 0) { 
              s += to_string(n % 3);
              n /= 3;
          }
          
          for (int i = 0; i < s.size(); i++) {
              answer += (s[i] - '0') * pow(3, s.size() - 1 - i);
          }
          
          return answer;
      }
      - to_string(): 숫자 타입 설명 : (참고) 숫자를 문자열로 변환(123 => "123") to_string() 함수

      먼저 while문에서 n % 3을 통해 3으로 나눈 나머지를 구한다.
      이후 to_string 함수 통해 나머지를 문자열에 순서대로 저장하면 3진법 숫자가 뒤집힌 형태로 저장된다.
      s += to_string(n % 3);
      n /= 3;
      45를 3진법 역순한 수 (0021)


    • 2번 풀이(reverse 사용하여 pow 안의 idx 활용 단순하게 하기)
      #include <string>
      #include <vector>
      #include <algorithm>
      #include <cmath>
      
      using namespace std;
      
      int solution(int n) {
          int a=0;
          string s;
          int answer = 0;
          
          while(n!=0){
              s+=to_string(n%3);
              n = n/3;
          }
          reverse(s.begin(), s.end()); 
          // 정상적인 3진법으로 바꿔주기 위해서 reverse함수 사용 => pow(3,i) 으로 사용하기 위함
         
          for(int i=0 ;i<s.size(); i++){        
              int a = (s[i]-'0')*pow(3,i);
              answer += a;
          }
          return answer;
      }
       - 예를들어 n이 45라면 while문을 통과하고 난 다음에 s: 0021이 저장이 된다.(3진법 뒤집은 결과)
      - revere 함수를 통해 정상적인 3진법으로 변환 = 1200  => pow(3, i)로 인덱스를 단순하게 사용하기 목적

      while문으로 나머지를 저장하면 문자열은 이미 뒤집힌 3진법 형태로 만들어진다.
      이 상태에서 바로 10진수로 변환하려면 pow(3, s.size() - 1 - i)처럼 자릿수를 계산해야 한다.
      
      하지만 인덱스를 더 단순하게 사용하기 위해 reverse()로 문자열을 정상적인 3진법 형태로 바꿔주었다.
      그 후 pow(3, i)를 사용하면 i가 0부터 증가하면서 3⁰, 3¹, 3² 순서로 계산할 수 있다.
      
      즉, reverse()는 정답을 만들기 위한 필수 과정이라기보다,
      pow(3, i) 형태로 인덱스를 쉽게 사용하기 위한 처리라고 볼 수 있다.

 

  • 1번 2번풀이 표로 정리(n=45 기준)
    구분 1번 풀이 2번 풀이
    방식 뒤집힌 3진법 문자열을 그대로 사용 reverse()로 정상 3진법처럼 바꾼 뒤 사용
    while문 결과 "0021" "0021"
    reverse 사용 사용 안 함 사용함
    계산 방식 pow(3, s.size() - 1 - i) pow(3, i)
    장점 문제 흐름과 가장 직접적으로 연결됨 인덱스를 단순하게 사용할 수 있음
    단점 제곱 위치 계산식이 조금 복잡함 reverse()를 왜 하는지 헷갈릴 수 있음
    핵심 의미 뒤집힌 값을 그대로 10진수 변환 pow(3, i)를 쉽게 쓰기 위한 처리

 

3. 문법

  • to_string()
    s += to_string(n % 3);
    - to_string()은 숫자를 문자열로 바꿔주는 함수이다.
    - 예를 들어 2를 "2"로 바꿔 문자열에 붙일 수 있다.

 
  • s[i] - '0'
    (참고) 문자형태의 숫자 -> 정수 숫자로 바꾸기 (’7’ → 7)  
    s[i] - '0'
    
    '2' - '0' = 2
    '1' - '0' = 1
    - 문자 형태의 숫자를 실제 정수로 바꾸는 코드이다.


  • 4) pow()
    이 풀이에서는 pow() 함수를 사용하기 때문에 <cmath> 헤더가 필요하다.
    #include <cmath>
    
    pow(3, s.size() - 1 - i)
    - pow(a, b)는 a의 b제곱을 구하는 함수이다.
    - 이 문제에서는 3진법을 10진법으로 변환하기 위해 사용한다.

 

4. 최종 요약

이 문제의 핵심은 10진수를 3진법으로 변환할 때 나머지가 뒤쪽 자리부터 나온다는 점이다.

n % 3으로 나머지를 구하고 n /= 3으로 숫자를 줄여나가면, 문자열에는 자연스럽게 뒤집힌 3진법 값이 저장된다.

이 값을 그대로 사용하면 pow(3, s.size() - 1 - i)로 계산하고,
reverse()를 사용하면 pow(3, i)처럼 인덱스를 더 단순하게 사용할 수 있다.

결국 두 풀이 모두 핵심은 3진법 변환 → 뒤집힌 값 처리 → 10진수 변환이다.

+ Recent posts