본문 바로가기
Algorithm 알고리즘/BAEKJOON 백준

[BAEKJOON][문자열1]-B-!밀비 급일(11365번) / 힌트:슬라이싱

by 개복치96 2022. 10. 21.
반응형

https://www.acmicpc.net/problem/11365

 

11365번: !밀비 급일

당신은 길을 가다가 이상한 쪽지를 발견했다. 그 쪽지에는 암호가 적혀 있었는데, 똑똑한 당신은 암호가 뒤집으면 해독된다는 것을 발견했다. 이 암호를 해독하는 프로그램을 작성하시오.

www.acmicpc.net

이 문제는 상당히 오래걸렸다.
이 문제를 풀면서 느낀게, 파이썬만의 그런 기능이랄까 효과적인 방법들이 아직 체화가 되지 않았다는걸 뼈져리게 느꼈다.

먼저 내 생각에 백준 온라인 저지를 사용해서 알고리즘 공부를 처음시작하시는 분들께 꼭 하고싶은 말이 있다.
입력을 다 받고 나서 출력을 할 필요가 없다.
무슨 말이냐 하면, 나는 부스트코스 코칭스터리를 하면서 정말 알고리즘이 아니라 '프로그램'처럼 만드는 것부터 배웠다.
예를 들어 '숫자를 입력해라'를 구현해야 하면, 나는 사용자가 공백부터 입력할지, 문자를 입력할지, 문자와 숫자를 입력하면 어떻게 할지 등 모든 경우를 다 따져서 구현했었다. 그런데 여기는 그럴 필요가 없다.

또한 입력과 출력을 그대로 다 따라갔었다.

위와 같이 입력 값이 주어진다고 하면, 일단 저렇게 그대로 END가 입력될때까지 입력만 다 받고나서
그 다음 출력을 할 수 있도록 구현했다.

그런데 꼭 그렇게 할 필요가 없다.
그냥 입력하면 출력나오고 다시 입력하고, 그렇게 구현해도 무관하다!!!


서론이 길었다.
각설하고 본론으로 들어가자.

11365번은 문자열에 대한 그 중에서도 슬라이싱에 대한 부분이다.
힌트를 찾기위해 들어오신분이라면 '슬라이싱'이라는 힌트를 얻으셨으니, 다시한번 해보시라!!!

자, 여기서부터는 정답 코드와 시행착오이다.

import sys

i = 0
data = [] #빈 리스트 선언

#END가 입력될때까지 무한루프
while True:
    i = i + 1
    #data에 값을 한 줄씩 넣는다. 띄어쓰기 포함.
    data.append(sys.stdin.readline().strip())
    if data[-1] == 'END': #END가 입력되면 break
        break

#END를 제외하고 입력한 문자열의 줄 수만큼 반복
#data에 한 줄씩 해당 줄을 거꾸로 만든 문자열을 입력
for i in range(len(data) - 1):
    data[i] = data[i][::-1]

#입력한 문자열을 다시 출력
for i in range(len(data) - 1):
    print(data[i])

위에 코드가 정답 코드이다.
코드 번호가 불편하다. 조만간 HTML손을 조금 봐야겠다.

코드는 생각보다 간단하다. 슬라이싱을 떠올리면 금방 해결이 된다.
슬라이싱 중에서도 [::-1]을 사용하면 해당 문자열을 거꾸로 출력할 수 있다.
처음에는 이걸 생각을 못해서 reverse() 함수를 사용해서 해보려고 용을 쓰다가 결국 포기했었다.

먼저 while문의 무한루프를 활용하여 'END'가 입력될때까지 문자를 계속해서 입력받는다.
그리고 입력 받는 문자들을 한 줄씩 data에 넣는다.

예를 들어 입력값을

Hello world, Choi
Welcome to heaven
Nice to meet you
END


라고 입력하면
data[0]에 Hello world, Choi
data[1]에 Welcome to heaven
data[2]에 Nice to meet you
data[3]에 END
가 저장된다.

따라서

if data[-1] == 'END':
        break

이 부분은 뒤에서 첫번째, 즉 마지막에 저장되어 있는 문자가 END일 경우 무한루프를 종료하라는 뜻이다.

그 다음은 뭐, 거꾸로 다시 만들어주고 그걸 저장한 다음 출력했다.

❗️중요한 것 은 딱 두개이다.
1. 문자열을 한 줄씩 입력받아 리스트에 저장하는 방법
2. 리스트에 저장된 문자를 슬라이싱을 통해 거꾸로 나열하는 방법


나는 리스트를 사용했다. 출력을 한번에 입력한 줄 그대로 해야되다 보니...

그리고 sys.stdin.readline().strip()에서 spit()을 사용할게 아니라, strip()으로 한줄에 띄어쓰기로 입력된 문자들을 다 저장했다.
즉, 한 줄이 리스트의 한 원소이다.

6번째줄이 나름 꿀팁이다.
data[-1]은 리스트 맨 마지막의 원소를 이야기 하는거다. 그러니, 저기에서는 가장 마지막 줄에 입력된 것을 뜻한다.

9,10번 줄은 입력한 걸 거꾸로 해주는 역할이다.
data[::-1]로 했으면 마지막줄이 첫번째줄이 되었겠지만, data[i][::-1]로 구현해서,
i번재 data의 원소를 거꾸로 나열해서 다시 data의 i번째 원소에 저장한 것.

아래는 같이 스터디를 진행하는 친구의 코드이다.

훨씬 간단하다.
나처럼 배열로 받고 저장하고 하는 단계를 전부 생략했다.
반복문이 많을 수록 시간복잡도가 올라간다 최대한 줄여보자.

어차피 줄바꿈과 띄어쓰기도 문자로 인식되서 input()으로 받을 수 있다.
그러니 저렇게 한번에 다 받고 한번에 뒤집어서 출력해도 결과는 같다!

쉽게 할 수 있는 방법을 더 생각하자.
문제 자체를 잘 읽고 쉬운 방법을 찾고 코딩을 하자.

 

아래 링크는 내가 푼 코드가 들어있는 깃헙 레포이다.

https://github.com/Headfish96/Algorithm.git

 

GitHub - Headfish96/Algorithm: Algorithm That I study

Algorithm That I study. Contribute to Headfish96/Algorithm development by creating an account on GitHub.

github.com

 

반응형