티스토리 뷰

반응형

문제 링크

문제

피보나치 수는 0과 1로 시작한다. 0번째 피보나치 수는 0이고, 1번째 피보나치 수는 1이다. 그 다음 2번째 부터는 바로 앞 두 피보나치 수의 합이 된다.

이를 식으로 써보면 Fn= Fn-1+ Fn-2(n>=2)가 된다.

n=17일때 까지 피보나치 수를 써보면 다음과 같다.

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597

n이 주어졌을 때, n번째 피보나치 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 n이 주어진다. n은 90보다 작거나 같은 자연수이다.

출력

첫째 줄에 n번째 피보나치 수를 출력한다.

문제 풀이

피보나치 수열은 단순한 재귀 함수로도 구현할 수 있지만 시간이 너무 오래 걸린다. 

단순한 재귀함수로 구현했다면 아래와 같이 구현할 수 있을 것이다.

import Foundation

guard let n = Int(readLine()!) else { fatalError() }

func fibonacci(_ n: Int) -> Int {
    
    if n == 1 || n == 2{
        return 1
    } else if n == 0{
        return 0
    } else {
        return fibonacci(n-1) + fibonacci(n-2)
    }
}

print(fibonacci(n))

위와 같이 구현하게 됐을 때 N이 5가 주어진다면 결과를 구하기 위한 과정은 다음과 같을 것이다.

 

N = 5 일때 -> fibonacci(4) + fibonacci(3)

N = 5 일때 호출한 fibonacci(4) -> fibonacci(3) + fibonacci(2)

N = 5 일때 호출한 fibonacci(3) -> fibonacci(2) + fibonacci(1) 

N = 5 일때 호출한 fibonacci(4)가 호출한 fibonacci(3) -> fibonacci(2) + fibonacci(1)

 

위와 같이 같은 계산을 계속 반복하는 비효율적인 방법이 된다. 위의 예에서만 해도 fibonacci(4)는 1번, fibonacci(3)은 2번, fibonacci(2)는 3번 과 같이 여러 번 계산됐다. 위의 예를 N = 5이기 때문에 크게 못 느끼지만 N이 커지면 커질수록 불필요한 연산이 늘어난다.  그래서 나는 한 번 계산한 값은 기억을 해서 다음에 필요할 땐 기억해둔 값으로 피보나치수열을 구해보려고 한다.

소스 코드

import Foundation

guard let n = Int(readLine()!) else { fatalError() }

func fibonacci(_ n: Int) -> Int {
    
    var numbers: Array<Int> = [0,1,1]
    for i in 0...n{
        if i == 0 || i == 1 || i == 2{
            continue
        } else {
            numbers.append(numbers[i-1] + numbers[i-2])
        }
    }
    return numbers[n]
}

print(fibonacci(n))
반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함