Python/알고리즘

프로그래머스-파이썬 (시저 암호)

SeongWon 2021. 1. 13. 18:07
반응형

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

 

<제한사항>

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

 

<예시>

 


<해결과정>

 

문제를 보고 처음에는 모든 알바펫을 담아놓은 리스트가 필요하다 생각해서 하나하나 작성하고 있었다.

심지어 소문자, 대문자를 따로따로 해놓은 2개의 리스트를 별도로 손수 작성하고 있자니 이게 맞나싶어서 찾아보았다.

 

정말 고맙게도 파이썬에서는 알파벳 데이터를 상수로 정의해놓았다고 한다.

from string import ascii_lowercase, ascii_uppercase

lower_case= ascii_lowercase # 소문자 abcdefghijklmnopqrstuvwxyz
upper_case= ascii_uppercase # 대문자 ABCDEFGHIJKLMNOPQRSTUVWXYZ

이런식으로 파이썬이 정의해놓은 알파벳 데이터를 변수로 정의해서 사용할 수 있었다.

 

<내 풀이>

from string import ascii_lowercase, ascii_uppercase
def solution(s, n):
    answer = ''
    s = list(s)
    
    lower_list= list(ascii_lowercase)
    upper_list= list(ascii_uppercase)

우선 입력 데이터 문자열 s를 리스트로 변환하고 대문자, 소문자 ascii string 객체도 리스트로 변환하고 시작했다.

n만큼의 알파벳 자리를 이동시키려면 우선 인덱스가 필요하다고 가장 먼저 느꼈기 때문이다.

 

....
    for i in range(len(s)):
        if s[i] in lower_list:
            idx = lower_list.index(s[i])
            
            if idx+n < len(lower_list):
                s[i] = lower_list[idx+n]
            else:
                s[i] = lower_list[(idx+n)%26]
        
        elif s[i] in upper_list:
            idx = upper_list.index(s[i])
            
            if idx+n < len(upper_list):
                s[i] = upper_list[idx+n]
            else:
                s[i] = upper_list[(idx+n)%26]
                
    answer = ''.join(s)
    
    return answer

입력문자열 s의 i 번째 알파벳이 전체 알파벳에서는 몇 번째 알파벳인지를 알기 위한 idx를 정의해준다.

그리고 s의 i 번째 알파벳을 n만큼 이동시킨 알파벳(idx+n번째)으로 변환해주는데 이때 중요한 점이 있다.

 

idx+n번째 알파벳은 전체 알파벳의 범위를 넘어서면 다시 a(A)부터 시작하여 이동해야 한다. ex) z , 1 , a

그렇기때문에 idx+n이 범위를 넘어가는 경우는 전체 알파벳의 "(idx+n)%26" 번째로 인덱스를 주었다. (알파벳 개수=26)

 

마무리는 로직의 결과로 나온 알파벳 리스트 answer를 다시 문자열로 병합해주면 해결!

 

반응형