티스토리 뷰

문제 설명

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

제한 조건

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

 

💡 나의 풀이 

  • 처음엔 비트연산자인 shift 방식으로 생각했었다. 시도했다가 아닌 것 같아서 아스키코드로 치환해서 풀어야겠다고 생각했다. 문자열을 아스키코드 값으로 변환해주는 ord(string)을 사용하여 + n을 해주었는데 z or Z를 벗어나는 문제가 생겼다. 막막해 했다가 다른 사람의 풀이를 보고 힌트를 얻었다. 
def solution(s, n):
    s = list(s)
    
    for i in range(len(s)):
        if s[i].isupper():
            s[i]=chr((ord(s[i])-ord('A')+ n)%26+ord('A'))
        elif s[i].islower():
            s[i]=chr((ord(s[i])-ord('a')+ n)%26+ord('a'))

    return "".join(s)

 

  • 각 문자열을 하나씩 쪼개서 아스키코드로 변환해야하기 때문에 list(s)로 치환해서 담았다. 
  • 만약 s[i]번째 문자가 대문자/소문자라면(isupper/islower) s[i]의 값은 (s[i]의 ASCII값 - 'A'/'a'의 ASCII값(97/65))+n을 해주어 몇 번째에 있는 알파벳인지 찾아준다. (알파벳은 총 25글자)
  • ord(s[i])-ord('A') (또는 ord('a')) 26으로 나눈 나머지 값에 'A'/'a' ASCII 값 = 97/65을 더해주면 n만큼 민 값이 나오게 된다. 
  • %26을 해주는 이유 ? z 또는 Z의 범위를 넘어가지 않도록 하기 위해
  • 즉, 맨 처음 값인 ord('A')와 ord('a')에서 n만큼 증가한 값이 무엇인지 찾는 것이다. 
  • 공백은 밀어도 공백이기 때문에 무시한다.
  • ""을 기준으로 join하여 return

 

✅ Python ASCII 

  • ord(문자) : 문자에 해당하는 ASCII 정수값 반환 
  • chr(정수) : 정수에 해당하는 ASCII 문자 반환
  • string.ascii_lowercase : 소문자에 해당하는 ASCII 값 
  • string.ascii_uppercase : 대문자에 해당하는 ASCII 값

 

 

✅ ASCII Chart 

032   056 8 080 P 104 h
033 ! 057 9 081 Q 105 i
034 " 058 : 082 R 106 j
035 # 059 ; 083 S 107 k
036 $ 060 < 084 T 108 l
037 % 061 = 085 U 109 m
038 & 062 > 086 V 110 n
039 ' 063 ? 087 W 111 o
040 ( 064 @ 088 X 112 p
041 ) 065 A 089 Y 113 q
042 * 066 B 090 Z 114 r
043 + 067 C 091 [ 115 s
044 , 068 D 092 \ 116 t
045 - 069 E 093 ] 117 u
046 . 070 F 094 ^ 118 v
047 / 071 G 095 _ 119 w
048 0 072 H 096 ` 120 x
049 1 073 I 097 a 121 y
050 2 074 J 098 b 122 z
051 3 075 K 099 c 123 {
052 4 076 L 100 d 124 |
053 5 077 M 101 e 125 }
054 6 078 N 102 f 126 ~
055 7 079 O 103 g    

 

 

💡 다른 사람의 풀이

import string

def caesar(s, n):
    result = ""
    base = ""
    for c in s:
        if c in string.ascii_lowercase:
            base = string.ascii_lowercase
        elif c in string.ascii_uppercase:
            base = string.ascii_uppercase
        else:
            result += c
            continue
        a = base.index(c) + n
        result += base[a % len(base)]
    return result


# 실행을 위한 테스트코드입니다.
print('s는 "a B z", n은 4인 경우: ' + caesar("a B z", 4))

 

Python의 아스키코드 값을 얻는 함수에 대해 알고있었다면 조금은 쉽게 풀었을 문제같다. 

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31