[프로그래머스] 시저암호

2024. 10. 16. 13:59·여러가지/알고리즘 & 자료구조

시저 암호: 파이썬과 자바로 구현해보는 간단한 암호화 방식

시저 암호는 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식입니다. 예를 들어, "AB"는 1만큼 밀면 "BC"가 되고, "z"는 1만큼 밀면 "a"로 변환됩니다. 시저 암호는 알파벳이 순환하는 구조이기 때문에 "Z"를 넘어서면 다시 "A"로 돌아옵니다.

이 글에서는 파이썬(Python)과 자바(Java) 두 가지 언어로 시저 암호를 구현하고, 각각의 코드와 시간, 공간 복잡도를 분석해 보겠습니다.


문제 정의

주어진 문자열 s에서 각 알파벳을 n만큼 밀어서 암호화된 문자열을 반환하는 함수를 작성합니다.

제한 사항

  1. 공백은 밀어도 그대로 유지됩니다.
  2. 문자열 s는 알파벳 대소문자와 공백으로만 이루어져 있습니다.
  3. s의 길이는 최대 8000 이하입니다.
  4. 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"

파이썬 코드 설명

  1. 대문자 처리: ord(char) - ord('A')를 사용하여 대문자 알파벳을 0부터 25까지의 범위로 변환합니다. 그 후 n만큼 이동하고, 26으로 나눠서 알파벳이 순환되도록 처리한 후 다시 chr()로 문자로 변환합니다.
  2. 소문자 처리: 대문자 처리와 동일한 방식으로 소문자도 처리하며, 범위만 'a'에서 'z'로 조정합니다.
  3. 공백 처리: 공백은 변경하지 않고 그대로 추가됩니다.

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"
    }
}

자바 코드 설명

  1. 대문자 처리: c - 'A'를 사용해 알파벳을 0부터 25까지의 값으로 변환한 후 n만큼 이동시킨 뒤 다시 A를 더해 대문자로 변환합니다.
  2. 소문자 처리: 대문자 처리와 동일하지만 'a'를 기준으로 변환합니다.
  3. 공백 처리: 공백은 그대로 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를 사용한 자바 코드 설명

  1. s.chars(): 문자열 s를 문자 스트림으로 변환합니다.
  2. mapToObj(c -> (char) c): 각 문자를 char로 변환합니다.
  3. map(): 각 문자를 대문자, 소문자, 공백에 따라 변환합니다.
  4. collect(Collectors.joining()): 스트림을 다시 문자열로 합칩니다.

결론

시저 암호는 간단한 암호화 기법으로, 대소문자 알파벳의 순환적인 특성을 이용해 문자열을 암호화하는 방식입니다. Python과 Java에서 각각 시저 암호를 구현해보았으며, 간결한 코드와 스트림을 이용한 방법까지 다양한 방식으로 문제를 해결할 수 있습니다.

두 언어 모두 시간 복잡도는 O(n)이며, 공간 복잡도 역시 O(n)로 효율적으로 처리할 수 있습니다.

저작자표시 (새창열림)

'여러가지 > 알고리즘 & 자료구조' 카테고리의 다른 글

[프로그래머스] 숫자 문자열과 영단어  (0) 2024.10.16
[프로그래머스] 가장 가까운 같은 글자  (0) 2024.10.16
[프로그래머스] 핸드폰 번호 가리기  (2) 2024.10.14
[프로그래머스] 음양 더하기  (1) 2024.10.14
[프로그래머스] 콜라츠 추측  (0) 2024.10.14
'여러가지/알고리즘 & 자료구조' 카테고리의 다른 글
  • [프로그래머스] 숫자 문자열과 영단어
  • [프로그래머스] 가장 가까운 같은 글자
  • [프로그래머스] 핸드폰 번호 가리기
  • [프로그래머스] 음양 더하기
hyeseong-dev
hyeseong-dev
안녕하세요. 백엔드 개발자 이혜성입니다.
  • hyeseong-dev
    어제 오늘 그리고 내일
    hyeseong-dev
  • 전체
    오늘
    어제
    • 분류 전체보기 (286)
      • 여러가지 (107)
        • 알고리즘 & 자료구조 (72)
        • 오류 (4)
        • 이것저것 (29)
        • 일기 (1)
      • 프레임워크 (39)
        • 자바 스프링 (39)
        • React Native (0)
      • 프로그래밍 언어 (38)
        • 파이썬 (30)
        • 자바 (3)
        • 스프링부트 (5)
      • 컴퓨터 구조와 운영체제 (3)
      • DB (17)
        • SQL (0)
        • Redis (17)
      • 클라우드 컴퓨팅 (2)
        • 도커 (2)
        • AWS (0)
      • 스케쥴 (65)
        • 세미나 (0)
        • 수료 (0)
        • 스터디 (24)
        • 시험 (41)
      • 트러블슈팅 (1)
      • 자격증 (0)
        • 정보처리기사 (0)
      • 재태크 (5)
        • 암호화폐 (5)
        • 기타 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    취업리부트
    ecs
    프로그래머스
    SAA
    OOP
    파이썬
    java
    DP
    docker
    reactor
    Spring WebFlux
    완전탐색
    항해99
    Python
    그리디
    RDS
    Redis
    시험
    EC2
    Docker-compose
    자바
    spring
    백준
    Spring Boot
    celery
    FastAPI
    AWS
    WebFlux
    mybatis
    #개발자포트폴리오 #개발자이력서 #개발자취업 #개발자취준 #코딩테스트 #항해99 #취리코 #취업리부트코스
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
hyeseong-dev
[프로그래머스] 시저암호
상단으로

티스토리툴바