시저 암호: 파이썬과 자바로 구현해보는 간단한 암호화 방식
시저 암호는 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식입니다. 예를 들어, "AB"
는 1만큼 밀면 "BC"
가 되고, "z"
는 1만큼 밀면 "a"
로 변환됩니다. 시저 암호는 알파벳이 순환하는 구조이기 때문에 "Z"
를 넘어서면 다시 "A"
로 돌아옵니다.
이 글에서는 파이썬(Python)과 자바(Java) 두 가지 언어로 시저 암호를 구현하고, 각각의 코드와 시간, 공간 복잡도를 분석해 보겠습니다.
문제 정의
주어진 문자열 s
에서 각 알파벳을 n만큼 밀어서 암호화된 문자열을 반환하는 함수를 작성합니다.
제한 사항
- 공백은 밀어도 그대로 유지됩니다.
- 문자열
s
는 알파벳 대소문자와 공백으로만 이루어져 있습니다. s
의 길이는 최대 8000 이하입니다.n
은 1 이상, 25 이하의 자연수입니다.
입출력 예시
s | n | result |
---|---|---|
"AB" | 1 | "BC" |
"z" | 1 | "a" |
"a B z" | 4 | "e F d" |
1. 파이썬(Python) 코드 구현
def solution(s, n):
result = []
for char in s:
# 대문자 처리
if 'A' <= char <= 'Z':
shifted = (ord(char) - ord('A') + n) % 26 + ord('A')
result.append(chr(shifted))
# 소문자 처리
elif 'a' <= char <= 'z':
shifted = (ord(char) - ord('a') + n) % 26 + ord('a')
result.append(chr(shifted))
# 공백 처리
else:
result.append(char)
return ''.join(result)
# 테스트 예시
print(solution("AB", 1)) # 출력: "BC"
print(solution("z", 1)) # 출력: "a"
print(solution("a B z", 4)) # 출력: "e F d"
파이썬 코드 설명
- 대문자 처리:
ord(char) - ord('A')
를 사용하여 대문자 알파벳을 0부터 25까지의 범위로 변환합니다. 그 후n
만큼 이동하고, 26으로 나눠서 알파벳이 순환되도록 처리한 후 다시chr()
로 문자로 변환합니다. - 소문자 처리: 대문자 처리와 동일한 방식으로 소문자도 처리하며, 범위만
'a'
에서'z'
로 조정합니다. - 공백 처리: 공백은 변경하지 않고 그대로 추가됩니다.
2. 자바(Java) 코드 구현
class Solution {
public String solution(String s, int n) {
StringBuilder result = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
// 대문자 처리
if (c >= 'A' && c <= 'Z') {
result.append((char) ((c - 'A' + n) % 26 + 'A'));
}
// 소문자 처리
else if (c >= 'a' && c <= 'z') {
result.append((char) ((c - 'a' + n) % 26 + 'a'));
}
// 공백 처리
else {
result.append(c);
}
}
return result.toString();
}
public static void main(String[] args) {
Solution sol = new Solution();
System.out.println(sol.solution("AB", 1)); // 출력: "BC"
System.out.println(sol.solution("z", 1)); // 출력: "a"
System.out.println(sol.solution("a B z", 4));// 출력: "e F d"
}
}
자바 코드 설명
- 대문자 처리:
c - 'A'
를 사용해 알파벳을 0부터 25까지의 값으로 변환한 후n
만큼 이동시킨 뒤 다시A
를 더해 대문자로 변환합니다. - 소문자 처리: 대문자 처리와 동일하지만
'a'
를 기준으로 변환합니다. - 공백 처리: 공백은 그대로
StringBuilder
에 추가됩니다.
3. 시간 및 공간 복잡도 분석
시간 복잡도
- 문자열의 길이를
n
이라고 할 때, 파이썬과 자바 모두 문자열의 각 문자를 한 번씩 순회하면서 처리를 합니다. 각 문자는 상수 시간 내에 처리되므로 O(n)의 시간 복잡도를 가집니다.
공간 복잡도
- 파이썬에서는 새로운 리스트
result
에 변환된 문자를 저장하고, 최종적으로 이를 문자열로 변환하므로 O(n)의 공간 복잡도를 가집니다. - 자바에서는
StringBuilder
를 사용하여 문자열을 조립하므로, 메모리 복잡도는 O(n)입니다.
4. 다른 자바 코드 풀이 방식
자바에서는 Stream API를 이용해 더 간결한 방식으로도 시저 암호를 구현할 수 있습니다. 아래 코드는 Stream
을 사용한 변형된 풀이입니다.
import java.util.stream.Collectors;
class Solution {
public String solution(String s, int n) {
return s.chars()
.mapToObj(c -> (char) c)
.map(c -> {
if (Character.isUpperCase(c)) {
return (char) ((c - 'A' + n) % 26 + 'A');
} else if (Character.isLowerCase(c)) {
return (char) ((c - 'a' + n) % 26 + 'a');
} else {
return c;
}
})
.map(String::valueOf)
.collect(Collectors.joining());
}
public static void main(String[] args) {
Solution sol = new Solution();
System.out.println(sol.solution("AB", 1)); // 출력: "BC"
System.out.println(sol.solution("z", 1)); // 출력: "a"
System.out.println(sol.solution("a B z", 4));// 출력: "e F d"
}
}
Stream API를 사용한 자바 코드 설명
s.chars()
: 문자열s
를 문자 스트림으로 변환합니다.mapToObj(c -> (char) c)
: 각 문자를char
로 변환합니다.map()
: 각 문자를 대문자, 소문자, 공백에 따라 변환합니다.collect(Collectors.joining())
: 스트림을 다시 문자열로 합칩니다.
결론
시저 암호는 간단한 암호화 기법으로, 대소문자 알파벳의 순환적인 특성을 이용해 문자열을 암호화하는 방식입니다. Python과 Java에서 각각 시저 암호를 구현해보았으며, 간결한 코드와 스트림을 이용한 방법까지 다양한 방식으로 문제를 해결할 수 있습니다.
두 언어 모두 시간 복잡도는 O(n)이며, 공간 복잡도 역시 O(n)로 효율적으로 처리할 수 있습니다.
'여러가지 > 알고리즘 & 자료구조' 카테고리의 다른 글
[프로그래머스] 숫자 문자열과 영단어 (0) | 2024.10.16 |
---|---|
[프로그래머스] 가장 가까운 같은 글자 (0) | 2024.10.16 |
[프로그래머스] 핸드폰 번호 가리기 (0) | 2024.10.14 |
[프로그래머스] 음양 더하기 (1) | 2024.10.14 |
[프로그래머스] 콜라츠 추측 (0) | 2024.10.14 |