https://www.acmicpc.net/problem/5639
사실 문제는 되게 심플하다. preorder로 순회한 결과를 받아서 트리를 구축하고 postorder로 순회한 결과를 보이라는 거니까 간단함.
근데 문제풀이 보다 더 난관이었던 것은 바로 입력의 끝을 가늠할 수 없다는 것이었음.
키 값만 들어온다는데 입력의 끝을 나타내는 -1 등의 입력이 없었음.
이는 곧 EOF가 들어온다는 뜻이므로 이를 처리하는 방법을 고려할 필요가 있었음.
파이썬은 EOF처리를 try-except로 해결한다.
while True:
try:
temp = input()
except EOFError:
break
심플하다. input() 함수로 특정 값을 입력받는데 이 값이 EOF라면 error를 try except로 건져 입력을 탈출 하면 된다.
코딩 테스트에서 난이도가 올라가면 입력을 10만개, 100만개 이상을 입력받는다. 이 경우 입력이 많아서 기존 내장된 input 함수를 사용하면 보통 늦는다. 이에 속도를 빠르게 할 sys 라이브러리의 sys.stdin.readline 함수를 사용하게 되는데, 이 함수를 사용할 경우 위 방법이 통하지 않는다.
윈도우 환경에선 eof를 키보드로 입력하려고 하면 ctrl+z를 눌러야하며 그걸 누른게 bvbb 아래 ^z이다. 그러나 이후 계속 입력된다.
입력된 결과를 보자
ctrl+z 부분만 빈 문자열이 들어갔고, 나머지는 입력한 값에 \n이 붙은채로 들어간 걸 볼 수 있다. 아마 이 때문에 EOFError가 발생하지 않는게 아닌가 추측되었다.
본래 기존 input 함수는 eof를 받으면 EOFError를 내보내지만
sys.stdin.readline 함수는 eof를 받으면 빈 문자열을 내보낸다.
실제로 그 결과를 위에서 확인할 수 있었다.
따라서 sys.stdin.readline으로 eof를 감지하려면 아래와 같다.
while True:
temp = sys.stdin.readline()
if temp == "":
break
sys.stdin.readline() 함수로 입력 받은 값이 빈문자열이라면 EOF가 들어온 것이므로 반환한다.
EOF가 아닌 빈문자열, 그러니까 아무것도 안하고 엔터를 치면 sys.stdin.readline() 함수는 빈문자열에 \n 문자를 붙혀서 반환한다. 그래서 문자열에 \n 하나만 붙은걸로 나온다.
input() 함수 : EOFError exception을 일으킴. try-except로 잡을 수 있음.
sys.stdin.readline() 함수 : 정말 빈 문자열을 반환함. 해당 함수로 얻은 문자열이 정말 빈문자열인지 확인하는걸로 EOF 감지 가능.