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

 

9093번: 단어 뒤집기

첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있으며, 문장이 하나 주어진다. 단어의 길이는 최대 20, 문장의 길이는 최대 1000이다. 단어와 단어 사이에는

www.acmicpc.net

이 문제는 티스토리에 올린 글에서 두 개의 유형을 짜집기해서 금방 풀었습니다.

https://ruo10102.tistory.com/6?category=1007186 

 

[BOJ] 10828번 스택

https://www.acmicpc.net/problem/10828 10828번: 스택 첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고,..

ruo10102.tistory.com

위의 글에서 배운 [::-1] 을 이용하여 문자열을 뒤집어서 출력이 가능하게 하였고,

 

https://ruo10102.tistory.com/6?category=1007186 

 

[BOJ] 10828번 스택

https://www.acmicpc.net/problem/10828 10828번: 스택 첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고,..

ruo10102.tistory.com

위의 글에서 배운 input 대신 sys.stdin.readline() 을 통해 출력시간을 줄이려고 노력했습니다.

 

import sys

num = int(input()) #test case는 input으로 받아도 상관 없다.
for _ in range(num):  # for문의 값을 이용하지 않을 때는 underbar를 이용하자.
    a = sys.stdin.readline().split()   #입력 받은 값을 공백으로 분리한다. i am happy 라면 ['i', 'am', 'happy']
    for i in a:
        print(i[::-1], end=' ')  #[::-1]를 통해 값들의 순서를 뒤집고 end=' ' 로 개행문자를 띄어쓰기로 바꾸었다.
        #['i', 'ma', 'yppah']

다른 사람의 코드를 한 번 살펴보았다..!

import sys

for i in range(int(sys.stdin.readline())):
   
    word = sys.stdin.readline()[::-1].split()
    word.reverse()
    
    # " ".join(list) 로 단어들을 이어 붙임 
    print( ' '.join(word))

이 분의 코드는 먼저 모든 단어들을 뒤집고 공백으로 나누고 시작했다

즉 " i am happy " 라면

['yppah', 'ma', 'i'] 이렇게 말이다.

이후에 list 를 reverse하면

['i', 'ma', 'yppah'] 이런식으로 출력이 가능하다.

 

그리고 또 다른 점은 나는 end=' ' 를 이용했지만 

print 문에서 join 문을 이용하는 것을 확인할 수 있었다.

 

Join 은 무슨 기능일까?

한 마디로 문자열을 합치는 기능 !!

 

>> ''.join(리스트)

>> '구분자'.join(리스트)

join 함수는 매개변수로 들어온 리스트에 있는 요소 하나하나를 합쳐서 하나의 문자열로 바꾸어 반환하는 함수입니다.

- ''.join(리스트)
''.join(리스트)를 이용하면 매개변수로 들어온 ['a', 'b', 'c'] 이런 식의 리스트를 'abc'의 문자열로 합쳐서 반환해주는 함수인 것입니다.

- '구분자'.join(리스트)
'구분자'.join(리스트)를 이용하면 리스트의 값과 값 사이에 '구분자'에 들어온 구분자를 넣어서 하나의 문자열로 합쳐줍니다.
'_'.join(['a', 'b', 'c']) 라 하면 "a_b_c" 와 같은 형태로 문자열을 만들어서 반환해 줍니다.

'백준' 카테고리의 다른 글

[BOJ] 10828번 스택  (0) 2022.05.02
[BOJ] 23080번 스키테일 암호  (0) 2022.05.01

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

 

10828번: 스택

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지

www.acmicpc.net

# 이전에 c++로 구현을 완료하였다.

#include <iostream>
#include <stack>
#include <string>

using namespace std;

int main() {
	stack<int> st;
	int a;
	cin >> a;
	string str;
	int temp;
	while (a--) {
		cin >> str;
		if (str == "push") {
			cin >> temp; //***
			st.push(temp);
		}
		else if (str == "pop") {
			if (st.empty()) {
				printf("-1\n");
			}
			else {
				printf("%d\n", st.top());
				st.pop();
			}
		}
		else if (str == "size") {
			printf("%d\n",st.size());
		}
		else if (str == "empty") {
			if (st.empty() == 0) {
				printf("0\n");
			}
			else {
				printf("1\n");
			}
		}
		else if (str == "top") {
			if (st.empty()) {
				printf("-1\n");
			}
			else {
				printf("%d\n",st.top());
			}
		}
	}
}

하지만 파이썬으로 코딩을 준비하게 되면서 알고리즘 기초 문제를 다시 접하면서 만난 문제입니다.

이건 너무 쉽다고 생각해 쉽게쉽게 작성해가고 있었습니다.

📌 기본 Logic은 stack 이라는 class 를 구현하고 
if-elif 문으로 각각의 case에 맞게 처리하자 였습니다.
#10828
class stack:
    def __init__(self):  # 스택 객체 생성
        self.items = []
    def push(self, item):  # 스택 요소 추가 push(.append())
        self.items.append(item)
    def pop(self):   # 스택 요소 삭제 pop()
        if self.items == []:
            return -1
        return self.items.pop()
    def top(self):  # 스택 맨 앞 요소 리턴
        if self.items == []:
            return -1
        return self.items[-1]
    def isEmpty(self):  # 스택이 비었는지 확인(비었으면 True 리턴)
        if not self.items:
            return 1
        return 0

stk =stack()
num = int(input())
for i in range(num):
    a = input()
    if a == "top":
        print(stk.top())
    elif a== "pop":
        print(stk.pop())
    elif a=="size":
        print(len(stk.items))
    elif a=="empty":
        print(stk.isEmpty())
    else:
        b = a.split(" ")
        stk.push(b[1])

이런 식으로 작성하니 시간초과가 떴습니다..!!!😵‍💫

시간초과 날 구석이 없는데 어떻게 시간초과 가 나는지 의문이었고 그래서 구글에 " 파이썬 시간초과 " 를 검색해보았고

로직의 worst time 의 문제가 아니라면 input() 사용을 바꿔 보라는 글을 확인했습니다.

 

https://ruo10102.tistory.com/5?category=1007534 

 

[Python] import sys 에 대하여

1. sys.stdin.readline()로 입력받기 입력값을 받아 저장해하는 경우 input() 으로 구현하시는 분들이 많으실텐데 sys 라는 파이썬의 표준 라이브러리를 사용하면 훨씬 빠른 시간에 적은 메모리를 사용하

ruo10102.tistory.com

 

이후 import sys를 통해 sys.stdin.readline() 에 대해서 공부 후 

기존의 class 정의도 파이썬에 내장되어잇는 list로 구현하자고 마음 먹었습니다.

import sys

stk = []
num = int(input())
for i in range(num):
    a = sys.stdin.readline().split()
    if a[0] == "top":
        if stk : print(stk[-1])
        else: print(-1)
    elif a[0]== "pop":
        if stk : print(stk.pop())
        else: print(-1)
    elif a[0]=="size":
        print(len(stk))
    elif a[0]=="empty":
        if stk : print(0)
        else: print(1)
    elif a[0]=='push':
        stk.append(a[1])

첫 num 입력 즉, test case 의 숫자는 제외하고 나머지는 sys.stdin.readline으로 입력받아 공백을 기준으로 split 하여

'a'에 저장했습니다.

따라서 a[0]의 문자열이 어떤 문자열이냐에 따라 처리를 달리했습니다..^____^

 

 

후기 : 생각보다 간단할 줄 알았는데 시간 초과 를 여러번 만나 힘들었습니다ㅜ

 

아!! 추가적으로 주피터 노트북은 stdin.readline 구현이 잘 안되어 있어.. 오늘 파이참을 설치하려고 합니다 또르륵,,,,,

'백준' 카테고리의 다른 글

[BOJ] 9093번 단어 뒤집기  (0) 2022.05.02
[BOJ] 23080번 스키테일 암호  (0) 2022.05.01

1. sys.stdin.readline()로 입력받기

입력값을 받아 저장해하는 경우 input() 으로 구현하시는 분들이 많으실텐데 sys 라는 파이썬의 표준 라이브러리를 사용하면 훨씬 빠른 시간에 적은 메모리를 사용하여 입력 받을 수 있답니다!

import sys 
변수 = sys.stdin.readline()​

2. 배열에 원소 추가할 때 인덱스로 접근하기

배열에 원소를 추가하면 보통 빈 배열을 만들고 append 로 추가할 때가 많은데, 이 경우 입력 받을 개수(N)를 알고있다면 N 만큼 배열을 초기화해두고 인덱스로 각자 접근해서 저장하는 것이 효율이 좋습니다.

## 7의 배수 10개 저장하기
# 수정 전
arr = []
for num in range(1, 11):
    arr.append(num * 7)
    
# 수정 후
arr = [0 for _ in range(10)]
for num in range(1, 11):
    arr[num] = num * 7

 

3. 줄바꿈을 출력해야하는 경우 문자열로 바꿔 출력하기

줄바꿈이 자주 반복된다면 print()보다 '\n' 사용하는 것이  좋습니다. 
그렇기 때문에 문자열 변수에 정답을 저장해놓고 한 번에 출력하는 것이 효율에 좋습니다.

# [1, 2, 3, 4]를 줄바꿈으로 하나씩 출력하기
# 1
# 2
# 3
# 4

# 수정 전
arr = [1, 2, 3, 4]
for n in arr:
    print(n)
    
# 수정 후
answer = ""
for n in arr:
    answer += str(n) + '\n'
print(answer)

 

4. 재귀 깊이 늘려주기

파이썬은 기본적으로 재귀호출을 1000번으로 제한하고 있기 때문에 더 많은 재귀를 요구할때는 재귀깊이를 늘려주어 사용해야합니다!

import sys
sys.setrecursionlimit(1000000) #1000000번 재귀가 가능하도록 변경하기

 

5. queue 로 구현할 때 리스트보다  deque 사용하기

Python 에서는 리스트보다 collections.deque 모듈을 사용하는 것이 더 빠르기 때문에 Queue 를 통해 문제를 해결해야하는 상황이 있다면 deque 를 사용하는 것이 시간이 단축됩니다!

# 수정 전
queue = []
for i in range(N):
	queue.append(i)
for i in range(N):
    print(queue[-1])
    queue.pop(-1)

# 수정 후
from collections import deque

queue = deque()
for i in range(N):
	queue.append(i)
for i in range(N):
	queue.popleft()

 

📌한 개의 정수를 입력받을 때

import sys
a = int(sys.stdin.readline())

😨 그냥 a = sys.stdin.readline() 하면 안되나요?
👉 sys.stdin.readline()은 한줄 단위로 입력받기 때문에, 개행문자가 같이 입력 받아집니다.
만약 3을 입력했다면, 3\n 이 저장되기 때문에, 개행문자를 제거해야 합니다.
또한, 변수 타입이 문자열 형태(str)로 저장되기 때문에, 정수로 사용하기 위해서 형변환을 거쳐야 합니다.

📌정해진 개수의 정수를 한줄에 입력받을 때

import sys
a,b,c = map(int,sys.stdin.readline().split())

map()은 반복 가능한 객체(리스트 등)에 대해 각각의 요소들을 지정된 함수로 처리해주는 함수입니다.
위와 같이 사용한다면 a,b,c에 대해 각각 int형으로 형변환을 할 수 있습니다.

📌 임의의 개수의 정수를 한줄에 입력받아 리스트에 저장할 때

import sys
data = list(map(int,sys.stdin.readline().split()))

split()은 문자열을 나눠주는 함수입니다.
괄호 안에 특정 값을 넣어주면 그 값을 기준으로 문자열을 나누고, 아무 값도 넣어주지 않으면 공백(스페이스, 탭, 엔터 등)을 기준으로 나눕니다.

list()는 자료형을 리스트형으로 변환해주는 함수입니다.
map()은 맵 객체를 만들기 때문에, 리스트형으로 바꿔주기 위해서 list()로 감싸주었습니다.

📌 임의의 개수의 정수를 n줄 입력받아 2차원 리스트에 저장할 때

import sys
data = []
n = int(sys.stdin.readline())
for i in range(n):
    data.append(list(map(int,sys.stdin.readline().split())))

이렇게 한다면 각 요소의 길이가 동일한 2차원 리스트도 만들 수 있고,
각각 길이가 다른 2차원 리스트도 입력 받을 수 있습니다.

📌 문자열 n줄을 입력받아 리스트에 저장할 때

import sys
n = int(sys.stdin.readline())
data = [sys.stdin.readline().strip() for i in range(n)]

strip()은 문자열 맨 앞과 맨 끝의 공백문자를 제거합니다.

문제 자체는 쉬웠다고 생각합니다.

우선 굵기 x와 문자열을 입력받고 string 의 idx를 굵기 x 로 나누었을 때, 나머지가 0인 문자는 print하면 된다. 

#23080

a = int(input())
string = input()
printStr = ""
for i in range(0, len(string)):
    if ( i % a == 0):
        printStr += string[i]
print(printStr)

이후 다른 분들은 어떻게 작성하는지 살펴봤다.

N=int(input())
print(input()[::N])

단순했던 문제를 더욱 단순히 풀어서 충격이긴했다.

[::N] 에 대해서 알아보자.

 

 

x = '0123456789'

x[::2]        # ::증가분 표현 
x[::3]        # 처음부터 끝까지 3씩증가한다. 
x[0:7:2]     # 0부터 6까지 2씩 증가한다. 
x[5::2]      # 5부터 끝까지 2씩 증가한다. 
x[::-1]      # reverse(역순으로 출력)

'백준' 카테고리의 다른 글

[BOJ] 9093번 단어 뒤집기  (0) 2022.05.02
[BOJ] 10828번 스택  (0) 2022.05.02

+ Recent posts