어떤 수 x가 주어졌을 때, math.exp() 같은 라이브러리 함수를 사용하지 않고 ex(지수 함수)의 값을 효율적으로 계산해야 하는 문제입니다.
ex는 다음과 같은 테일러 급수(Taylor Series)로 표현할 수 있습니다.
ex = 1 + x + x2/2! + x3/3! + ...
예를 들어 입력이 x = 5라면 출력은 148.4131이 됩니다. 실제로 e5 = 1 + 5 + 52/2! + 53/3! + ... = 148.4131... 이기 때문입니다.
해결 접근 방식
이 문제는 테일러 급수의 각 항을 순서대로 더하는 방식으로 해결할 수 있습니다. 핵심 아이디어는 이전 항의 결과를 재활용하는 것입니다. 매번 x의 거듭제곱과 팩토리얼을 처음부터 새로 계산하면 비효율적이지만, 반복문 안에서 분자에는 x를 곱하고 분모에는 다음 정수를 곱하기만 하면 각 항을 상수 시간에 구할 수 있습니다.
알고리즘 단계
- fact := 1 (팩토리얼 값, 분모)
- res := 1 (결과값, 급수의 첫 항인 1로 초기화)
- n := 20 (반복 횟수, 더 정밀한 결과가 필요하면 크게 설정)
- nume := x (분자, x의 거듭제곱)
- i를 1부터 n까지 반복:
- res := res + nume / fact
- nume := nume * x
- fact := fact * (i + 1)
- res 반환
파이썬 구현 예제
def solve(x):
fact = 1
res = 1
n = 20
nume = x
for i in range(1, n):
res += nume / fact
nume = nume * x
fact = fact * (i + 1)
return res
x = 5
print(solve(x))입력
5
출력
148.4131591025766
동작 원리와 성능 분석
반복문이 한 번 실행될 때마다 다음과 같은 일이 일어납니다.
- res: 현재까지 계산된 급수의 합에 새로운 항 xi/i!를 더합니다.
- nume: x를 곱해 다음 거듭제곱(xi+1)을 준비합니다.
- fact: (i+1)을 곱해 다음 팩토리얼((i+1)!)을 준비합니다.
이렇게 이전 결과를 재활용하므로 전체 시간 복잡도는 O(n)으로 매우 효율적입니다. 또한 테일러 급수는 빠르게 수렴하므로, 부동소수점 정밀도의 한계를 고려하더라도 반복 횟수를 20~30회 정도만 설정하면 소수점 이하 여러 자리까지 정확한 결과를 얻을 수 있습니다.