어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식을 시저 암호라고 합니다. 예를 들어 "AB"는 1만큼 밀면 "BC"가 되고, 3만큼 밀면 "DE"가 됩니다. "z"는 1만큼 밀면 "a"가 됩니다. 문자열 s와 거리 n을 입력받아 s를 n만큼 민 암호문을 만드는 함수
제한 조건
공백은 아무리 밀어도 공백입니다.
s는 알파벳 소문자, 대문자, 공백으로만 이루어져 있습니다.
s의 길이는 8000이하입니다.
n은 1 이상, 25이하인 자연수입니다.
#include <string>
#include <vector>
using namespace std;
string solution(string s, int n) {
string answer = "";
// 문자열 한 글자씩 확인
for (int i = 0; i < s.length(); i++) {
// 공백인 경우, answer에 공백 그대로
if (s[i] == ' ') {
answer += ' ';
}
// 대문자인 경우 밀어낸 글자 answer 넣기
else if (s[i] >= 'A' && s[i] <= 'Z') {
answer += (s[i] - 'A' + n) % 26 + 'A';
}
// 소문자인 경우 밀어낸 글자 answer 넣기
else if (s[i] >= 'a' && s[i] <= 'z') {
answer += (s[i] - 'a' + n) % 26 + 'a';
}
}
return answer;
}
AI가 작성한 코드
#include <string>
using namespace std;
string solution(string s, int n) {
// 1. 빈 문자열에 한 글자씩 이어 붙이지 않고, 원본을 그대로 통째로 복사
string answer = s;
// 2. 인덱스(i) 대신 범위 기반 for문과 참조(&)를 사용하여 글자들을 직접 수정
for (char& c : answer) {
if (c >= 'A' && c <= 'Z') {
c = (c - 'A' + n) % 26 + 'A';
} else if (c >= 'a' && c <= 'z') {
c = (c - 'a' + n) % 26 + 'a';
}
// 공백(' ')은 위 조건에 모두 해당하지 않으므로 아무런 추가 연산 없이 원본 그대로 유지
}
return answer;
}
'메모리 재할당 방지'에 초점을 맞춘 방식
문자열에 글자를 계속 이어 붙이다가 미리 준비된 메모리 공간이 꽉 차면, 컴퓨터는 어딘가에 더 큰 빈 공간을 새로 할당받고 기존 글자들을 전부 새집으로 이사시키는 작업을 백그라운드에서 수행함. 문자열이 8,000자까지 길어질 수 있는 이 문제의 조건상, 반복문 안에서 이런 이사 작업이 여러 번 발생하면 시스템에 미세한 병목이 쌓이게 됨
따라서 아예 처음부터 string answer = s;를 통해 원본과 똑같은 크기의 방을 한 번만 할당해두기.
그다음 for (char& c : answer)를 통해 배열의 주소를 직접 참조(&)하며 그 방 안에서 글자들만 덮어씌우고 불필요했던 공백 확인용 if (c == ' ') 분기문 제거하고, 컴퓨터가 조건문 때문에 실행 흐름을 멈칫거리는 일조차 없도록 코드의 흐름을 직선으로 펴주었음