λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
5️⃣ CS/Algorithm

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

by seolhee2750 2021. 7. 8.

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

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

μž¬κ·€ ν•¨μˆ˜λŠ” 말 κ·ΈλŒ€λ‘œ,
ν•¨μˆ˜μ—μ„œ κ·Έ ν•¨μˆ˜λ₯Ό λΆ€λ₯΄κ³ , 또 λΆ€λ₯΄κ³ ...!λ₯Ό λ°˜λ³΅ν•˜λŠ” 것이닀.

μž¬κ·€ ν•¨μˆ˜μ˜ λŒ€ν‘œμ μΈ μ˜ˆλŠ” λ°”λ‘œ νŒ©ν† λ¦¬μ–Όμ΄λ‹€.
νŒ©ν† λ¦¬μ–Ό ν•¨μˆ˜λ₯Ό κ΅¬ν˜„ν•΄λ΄„μœΌλ‘œμ¨ μž¬κ·€ ν•¨μˆ˜λ₯Ό μ΄ν•΄ν•΄λ³΄μž.

πŸ“Œ νŒ©ν† λ¦¬μ–Ό ν•¨μˆ˜ κ΅¬ν˜„

νŒ©ν† λ¦¬μ–Ό κ³„μ‚°μ˜ 진행 방식을 κ°„λ‹¨νžˆ μž‘μ„±ν–ˆλ‹€.

μœ„μ™€ 같이 νŒ©ν† λ¦¬μ–Όμ€ (μš”κ΅¬ν•œ 숫자) * (κ·Έ μ „ 숫자의 νŒ©ν† λ¦¬μ–Ό κ°’) 의 μ‹μœΌλ‘œ κ΅¬μ„±λ˜κ³ ,
이λ₯Ό κ°„λ‹¨νžˆ ν‘œν˜„ν•˜λ©΄ (num) * (num -1)! 이 λ˜κ² λ‹€.

μ—¬κΈ°μ„œ μ•Œ 수 μžˆλŠ” 점은
3!을 κ΅¬ν•˜λ €λ©΄ 2!을 ꡬ해야 ν•˜κ³ , 2!을 κ΅¬ν•˜λ €λ©΄ 1!λ₯Ό ꡬ해야 ν•˜λŠ” λ°©μ‹μœΌλ‘œ,
꼬리에 꼬리λ₯Ό λ¬΄λŠ” 풀이 방식이 ν•„μš”ν•˜λ‹€λŠ” 것이닀.
πŸ‘‰ νŒ©ν† λ¦¬μ–Όμ„ ν¬ν•¨ν•˜μ—¬, 이런 λ°©μ‹μ˜ 풀이가 ν•„μš”ν•  λ•Œ! λ°”λ‘œ μž¬κ·€ν•¨μˆ˜λ₯Ό μœ μš©ν•˜κ²Œ μ‚¬μš©ν•  수 μžˆλ‹€.

μœ„μ˜ λ‚΄μš©μ„ μ½”λ“œλ‘œ ν™•μΈν•΄λ³΄μž.

func Factorial(_ num: Int) -> Int {
    if num < 2 { return num }
    return Factorial(num-1) * num
}

print(Factorial(3)) // 6
print(Factorial(5)) // 120

λ¨Όμ € Factorial ν•¨μˆ˜μ˜ return 문을 보면, μœ„μ—μ„œ κ΅¬ν•œ num * (num - 1)! 을 ν‘œν˜„ν•œ 것을 확인 κ°€λŠ₯ν•˜λ‹€.
μž…λ ₯ν•œ num 값에 λŒ€ν•΄ num - 1에 ν•΄λ‹Ήν•˜λŠ” Factorial ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜κ³ , num 값을 κ³±ν•΄ λ¦¬ν„΄ν•œλ‹€.
전체적인 λ‘œμ§μ„ μ‚΄νŽ΄λ³΄λ©΄, if 문에 μž‘μ„±ν•œ μ˜ˆμ™Έμ²˜λ¦¬μ— 도달할 λ•ŒκΉŒμ§€ ν•¨μˆ˜ ν˜ΈμΆœμ„ λ°˜λ³΅ν•˜λ‹€κ°€
num이 2보닀 μž‘μ•„μ§€λ©΄ return num ꡬ문을 μ‹œμž‘μœΌλ‘œ, μŒ“μ•„λ†“μ€ 계산을 μ§„ν–‰ν•˜κ²Œ λ˜λŠ” 방식이닀.

λͺ‡ 쀄 λ˜μ§€ μ•ŠλŠ” κ°„λ‹¨ν•œ ν•¨μˆ˜μ§€λ§Œ,
막상 κ΅¬ν˜„ν•˜λ €κ³  ν•˜λ©΄ λ³΅μž‘ν•˜κ²Œ λŠκ»΄μ§€λŠ”κ²Œ λ°”λ‘œ 이 μž¬κ·€ν•¨μˆ˜μΈλ“― ν•˜λ‹€.γ…œ
말둜 적은 μ„€λͺ…이 쑰금 μ–΄λ €μš°λ‹ˆ,, λŒ€ν‘œλ‘œ Factorial(3)의 처리 과정을 그림으둜 ν™•μΈν•΄λ³΄μž.

λ©”λͺ¨λ¦¬μ— ν•¨μˆ˜κ°€ μ €μž₯λ˜λŠ” 과정을 μˆœμ„œλŒ€λ‘œ ν‘œν˜„ν–ˆλ‹€.
μš°μ„  3을 μž…λ ₯ν–ˆκΈ°μ— Factorial(2)λ₯Ό ν˜ΈμΆœν•˜κ³ , Factorial(2)λŠ” 또 Factorial(1)을 ν˜ΈμΆœν•œλ‹€.
이 λ•Œ 1은 2보닀 μž‘μœΌλ―€λ‘œ if문이 μ‹€ν–‰λ˜μ–΄ 1을 λ°˜ν™˜ν•˜κ²Œ 되고, 본격적인 νŒ©ν† λ¦¬μ–Ό 계산이 μ‹œμž‘λœλ‹€.

μ΄λ ‡κ²Œ LIFO μˆœμ„œλŒ€λ‘œ (stack ꡬ쑰이기 λ•Œλ¬Έ)
λ§ˆμ§€λ§‰ return κ°’μœΌλ‘œ 이전에 호좜된 ν•¨μˆ˜μ˜ 계산 κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜κ³ ,
또 κ·Έ κ²°κ³Ό κ°’μœΌλ‘œ κ·Έ 이전 호좜된 ν•¨μˆ˜μ˜ 계산 κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜λŠ” λ°©μ‹μœΌλ‘œ μ§„ν–‰λ˜λŠ” 것이닀.
λ”°λΌμ„œ μ΅œμ’… return κ°’μœΌλ‘œ 6이 λ°˜ν™˜λ¨μ„ 확인할 수 μžˆλ‹€.


πŸ“Ž μž¬κ·€ ν•¨μˆ˜μ˜ κΈ°λ³Έ ν˜•νƒœ

μœ„μ—μ„œ νŒ©ν† λ¦¬μ–Ό ν•¨μˆ˜λ₯Ό κ΅¬ν˜„ν•΄λ³΄λ©° μž¬κ·€ν•¨μˆ˜μ— κΌ­ ν•„μš”ν•œ ν•„μˆ˜ μš”μ†Œλ“€μ΄ μžˆμŒμ„ μ•Œ 수 μžˆμ—ˆλ‹€.
μž¬κ·€ν•¨μˆ˜μ˜ ν•„μˆ˜ μš”μ†Œλ“€μ„ 체크해보고, κΈ°λ³Έ ν˜•νƒœλ₯Ό μ •λ¦¬ν•΄λ³΄μž.

πŸ“Œ μž¬κ·€ν•¨μˆ˜μ˜ ν•„μˆ˜ μš”μ†Œ

  • ν•¨μˆ˜ νƒˆμΆœ 쑰건
  • ν•¨μˆ˜ 호좜
  • 리턴 κ°’

λ¬΄ν•œ λ°˜λ³΅μ— 빠지지 μ•Šλ„λ‘ ν•˜κΈ° μœ„ν•΄ νƒˆμΆœ 쑰건을 μ •ν™•νžˆ λͺ…μ‹œν•΄μ£Όκ³ ,
μž¬κ·€ ν•¨μˆ˜μ˜ 핡심인 ν•¨μˆ˜ 슀슀둜λ₯Ό ν˜ΈμΆœν•˜λŠ” ꡬ문을 잘 μž‘μ„±ν•΄μ€€λ‹€λ©΄ μž¬κ·€ν•¨μˆ˜μ˜ κΈ°λ³Έ ν˜•νƒœλŠ” μ™„μ„±λœλ‹€.

func recursiveCall(_ num: Int) -> /*λ°˜ν™˜ νƒ€μž…*/ {
    if /*νƒˆμΆœ 쑰건*/ { return /*λ°˜λ³΅λ˜λŠ” ν•¨μˆ˜ 호좜의 μ’…λ£Œμ΄μž, 첫 번째 λ°˜ν™˜ κ°’*/ }
    return return recursiveCall(/*μƒˆλ‘œμš΄ μž…λ ₯ κ°’*/)
}

μœ„μ—μ„œ μž‘μ„±ν•œ ν•„μˆ˜ 쑰건을 기반으둜 μž¬κ·€ ν•¨μˆ˜μ˜ κΈ°λ³Έ ν˜•νƒœλ₯Ό μž‘μ„±ν–ˆλ‹€.
λ‹€μ–‘ν•œ μž¬κ·€ ν•¨μˆ˜λ“€μ΄ μ‘΄μž¬ν•˜κ² μ§€λ§Œ, κ°€μž₯ 기본적인 μΌ€μ΄μŠ€λ₯Ό ν‘œν˜„ν–ˆλ‹€.


πŸ‘€ 정리

νŒ©ν† λ¦¬μ–Ό ν•¨μˆ˜μ˜ κ΅¬ν˜„μ„ 톡해 μž¬κ·€ ν•¨μˆ˜λ₯Ό μ΄ν•΄ν•˜κ³ , μ‚¬μš© 방법을 κ³΅λΆ€ν–ˆλ‹€.

μž¬κ·€ ν•¨μˆ˜λŠ” ν•œλ§ˆλ””λ‘œ 'LIFO 반볡 ν•¨μˆ˜'라고 ν‘œν˜„ν•˜κ³ μ‹Άλ‹€.

κ°œλ…μ€ 어렡지 μ•Šμ§€λ§Œ, 막상 κ΅¬ν˜„ν•˜λ €κ³  ν•˜λ©΄ 머리 μ†μ—μ„œ 버퍼링이 κ±Έλ¦°λ‹€,,
μ •ν™•νžˆ μ΅ν˜”μœΌλ‹ˆ, 무쑰건 μ—°μŠ΅μ„ 많이 ν•΄λ³΄λŠ” 것이 μ€‘μš”ν•  것 κ°™λ‹€.

πŸ’₯ μΆ”κ°€!!

μž¬κ·€ ν•¨μˆ˜λŠ” μž₯점도 λͺ…ν™•ν•˜μ§€λ§Œ, 단점 λ˜ν•œ λͺ…ν™•νžˆ μ‘΄μž¬ν•œλ‹€.

λ”°λΌμ„œ 이 단점을 κ·Ήλ³΅ν•˜κΈ° μœ„ν•œ '꼬리 μž¬κ·€ ν•¨μˆ˜'에 λŒ€ν•œ 글을 λ‹€μŒμ— 닀뀄보렀고 ν•œλ‹€.

 

 

 

λŒ“κΈ€