코딩 테스트를 준비할 때 사용하는 플랫폼의 종류에 따라서 제출하는 형식, 입력받는 형식 등이 달라지게 된다.
대표적으로 코딩 테스트를 시행하는 프로그래머스, 구름 플랫폼은 solution 이라는 함수를 호출식으로 인자를 넘겨받게 되어 별도의 input 처리가 필요하지 않다.
그러나 백준, SWEA와 같이 사용자가 input 처리부터 해야하는 플랫폼이 있다.
데이터를 입력받는 형식에는 다양한 방식이 있다.
import sys
#표준입력을 파일로 설정
sys.stdin = open("input.txt", "r")
N = int(input())
print(N)
# 입력
>>> 3
# 결과
3
print(input().split())
# 입력
>>> a b c
# 결과
['a', 'b', 'c']
N, M = map(int, input().split())
print(N, M)
# 입력
>>> 1 2
# 결과
1 2
이때 리스트에 있는 요소의 갯수에 맞춰서 변수의 개수를 해줘야 함
→ 변수의 개수에 맞춰서 입력을 해줘야 함
변수와 입력의 개수를 다르게 설정하면 아래와 같은 오류 발생
N, M = map(int, input().split())
# 1 2 3 입력
Traceback (most recent call last):
File "<input>", line 1, in <module>
ValueError : too many values to unpack (expected 2)
→ 입력 데이터가 여러개이거나 미리 알 수 없는 경우에 사용
arr = list(map(int, input().split())
print(arr)
# 입력
>>> 1 2 3 4 5
# 결과
[1, 2, 3, 4, 5]
print(input()) # 한 줄을 입력받아 그대로 출력
# 입력
>>> 12345
# 결과
12345
---------------------------------------------------------
arr = list(input()) # 한 줄을 입력받아 list 함수를 적용
# 입력
>>> 12345
# 결과
['1', '2', '3', '4', '5']
map() 함수를 이용해서 문자열을 숫자로 변환한 후 list() 함수를 이용해서 리스트로 변환
arr = list(map(int, input())) # map을 이용해서 문자열을 숫자로 변환
print(arr)
# 입력
>>> 12345
# 결과
[1, 2, 3, 4, 5]
N = int(input())
arr = [list(map(int, input().split())) for _ in range(N)]
print(arr)
# 입력
>>> 3 # N 입력받기
>>> 1 2 3 # 공백으로 구분되어 총 3행이 입력
>>> 4 5 6 # N번을 반복하며 한 줄씩 읽고, 공백 문자로 나눠서 숫자형으로 반환
>>> 7 8 9 # 1차월 배열로 만들어 2차원 배열로 완성
# 결과
[[1, 2, 3], [4, 5, 6], [7, 8, 9]] # 2차원 배열로 출력
백준에서 문제를 풀다보면 데이터 입력에서 input()을 사용하여 시간초과가 되는 경우가 있다. 그럴 때 input 대신 sys.stdin.readline을 사용하면 대부분의 경우에서 시간 초과를 방지할 수 있다.
Java에서는 Sanner나 System.out.println 보다는 BufferedReader를 사용해야 하고,
Python에서는 input 대신 sys 라이브러리의 sys.stdin.readline()을 권장한다.
→ 두 입력 방식의 작동 과정을 통해 많은 양의 입출력을 시행할 경우 input() 함수가 더 느린 이유를 이해해보자.
input() 함수의 경우 사용자의 입력을 읽어온 후, 아래와 같은 처리 과정을 거친다.
또한, input() 함수의 경우, 더 이상 입력이 주어지지 않을 때 EOFError를 띄운다.
sys.stdin은 input() 함수와 달리 File Object → 하나의 객체
하단의 코드를 실행시켰을 경우, sys.stdin 객체의 속성을 열람할 수 있다.
dir(sys.stdin)
>>> ['_CHUNK_SIZE', '__class__', '__del__', '__delattr__',
'__dict__', '__dir__', ..., 'write', 'writelines']
그리고 readline의 경우 sys.stdin 객체에서 지원하는 메소드이다.
또한 readline은 EOF에 도달할 시 에러가 아닌 빈 문자열을 반환한다.
❗️ 주의 readline의 경우 개행문자 \n까지 받아온다.
이를 제거하고 싶다면 strip() 함수를 추가로 실행해주어야 한다.
→ 그렇기 때문에 sys.stdin.readline이 input() 함수보다 더 빠르게 동작
불필요한 전처리 과정 없이 바로 Buffer에서 한 줄씩 값을 읽어오기만 하면 된다.
→ 파이썬에서의 함수는 1급 객체(First-Class Object)로 취급
import sys
read = sys.stdin.readline
N = int(read())
data = [sum(map(int, read().split())) for _ in range(N)]
for num in data:
print(num)
→ 보다 효율적으로 입출력 처리가 가능
import sys
read = sys.stdin.readline
N, M, K = map(int,input().split())
→ read().split()을 통해 나온 list 내의 요소들을 int() 함수로 변환하여 최종적으로 나온 정수들을 순차적으로 변수에 저장하는 방식
import sys
read = sys.stdin.readline
data = list(map(int, read().split()))
위의 방식과 거의 동일하지만 차이점이 있다면 list() 함수의 유무다
map() 함수는 map 객체를 리턴하기 때문에 이를 다시 list로 반환해주어야 한다.
import sys
read = sys.stdin.readline
N = int(read())
data = [int(read()) for _ in range(N)]
다른 방식으로 list 배열을 생성한 후 append() 함수를 통해 요소를 추가해도 가능
But, List Comprehension 기법을 사용하면 더 간결하게 코드를 작성할 수 있음.
import sys
read = sys.stdin.readline
N = int(read())
data = [read().strip() for _ in range(N)]
대부분의 문자열 처리의 경우 개행문자 \n를 제거해야 하는 경우가 많은데 strip() 함수를 통해 문자열에 붙은 개행문자를 제거하면 된다.
import sys
read = sys.stdin.readline
N = int(read())
arr = [list(map(int, read().split())) for _ in range(N)]
2차원 배열의 경우 그래프 문제를 풀기 위해 주어진 입력을 토대로 만드는 경우가 많다.
이 경우에도 List Comprehension 기법을 사용하여 한 줄로 2차원 배열 생성이 가능
알고리즘 문제를 풀 때 항상 sys.stdin.readline()을 사용하였지만 그 원리에 대해서 공부를 하니 이해도가 확실히 상승한거 같다.