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

 

프로그래머스

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

programmers.co.kr

 

1. 문제 접근

이 문제는 문자열의 각 알파벳을 일정 거리(n) 만큼 밀어내는 문제이다.

예를 들어:

  • A를 1칸 밀면 -> B
  • B를 3칸 밀면 -> E
  • Z를 1칸 밀면 -> 다시 A

즉 알파벳이 끝까지 가면 다시 처음으로 돌아오는 순환 구조를 만들어야 한다. 여기서 핵심은 바로 % 26 이다. 알파벳은 총 26개이므로 26으로 나눈 나머지를 사용하면 자연스럽게 반복 순환을 만들 수 있다.

예를 들어:

  • (25 + 1) % 26 = 0 // (A=0 ~ Z=25)
  • 즉 Z 다음이 다시 A가 된다.

이 원리를 이용하면 복잡한 조건문 없이 깔끔하게 해결할 수 있다.

 

 

2. 풀이

  • 내가 푼 오답 코드(A)
    #include <string>
    #include <vector>
    
    using namespace std;
    
    string solution(string s, int n) {
        string answer = "";
        for(int i=0 ; i<s.size() ; i++){
            
            if(s[i] == ' '){
                answer += s[i];
                continue;
            }
            
            if(s[i]>=65 && s[i]<=90){
                s[i] = s[i]+n;
                if(s[i]>90) s[i] = s[i]-26;
            }
            else if(s[i]>=97 && s[i]<=122){
                s[i] = s[i]+n;
                if(s[i]>122) s[i] = s[i]-26;    
            }
            answer += s[i];
        }
        return answer;
    }
    ​
    - 내가 처음 풀이했던 오답 코드는 범위를 넘어가면 -26을 한번만 진행한다.
    ⇒ 예를 들어 n이 매우 커졌을때 범위가 넘어가서 오류 발생 가능

  • 정답 코드(B)
    #include <string>
    using namespace std;
    
    string solution(string s, int n) {
        string answer = "";
    
        for(int i = 0; i < s.size(); i++) {
            if(s[i] == ' ') {
                answer += ' ';
            }
            else if(s[i] >= 'A' && s[i] <= 'Z') {
                answer += (s[i] - 'A' + n) % 26 + 'A';
            }
            else if(s[i] >= 'a' && s[i] <= 'z') {
                answer += (s[i] - 'a' + n) % 26 + 'a';
            }
        }
    
        return answer;
    }
    ​
    • 핵심 문자 처리 방식
      (s[i] - 'A' + n) % 26 + 'A' // 이 부분이 가장 중요하다.
      
      // 동작과정 예시
      s[i] = 'A'라고 가정한다면 여기서 'A'를 빼면 
      'A'-'A' = 0
      즉, s[i] - 'A' 의 의미는 = 알파벳 순서를 0번부터 시작하도록 만드는 것이다.
      
      // 예시 1
      - B를 3칸 이동한다면? = E
      ('B' - 'A' + 3) % 26 + 'A'
      
      1 + 3 = 4
      4 % 26 = 4
      4 + 'A' = 'E'
      
      // 예시 2
      - Z를 1칸 이동한다면? = A
      ('Z' - 'A' + 1) % 26 + 'A'
      
      25 + 1 = 26
      26 % 26 = 0
      0 + 'A' = 'A'
      ​
    • 왜 %26이 필요한가?
      알파벳은 총 26개이기 때문에 이동한 값이 26 이상이 되면 다시 처음으로 돌아가야 한다.
      'Z' - 'A' = 25
      
      // Z를 1칸 이동
      (25 + 1) % 26 = 0
      0 + 'A' = 'A'
      
      // Z를 27칸 이동
      (25 + 27) % 26 = 0
      0 + 'A' = 'A'
      
      • 범위를 벗어나지 않게 하고
      • 다시 처음으로 돌아가게 만드는 역할을 한다.
  • A, B 코드 표로 비교비교 항목 기존 코드 정답 코드
    비교항목 A 코드 B 코드
    이동 처리 방식 문자에 n을 바로 더함 알파벳 순서를 0~25로 바꾼 뒤 계산
    순환 처리 범위 초과 시 26을 한 번 뺌 % 26으로 순환 처리
    안정성 n이 커질 경우 불안정 항상 0~25 범위 유지

 

 

3. 최종 요약

이번 문제의 핵심은 알파벳 순환 구조를 어떻게 처리하느냐이다. 처음 풀이(A)에서는 문자에 n을 직접 더한 뒤, 범위를 넘어가면 26을 한 번 빼는 방식으로 해결했다.

하지만 이 방식은 순환 처리를 조건문에 의존하기 때문에 n이 커지는 경우 안정성이 떨어질 수 있다.
정답 코드(B)에서는 알파벳을 먼저 0~25 범위의 숫자로 변환한 뒤 % 26을 사용했다.

(s[i] - 'A' + n) % 26 + 'A'

즉 % 26은 알파벳이 Z를 넘어갔을 때 다시 A로 돌아오게 해주는 핵심 연산이다.

+ Recent posts