구름LEVEL
난이도별 다양한 문제를 해결함으로써 SW 역량을 향상시킬 수 있습니다.
level.goorm.io
문제해결방법
오늘 챌린지 문제도 크게 어려울 것은 없다.
리스트에 계산할 식을 입력받으면 [ "1", "+", "3"]과 같이 문자열을 담은 리스트가 될 것이다.
이 리스트의 요소 중, 첫 번째(0번 인덱스) 요소와 세 번째(2번 인덱스) 요소가 피연산자이므로 int 타입으로 형변환 되어야하고, 두 번째(1번 인덱스) 요소는 연산자로서 어떤 연산을 수행할지를 결정할 조건의 역할을 한다.
t 번의 반복을 거쳐 각 연산의 결과를 sum에 더해주고 sum을 출력하면 간단하게 문제가 해결된다.
import sys
t = int(sys.stdin.readline())
sum = 0
for i in range(t):
expression = list(sys.stdin.readline().rstrip().split())
if expression[1] == "+":
sum += int(expression[0]) + int(expression[2])
elif expression[1] == "-":
sum += int(expression[0]) - int(expression[2])
elif expression[1] == "*":
sum += int(expression[0]) * int(expression[2])
else: #남은 연산자는 "/"
sum += int(expression[0]) // int(expression[2]) #파이썬의 몫은 "/"가 아닌 "//"
print(sum)
파이썬의 정수끼리의 / 연산과 // 연산의 성능 차이는 없을까?
위 문제를 푸는 과정에서 한 가지 궁금증이 떠오르게 되었다. 바로 파이썬에서 정수끼리의 / (division) 연산과 // (floor division) 연산의 성능 차이는 없을까 하는 부분이었다.
처음 예상하기로는 // 연산이 더 빠를 것이라고 생각했다. 파이썬에서 / 연산을 하면 결과로는 실수가 출력된다. 6 / 3과 같이 나누어 떨어지는 정수끼리 / 연산을 수행하더라도 결과는 2가 아닌 2.0이 된다. 이를 토대로 파이썬에서 정수끼리 / 연산을 수행할 때 내부적으로 두 정수를 실수로 형변환 할 것이라고 예측했고, 따라서 형변환 과정에서의 비용이 더해져서 / 연산이 더 느릴 것이라고 예상한 것이다.
예상이 맞는지를 직접 확인해보기 위해, // 와 / 만 다르고 나머지는 모두 동일한 연산을 매우 많이 반복해보았다.
from time import time
def floor_division():
for i in range(10**8):
a = 1 * 12 // (i+1) * 2 // (77*i+998) * 23
t1 = time()
floor_division()
t2 = time()
print("%.3f"%(t2-t1))
from time import time
def normal_division():
for i in range(10**8):
a = 1 * 12 / (i+1) * 2 / (77*i+998) * 23
t1 = time()
normal_division()
t2 = time()
print(t2-t1)
결과는 예상과 같이 / 연산의 속도가 더 느렸다.
그렇다면 만약 오늘의 문제 같이 답으로 정수를 얻어내야 하는 상황에 / 연산을 사용하고 int 형으로 형변환까지 해야한다면 어떨까? 이것도 위의 normal_division 함수에 정수 형변환까지 하는 과정을 추가한 코드를 돌려보며 걸리는 시간을 측정해보았다.
from time import time
def normal_division_with_int_conversion():
for i in range(10**8):
a = 1 * 12 / (i+1) * 2 / (77*i+998) * 23
int(a)
t1 = time()
normal_division_with_int_conversion()
t2 = time()
print(t2-t1)
/ 연산만 수행할 때보다 시간이 더 오래 걸리는 것을 확인할 수 있었다. // 연산을 사용했을 때와 비교하면 두 배 이상의 시간이 소요된 것이다.
물론 한번의 연산에서는 차이를 느끼지 못할 정도로 작은 성능 차이겠지만, 그 차이가 누적되었을 때에는 꽤 큰 차이가 될 수 있다. 따라서 평균을 구하는 등 정확한 실수형의 결과를 얻어야하는 상황이라면 당연히 / 연산을 사용해야겠지만, 몫만 구해도 되는 상황에서는 // 연산을 사용하는 것이 바람직해 보인다.
'알고리즘 > 9oormthon Challenge' 카테고리의 다른 글
[구름톤 챌린지 #6] 문자열 나누기 (0) | 2023.08.21 |
---|---|
[구름톤 챌린지 #5] 이진수 정렬 (0) | 2023.08.18 |
[구름톤 챌린지 #4] 완벽한 햄버거 만들기 (0) | 2023.08.18 |
[구름톤 챌린지 #2] 프로젝트 매니징 (0) | 2023.08.16 |
[구름톤 챌린지 #1] 운동 중독 플레이어 (0) | 2023.08.14 |