코드카타

시저 암호

문제 설명
어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식을 시저 암호라고 합니다. 예를 들어 "AB"는 1만큼 밀면 "BC"가 되고, 3만큼 밀면 "DE"가 됩니다. "z"는 1만큼 밀면 "a"가 됩니다. 문자열 s와 거리 n을 입력받아 s를 n만큼 민 암호문을 만드는 함수, solution을 완성해 보세요.

제한 조건
공백은 아무리 밀어도 공백입니다.
s는 알파벳 소문자, 대문자, 공백으로만 이루어져 있습니다.
s의 길이는 8000이하입니다.
n은 1 이상, 25이하인 자연수입니다.

#include <string>
#include <vector>

using namespace std;

string solution(string s, int n) {
    string answer = "";

    for (char c : s)
    {
        if (c == ' ') 
        {
            answer += ' ';
            continue; 
        }

        if (islower(c))
        {
            if (c + n > 'z')
            {
                answer += (c + n - 26);
                continue;
            }
        }
        else
        {
            if (c + n > 'Z')
            {
                answer += (c + n - 26);
                continue;
            }

        }

        answer += c + n;
    }

    return answer;
}

 

공백 생략 조건문과 소문자, 대문자 확인 후 'z' 와 'Z'의 아스키값을 넘어가는 값을 처리해주었다. 

 

직접 풀고난 후 Gemini 에게 리팩토링을 요청해 봤다.

#include <string>
#include <cctype> // islower, isupper 함수를 사용하기 위해 포함

using namespace std;

string solution(string s, int n) {
    string answer = "";

    for (char c : s) {
        // 1. 공백 처리: 공백은 밀어도 공백이므로 바로 추가 후 다음 문자로 이동
        if (c == ' ') {
            answer += c;
            continue;
        }

        // 2. 기준점(base) 설정: 대문자인지 소문자인지 판별하여 시작점 지정
        // 'A' 또는 'a'를 기준으로 삼아 알파벳 순환 계산을 단순화합니다.
        char base = islower(c) ? 'a' : 'A';

        /* 3. 핵심 로직:
           - (c - base): 현재 문자가 알파벳 중 몇 번째(0~25)인지 계산
           - (+ n): 이동할 거리만큼 더함
           - (% 26): 26(알파벳 개수)으로 나눈 나머지를 구하여 'z'를 넘어가면 'a'로 순환하게 만듦
           - (+ base): 다시 아스키 코드 값으로 복구
           
           ※ 주의: (c - base + n) 과정에서 c + n을 먼저 하면 char 범위를 넘을 수 있으므로 
              base를 먼저 빼주는 순서가 안전합니다.
        */
        answer += (c - base + n) % 26 + base;
    }

    return answer;
}

 

단 3줄... 수학을 섞으면 훨씬 간단해질 수 있다. 수학적 접근으로 다음 문제부턴 간소화를 할 수 있도록 노력해야겠다...

+ Recent posts