본문 바로가기

Python

[Python/Silver IV] 덱 - 10866, deque, split(" ") vs. split(), sys.stdin

문제 설명

정수를 저장하는 덱(Deque)를 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.

명령은 총 여덟 가지이다.

  • push_front X: 정수 X를 덱의 앞에 넣는다.
  • push_back X: 정수 X를 덱의 뒤에 넣는다.
  • pop_front: 덱의 가장 앞에 있는 수를 빼고, 그 수를 출력한다. 만약, 덱에 들어있는 정수가 없는 경우에는 -1을 출력한다.
  • pop_back: 덱의 가장 뒤에 있는 수를 빼고, 그 수를 출력한다. 만약, 덱에 들어있는 정수가 없는 경우에는 -1을 출력한다.
  • size: 덱에 들어있는 정수의 개수를 출력한다.
  • empty: 덱이 비어있으면 1을, 아니면 0을 출력한다.
  • front: 덱의 가장 앞에 있는 정수를 출력한다. 만약 덱에 들어있는 정수가 없는 경우에는 -1을 출력한다.
  • back: 덱의 가장 뒤에 있는 정수를 출력한다. 만약 덱에 들어있는 정수가 없는 경우에는 -1을 출력한다.

 

deque

양방향 자료형

  • 앞과 뒤에서 데이터를 처리할 수 있는 양방향 자료형
  • 스택처럼 써도 되고, 처럼 써도 됨

언제 쓸 수 있어?

  • 시계방향으로 1~5가 적힌 다이얼이 있고, 현재 가리키는 눈금은 1
    • [1, 2, 3, 4, 5]
  • 이 다이얼을 오른쪽으로 2칸 돌려 눈금이 4가 되도록 하려면 어떻게 해야할까?
    • [4, 5, 1, 2, 3]

주요 문법

  • collections 모듈의 deque를 통해 덱 자료구조를 구현할 수 있음
메소드 설명
appendleft() 덱 왼쪽에 요소 추가
popleft() 덱 왼쪽 요소 제거(제일 앞에 있는 요소 제거)
rotate() 시계방향 회전은 양수, 그 반대는 음수
from collections import deque
dial = [1,2,3,4,5]
q = **deque(dial) #dial이 deque 자료구조로 변경됨**
q.rotate(2) # 45123

 

deque 객체 지원 메소드

메소드 설명
append(x) / appendleft(x) 덱 오른쪽 / 왼쪽에 x추가, 단일 객체 추가
예시) append[5. 6] → [1, 2, 3, 4, [5, 6]]
copy() 덱의 얕은 복사본 만듦
count(x) x와 같은 덱 요소의 수를 카운트
pop(), popleft() 덱 오른쪽 / 왼쪽에서 요소 제거
extend(iterable) / extendleft(iterable) iterable 에서 온 요소를 추가하여 덱의 오른쪽 / 왼쪽 확장
iterable의 모든 요소 개별적으로 추가
index(x, (start), (stop)]) 덱에 있는 x의 위치 반환
start: 인덱스 start 또는 그 이후
stop: 인덱스 stop 이전
insert(i, x) x를 덱 i 위치에 삽입
clear() 덱에서 모든 요소 제거, 길이가 0인 상태로 만듦
remove(value) value의 첫 번째 항목 제거
reverse() 덱 요소를 제자리에서 순서를 뒤집음(None 반환)
rotate(n) n: 오른쪽으로 회전, -n: 왼쪽으로 회전
오른쪽으로 한 단계 회전 = d.appendleft(d.pop())
왼쪽으로 한 단계 회전 = d.append(d.popleft())
maxlen 덱 최대 크기, 제한이 없는 경우 None 반환

 

split(" ") vs. split()

input().split(” ”) vs. input().split()
# 이 둘은 다르다, 앵간하면 input.split()을 쓰자!
메소드 split(" ") split()
설명 - 단일 공백 문자 기준으로 분할
- 연속된 공백을 빈 문자열로 간주
- 연속된 공백을 무시
-
모든 종류의 공백을 기준으로 분할
  s = "apple banana cherry"
print(s.split(" "))
s = "apple banana cherry"
print(s.split())
  ['apple', '', 'banana', '', '', 'cherry'] ['apple', 'banana', 'cherry']

 

 sys.stdin

import sys
input = sys.stdin.readline
# 이러면 시간복잡도 속도가 빨라진다

 

메소드 input() sys.stdin.readline()
설명 - 입력 문자열에서 줄 바꿈 문자를 제거하고 반환
- 여러 줄 입력 받을 때 상대적으로 느림
- 입력 문자열에서 줄 바꿈 문자를 포함하여 반환
- 한 번의 시스템 호출로 한 줄을 읽어오기 때문에, 많은 양의 데이터를 읽을 때 효율적임
    sys.stdin.read(): 전체 입력을 한번에 문자열로 읽음
    sys.stdin.readlines(): 모든 입력을 읽어 각 줄을 요소로 갖는 리스트 반환
import sys
from io import StringIO

# 가상의 입력 데이터 설정
input_data = "Hello\nWorld\nThis is a test."
sys.stdin = StringIO(input_data)

# 전체 입력을 한 번에 읽음
all_data = sys.stdin.read()
print(all_data)

# Hello
# World
# This is a test.
# 한 줄씩 읽음
line1 = sys.stdin.readline()
line2 = sys.stdin.readline()
print(line1, end='')  # 줄 바꿈 문자를 포함하고 있으므로 end=''로 제거
print(line2, end='')

# Hello
# World
# 모든 줄을 읽어 리스트로 반환
all_lines = sys.stdin.readlines()
print(all_lines)

# ['Hello\n', 'World\n', 'This is a test.']

 

 

code

from collections import deque
import sys
input = sys.stdin.readline

num = int(input())
deq = deque()

for _ in range(num):
    dequeCommand = input().split()
    if dequeCommand[0] == "push_front":
        deq.appendleft(dequeCommand[1])
    elif dequeCommand[0] == "push_back":
        deq.append(dequeCommand[1])
    elif dequeCommand[0] == "pop_front":
        if deq:
            print(deq.popleft())
        else:
            print("-1")
    elif dequeCommand[0] == "pop_back":
        if deq:
            print(deq.pop())
        else:
            print("-1")
    elif dequeCommand[0] == "size":
        print(len(deq))
    elif dequeCommand[0] == "empty":
        if deq:
            print(0)
        else:
            print(1)
    elif dequeCommand[0] == "front":
        if deq:
            print(deq[0])
        else:
            print("-1")
    elif dequeCommand[0] == "back":
        if deq:
            print(deq[-1])
        else:
            print("-1")
반응형