5️⃣ CS/Algorithm

[Swift Algorithm Note] 꼬리 μž¬κ·€ ν•¨μˆ˜ (feat. Fibonacci)

seolhee2750 2021. 7. 9. 03:24

μ €λ²ˆ κΈ€μ—μ„œ μž¬κ·€ ν•¨μˆ˜μ— λŒ€ν•΄ λ‹€λ€˜λ‹€λ©΄, μ΄λ²ˆμ—” '꼬리' μž¬κ·€ ν•¨μˆ˜μ— λŒ€ν•΄ 정리해보렀고 ν•œλ‹€.

ν”Όλ³΄λ‚˜μΉ˜ 수λ₯Ό κ΅¬ν•˜λŠ” ν•¨μˆ˜λ₯Ό κ΅¬ν˜„ν•΄λ³΄λ©΄μ„œ, μž¬κ·€ν•¨μˆ˜μ˜ λ¬Έμ œμ μ„ μ•Œκ²Œ λ˜μ—ˆλ‹€.

그런데 이 λ¬Έμ œμ μ„ 꼬리 μž¬κ·€ ν•¨μˆ˜κ°€ ν•΄κ²°ν•΄ μ€€λ‹€λŠ” 사싀을 μ•Œκ²Œ λ˜μ—ˆλ‹€,,!!

λ”°λΌμ„œ μ˜€λŠ˜μ€ 꼬리 μž¬κ·€ ν•¨μˆ˜λ₯Ό 곡뢀해보고, κ΅¬ν˜„ λ°©λ²•κΉŒμ§€ ν™•μ‹€νžˆ μ΄ν•΄ν•΄λ³΄μž.

 

πŸ“Ž 꼬리 μž¬κ·€ ν•¨μˆ˜(Tail Recursive Call)

꼬리 μž¬κ·€ ν•¨μˆ˜λŠ” 일반적인 μž¬κ·€ ν•¨μˆ˜μ˜ 단점을 λ³΄μ™„ν•œλ‹€.

 

일반적인 μž¬κ·€ ν•¨μˆ˜κ°€ κ°€μ§€λŠ” 단점은 λ°”λ‘œ

μŠ€νƒ μ˜€λ²„ν”Œλ‘œμš°κ°€ λ°œμƒν•  수 μžˆλ‹€λŠ” 점,,!!!πŸ’₯

 

일반 μž¬κ·€μ˜ 경우, μ €λ²ˆ κΈ€μ—μ„œ λ‹€λ€˜λ“―

μŠ€νƒμ— ν•¨μˆ˜ ν˜ΈμΆœμ„ ν•˜λ‚˜μ”© μŒ“κ³ , 거꾸둜 λ°˜ν™˜ 값을 λ„˜κΈ°λ©° 계산을 μˆ˜ν–‰ν•œλ‹€.

(이 λ‚΄μš©μ€ μš”κΈ°πŸ‘‡ 글을 μ°Έκ³ ν•΄μ£Όμ„Έμš”!)

2021.07.08 - [πŸ“ Algorithm Note/πŸ” with Swift] - [Swift Algorithm Note] μž¬κ·€ν•¨μˆ˜ 정리 (feat. Factorial)

 

[Swift Algorithm Note] μž¬κ·€ν•¨μˆ˜ 정리 (feat. Factorial)

λŒ€μΆ©μ€ μ•Œκ³  μžˆμ—ˆμ§€λ§Œ,, μ§€κΈˆκΉŒμ§€λŠ” μ•Œκ³ λ¦¬μ¦˜μ— λŒ€ν•œ μ •ν™•ν•œ κ°œλ… 없이 문제λ₯Ό ν•΄κ²°ν•΄μ™”λ‹€. ν•˜μ§€λ§Œ 점차 문제 μˆ˜μ€€μ΄ λ†’μ•„μ§€λ©΄μ„œ μ•Œκ³ λ¦¬μ¦˜μ„ μ •ν™•νžˆ νŒŒμ•…ν•˜κ³  μžˆμ–΄ν– ν•œλ‹€λŠ” 것을 λŠλ‚Œ,, λ”°λΌμ„œ

seolhee2750.tistory.com

 

값이 λ„ˆλ¬΄ μ»€μ„œ ν•¨μˆ˜ ν˜ΈμΆœμ„ μ•„~μ£Ό 많이 ν•΄μ•Ό ν•  κ²½μš°μ—λŠ” μŠ€νƒ μ˜€λ²„ν”Œλ‘œμš°κ°€ λ°œμƒν•  수 μžˆλŠ” 것이닀.

πŸ‘‰ μ΄λŸ¬ν•œ 점을 λ³΄μ™„ν•˜κ³ , μž¬κ·€ ν•¨μˆ˜μ˜ μž₯점은 μ‚΄λ¦¬λŠ” 방법이 λ°”λ‘œ 꼬리 μž¬κ·€μ΄λ‹€.

 

말둜 μ„€λͺ…ν•˜κΈ°λ³΄λ‹€,

μž¬κ·€ ν•¨μˆ˜μ˜ λŒ€ν‘œκ²©μΈ νŒ©ν† λ¦¬μ–Ό ν•¨μˆ˜μ˜ 일반 μž¬κ·€, 꼬리 μž¬κ·€ κ΅¬ν˜„μ„ 보며 μ΄ν•΄ν•΄λ³΄μž.

// 일반 μž¬κ·€
func Recursion(_ x: Int) -> Int {
    if x == 1 { return 1 }
    return x * Recursion(x-1)
}

// 꼬리 μž¬κ·€
func tailRecursion(_ x: Int, _ result: Int) -> Int {
    if x == 1 { return result }
    return tailRecursion(x-1, x * result)
}

print(Recursion(3)) // 6
print(tailRecursion(3, 1)) // 6

πŸ“Œ 두 μž¬κ·€ ν•¨μˆ˜μ˜ 차이점

  1. νŒŒλΌλ―Έν„°κ°€ ν•˜λ‚˜ 더 μΆ”κ°€λ˜μ—ˆλ‹€.
    : ν•˜λ‚˜μ˜ μΆ”κ°€λœ νŒŒλΌλ―Έν„°λŠ” κ³„μ‚°μ˜ λˆ„μ μ„ λ‹΄κΈ° μœ„ν•¨μ΄λ‹€.
  2. λ§ˆμ§€λ§‰ λ¬Έμž₯의 μž¬κ·€ 방식에 차이가 μžˆλ‹€.
    : 일반 μž¬κ·€λŠ” ν•¨μˆ˜μ˜ 호좜과 μƒˆλ‘œμš΄ 계산식이 λ”ν•΄μ‘Œλ‹€. ν•˜μ§€λ§Œ 꼬리 μž¬κ·€λŠ” ν•¨μˆ˜ 호좜만이 μ‘΄μž¬ν•œλ‹€.
    (꼬리 μž¬κ·€λŠ” return λ¬Έμ—μ„œ μΆ”κ°€ 계산 없이 ν•¨μˆ˜ 호좜만으둜 끝내기 μœ„ν•΄
    1번 λ¬Έν•­ 계산 λˆ„μ  μš©λ„μ˜ νŒŒλΌλ―Έν„°λ₯Ό μΆ”κ°€ν•œ 것이닀.)

μ—¬κΈ°μ„œ 잠깐,

μœ„μ—μ„œ 꼬리 μž¬κ·€λŠ” 일반 μž¬κ·€μ˜ μŠ€νƒ μ˜€λ²„ν”Œλ‘œμš° λ°œμƒ κ°€λŠ₯성을 κ·Ήλ³΅ν•˜κΈ° μœ„ν•œ 방법이라고 λͺ…μ‹œν–ˆλ‹€.

ν•˜μ§€λ§Œ μ½”λ“œλ‘œ λ΄μ„œλŠ” λΉ„μŠ·ν•œ 둜직처럼 λŠκ»΄μ§„λ‹€,,

그림으둜 두 ν•¨μˆ˜μ˜ 진행 방식을 μžμ„Ένžˆ μ‚΄νŽ΄λ³΄μž.

 

πŸ“Œ 두 μž¬κ·€ ν•¨μˆ˜μ˜ 진행 방식

βœ”οΈμΌλ°˜ μž¬κ·€ ν•¨μˆ˜

일반 μž¬κ·€ ν•¨μˆ˜ 진행 방식

일반적인 μž¬κ·€ ν•¨μˆ˜λŠ” μ €λ²ˆ κΈ€μ—μ„œ κ³΅λΆ€ν–ˆλ“―

μŠ€νƒμ— μ°¨λ‘€λŒ€λ‘œ ν•¨μˆ˜ ν˜ΈμΆœμ„ μŒ“κ³ , λ°˜ν™˜ 값을 LIFO μˆœμ„œλ‘œ μ „λ‹¬ν•˜λ©° κ³„μ‚°ν•˜μ—¬

μ΅œμ’… κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜λŠ” 방식이닀.

 

βœ”οΈ 꼬리 μž¬κ·€ ν•¨μˆ˜

꼬리 μž¬κ·€ ν•¨μˆ˜ 진행 방식

꼬리 μž¬κ·€ ν•¨μˆ˜λŠ” μŠ€νƒμ„ μŒ“μ§€ μ•Šκ³ ,

두 번째 μΈμžμ— 계산 값을 λˆ„μ ν•˜λ©° μ „λ‹¬ν•˜λŠ” 방식이닀.

계속 λˆ„μ ν•˜λ‹€κ°€, λ§ˆμ§€λ§‰μ— if문에 걸리면 λˆ„μ  인자 값을 λ°˜ν™˜ν•œλ‹€!

πŸ‘‰ μŠ€νƒμ„ μ‚¬μš©ν•˜μ§€ μ•Šμ•„ μŠ€νƒ μ˜€λ²„ν”Œλ‘œμš°κ°€ λ°œμƒν•  μœ„ν—˜μ΄ μ—†λ‹€. !!

 

그럼 이제 문제의 ν”Όλ³΄λ‚˜μΉ˜ ν•¨μˆ˜λ₯Ό 꼬리 μž¬κ·€λ‘œ κ΅¬ν˜„ν•΄λ³΄μž,,!!!!!

λ‚΄κ°€ 이 글을 μ“°κ²Œ 된 계기가 λ°”λ‘œ ν”Όλ³΄λ‚˜μΉ˜μ΄λ‹€.,,

μž¬κ·€λ₯Ό κ³΅λΆ€ν•˜κ³ , ν”Όλ³΄λ‚˜μΉ˜ 문제λ₯Ό λ‹€μ‹œ λ³΄λ‹ˆ μž¬κ·€λ‘œ ν’€λ©΄ 쒋을 것 κ°™μ•„ λ°”λ‘œ ν•΄λ΄€λŠ”λ°,,

였λ₯˜κ°€ μ•Όλ¬΄μ§€κ²Œ λ°œμƒν•˜μ—¬,, 이유λ₯Ό μ°Ύλ‹€κ°€ μ—¬κΈ°κΉŒμ§€ μ™”λ‹€.


πŸ“Ž ν”Όλ³΄λ‚˜μΉ˜ 수 계산 κ΅¬ν˜„

ν”Όλ³΄λ‚˜μΉ˜ 수λ₯Ό κ΅¬ν•˜λŠ” ν•¨μˆ˜λ₯Ό 일반 μž¬κ·€, 꼬리 μž¬κ·€λ₯Ό μ΄μš©ν•΄ 각각 κ΅¬ν˜„ν–ˆλ‹€.

// 일반 μž¬κ·€
func Fibo(_ n: Int) -> Int {
    if n == 0 || n == 1 { return n }
    return Fibo(n - 1) + Fibo(n - 2)
}

// 꼬리 μž¬κ·€
func tailFibo(_ num: Int, _ n: Int, _ sum: Int) -> Int {
    if num == 1 { return sum }
    return tailFibo(num - 1, sum, n + sum)
}

print(tailFibo(5, 0, 1))
print(Fibo(5))

일반 μž¬κ·€μ˜ 경우, μœ„μ˜ μ˜ˆμ‹œμ²˜λŸΌ μž‘μ€ 수의 ν”Όλ³΄λ‚˜μΉ˜λ₯Ό ꡬ할 λ•ŒλŠ” λ¬Έμ œκ°€ μ—†μ§€λ§Œ

ν•¨μˆ˜ ν˜ΈμΆœμ„ μ•„μ£Ό 많이 λ°˜λ³΅ν•΄μ•Ό ν•˜λŠ” μƒν™©μ—μ„œλŠ” 였λ₯˜κ°€ λ°œμƒν•œλ‹€.

 

꼬리 μž¬κ·€μ˜ κ²½μš°μ—λŠ” 맨 λ’€ 인자 sum에 λˆ„μ λœ 계산 κ²°κ³Όλ₯Ό λ°˜ν™˜ν•œλ‹€.

λ”°λΌμ„œ μŠ€νƒμ„ μŒ“μ„ ν•„μš”λ„, μŠ€νƒ μ˜€λ²„ν”Œλ‘œμš° λ°œμƒ κ°€λŠ₯성도 사라진닀.


πŸ‘€ 정리

꼬리 μž¬κ·€ ν•¨μˆ˜λŠ” 일반 μž¬κ·€ ν•¨μˆ˜μ˜ 단점을 λ³΄μ™„ν•œλ‹€.

ν•¨μˆ˜ 호좜 μŠ€νƒμ„ μŒ“λŠ” λŒ€μ‹  νŒŒλΌλ―Έν„°λ₯Ό μΆ”κ°€ν•˜μ—¬ 계산을 λˆ„μ ν•œλ‹€.

 


μ°Έκ³