Bibi's DevLog πŸ€“πŸŽ

[Hello Coding μ•Œκ³ λ¦¬μ¦˜] 3μž₯. μž¬κ·€ λ³Έλ¬Έ

ν”„λ‘œκ·Έλž˜λ°/Algorithm μ•Œκ³ λ¦¬μ¦˜

[Hello Coding μ•Œκ³ λ¦¬μ¦˜] 3μž₯. μž¬κ·€

λΉ„λΉ„ bibi 2021. 6. 30. 22:24

3μž₯. μž¬κ·€

μ‹œμž‘ν•˜κΈ°μ— μ•žμ„œ

  • 예제 μ½”λ“œ 직접 μ‹€ν–‰ν•΄ 보기
  • 적어도 ν•œ λ²ˆμ€ μ—°ν•„κ³Ό 쒅이λ₯Ό 가지고 μž¬κ·€ν•¨μˆ˜μ˜ μ‹€ν–‰ 과정을 따라가 보기.
  • μ˜μ‚¬μ½”λ“œ(pseudocode, μŠˆλ„μ½”λ“œ) : λ¬Έμ œμ™€ 풀이 방법을 κ°„λ‹¨ν•œ μ½”λ“œλ‘œ μ„€λͺ…ν•œ 것. μ‹€μ œλ‘œ λ™μž‘ν•˜μ§„ μ•ŠμŒ

μž¬κ·€ recursion

  • μž¬κ·€
    • ν•¨μˆ˜κ°€ 자기 μžμ‹ μ„ ν˜ΈμΆœν•˜λŠ” 것.

문제 : μ—¬λŸ¬ 겹으둜 포μž₯된 μƒμžλ“€μ΄ 있고, κ·Έ μƒμžκ°€ 또 λ‹€λ₯Έ μƒμžλ“€ 속에 λ“€μ–΄ μžˆλ‹€. λͺ‡ κ°œμΌμ§€ λͺ¨λ₯΄λŠ” μƒμžλ“€ 쀑 μ—΄μ‡ κ°€ λ“€μ–΄μžˆλŠ” μƒμžλ₯Ό μ°Ύμ•„μ•Ό ν•œλ‹€.

방법 1 : 반볡문 μ‚¬μš©ν•˜κΈ°

  1. λ‚΄λΆ€λ₯Ό 확인할 μƒμžλ₯Ό μŒ“μ•„λ†“λŠ”λ‹€(=μƒμž 더미).
  2. μƒμž ν•˜λ‚˜λ₯Ό μ§‘μ–΄μ„œ λ‚΄λΆ€λ₯Ό ν™•μΈν•œλ‹€.
    1. λ§Œμ•½ μ•ˆμ— μƒμžκ°€ μžˆλ‹€λ©΄, 확인할 μƒμž 더미에 놓은 λ’€ 2둜 λŒμ•„κ°„λ‹€.
    2. λ§Œμ•½ μ•ˆμ— μ—΄μ‡ κ°€ μžˆλ‹€λ©΄ μž‘μ—…μ„ μ’…λ£Œν•œλ‹€.

μ•„λž˜λŠ” μœ„ 과정에 λŒ€ν•œ μŠˆλ„μ½”λ“œ.

def look_for_key(main_box):
    pile = main_box.make_a_pile_to_look_through()
    while pile is not empty:
        box = pile.grab_a_box()
        for item in box:
            if item.is_a_box():
                pile.append(item)
            elif item.is_a_key():
                print "μ—΄μ‡ λ₯Ό μ°Ύμ•˜μ–΄μš”!"

방법 2 : μž¬κ·€ μ‚¬μš©ν•˜κΈ°

  1. μƒμž μ•ˆμ„ ν™•μΈν•œλ‹€.
    1. λ§Œμ•½ μƒμžλ₯Ό λ°œκ²¬ν•˜λ©΄ 1.둜 κ°„λ‹€.
    2. λ§Œμ•½ μ—΄μ‡ λ₯Ό λ°œκ²¬ν•˜λ©΄ μž‘μ—…μ„ μ’…λ£Œν•œλ‹€.

μ•„λž˜λŠ” μœ„ 과정에 λŒ€ν•œ μŠˆλ„μ½”λ“œ.

def look_for_key(box):
    for item in box:
        if item.is_a_box():
            look_for_key(item)
        elif item.is_a_key():
            print "μ—΄μ‡ λ₯Ό μ°Ύμ•˜μ–΄μš”!"

μž¬κ·€μ˜ νŠΉμ§•

  • μ•Œκ³ λ¦¬μ¦˜ 풀이λ₯Ό λͺ…ν™•ν•˜κ²Œ ν•΄ μ€€λ‹€.
    • μ„±λŠ₯이 더 λ‚˜μ•„μ§€λŠ” 것은 μ•„λ‹˜. μ„±λŠ₯은 반볡문이 더 μ’‹λ‹€.
  • "ν”„λ‘œκ·Έλž¨μ— λ°˜λ³΅λ¬Έμ„ μ‚¬μš©ν•˜λ©΄ ν”„λ‘œκ·Έλž¨μ˜ μ„±λŠ₯을 ν–₯μƒμ‹œν‚¬ 수 μžˆμ§€λ§Œ, μž¬κ·€λ₯Ό μ‚¬μš©ν•˜λ©΄ ν”„λ‘œκ·Έλž˜λ¨Έμ˜ λŠ₯λ ₯을 ν–₯μƒμ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€. 상황에 따라 μ μ ˆν•œ 방법을 골라 μ‚¬μš©ν•˜μ„Έμš”."
  • λŒ€λΆ€λΆ„μ˜ μ€‘μš”ν•œ μ•Œκ³ λ¦¬μ¦˜λ“€μ΄ μž¬κ·€λ₯Ό μ‚¬μš©ν•œλ‹€.

κΈ°λ³Έ 단계와 μž¬κ·€ 단계

μž¬κ·€ν•¨μˆ˜λŠ” 자기 μžμ‹ μ„ ν˜ΈμΆœν•˜κΈ° λ•Œλ¬Έμ— λ¬΄ν•œλ£¨ν”„μ— 빠지기 쉽닀.

μž¬κ·€ν•¨μˆ˜λ₯Ό λ§Œλ“€ λ•Œμ—λŠ” μ–Έμ œ μž¬κ·€λ₯Ό λ©ˆμΆœμ§€ λ°˜λ“œμ‹œ μ•Œλ € μ£Όμ–΄μ•Ό ν•œλ‹€.

κ·Έλž˜μ„œ λͺ¨λ“  μž¬κ·€ν•¨μˆ˜λŠ” κΈ°λ³Έ 단계와 μž¬κ·€ λ‹¨κ³„λ‘œ λ‚˜λˆ„μ–΄μ Έ μžˆλ‹€.

  • κΈ°λ³Έ 단계 base case : μž¬κ·€λ₯Ό λΉ μ Έλ‚˜κ°€λŠ” 단계. λ¬΄ν•œλ°˜λ³΅μ— λΉ μ§€λŠ” 것을 λ§‰λŠ” 뢀뢄이닀.
  • μž¬κ·€ 단계 recursive case : ν•¨μˆ˜κ°€ 자기 μžμ‹ μ„ ν˜ΈμΆœν•˜λŠ” 단계.

μ•„λž˜λŠ” μΉ΄μš΄νŠΈλ‹€μš΄μ„ ν•˜λŠ” μ½”λ“œ. (λ¬΄ν•œλ£¨ν”„)

def countdown(i):
    print i
    countdown(i-1)

λ¬΄ν•œλ£¨ν”„ μ½”λ“œμ— κΈ°λ³Έ 단계λ₯Ό μΆ”κ°€ν•˜λ©΄ 정상 λ™μž‘ν•˜λŠ” μž¬κ·€ν•¨μˆ˜λ₯Ό λ§Œλ“€ 수 μžˆλ‹€.

def countdown(i):
    print i
    if i <= 1: ## κΈ°λ³Έ 단계
        return
    else: ## μž¬κ·€ 단계
        countdown(i-1)

μŠ€νƒ (콜 μŠ€νƒ)

호좜 μŠ€νƒμ€ ν”„λ‘œκ·Έλž¨μ˜ μ€‘μš” κ°œλ…μ΄λ‹€. μž¬κ·€λ₯Ό μ‚¬μš©ν•  λ•ŒλŠ” 더 μ€‘μš”ν•˜λ‹€.

μŠ€νƒ stack : ν‘Έμ‹œ(push, μ‚½μž…)와 팝(pop, λΉΌλ‚΄μ„œ 읽기) 두 λ™μž‘λ§Œ κ°€λŠ₯ν•œ 자료ꡬ쑰.

  • ν‘Έμ‹œ : κ°€μž₯ μœ„μ— μƒˆ ν•­λͺ©μ„ μΆ”κ°€
  • 팝 : κ°€μž₯ μœ„μ˜ ν•­λͺ©μ„ λΉΌλ‚΄μ–΄ 읽기

콜 μŠ€νƒ (call stack, 호좜 μŠ€νƒ)

컴퓨터가 ν•¨μˆ˜μ— μ‚¬μš©λ˜λŠ” λ³€μˆ˜λ₯Ό μ €μž₯ν•˜λŠ” μŠ€νƒμ„ 콜 μŠ€νƒμ΄λΌκ³  ν•œλ‹€.

ν•¨μˆ˜κ°€ ν•œ 번 호좜될 λ•Œ λ§ˆλ‹€, μ»΄ν“¨ν„°λŠ” κ·Έ ν•¨μˆ˜ ν˜ΈμΆœμ— ν•„μš”ν•œ λ©”λͺ¨λ¦¬λ₯Ό ν• λ‹Ήν•΄ μŠ€νƒμœΌλ‘œ μŒ“λŠ”λ‹€(push).

  • ν•¨μˆ˜μ— μ‚¬μš©λœ λ³€μˆ˜λ„ ν•΄λ‹Ή ν•¨μˆ˜μ˜ μŠ€νƒ 내에 μ €μž₯λœλ‹€.
  • ν•΄λ‹Ή ν•¨μˆ˜κ°€ μ’…λ£Œ(리턴)되기 μ „κΉŒμ§€ κ·Έ μŠ€νƒμ€ μœ μ§€λœλ‹€.
    • ν•΄λ‹Ή ν•¨μˆ˜κ°€ μ’…λ£Œ(리턴)되면 κ·Έ μŠ€νƒμ€ 사라진닀(pop).
  • ν•¨μˆ˜(A) λ‚΄μ—μ„œ λ‹€λ₯Έ ν•¨μˆ˜(B)λ₯Ό ν˜ΈμΆœν•˜λ©΄, A μŠ€νƒ μœ„μ— B μŠ€νƒμ΄ μŒ“μΈλ‹€.
    • ν•¨μˆ˜ 호좜 ν›„ μ’…λ£Œλ˜κΈ° 전이라도 λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  수 있으며, 이 λ•Œ μ€‘μ§€λœ ν•¨μˆ˜μ˜ λ³€μˆ˜ 값듀은 ν•΄λ‹Ή μŠ€νƒμœΌλ‘œ λ©”λͺ¨λ¦¬μ— μ €μž₯λœλ‹€.
    • 맨 μœ„μ— μŒ“μ—¬ μžˆλŠ” μŠ€νƒμ΄ ν˜„μž¬ μ‹€ν–‰λ˜κ³  μžˆλŠ” ν•¨μˆ˜μ— λŒ€ν•œ μŠ€νƒμ΄λ‹€.

μž¬κ·€ ν•¨μˆ˜μ—μ„œ 콜 μŠ€νƒ μ‚¬μš©

μž¬κ·€ ν•¨μˆ˜λ„ 콜 μŠ€νƒμ„ μ‚¬μš©ν•œλ‹€.

μ•„λž˜λŠ” νŒ©ν† λ¦¬μ–Ό ν•¨μˆ˜μ— λŒ€ν•œ μž¬κ·€ν•¨μˆ˜.

  • μ½œμŠ€νƒ λͺ¨μ–‘은 κΌ­ ꡐ재λ₯Ό ν™•μΈν•˜μž : 59~61νŽ˜μ΄μ§€.
def fact(x):
    if x == 1:
        return 1
    else:
        return x * fact(x-1)

μž¬κ·€ ν•¨μˆ˜μ—μ„œ 콜 μŠ€νƒμ˜ 역할은?

= λ°˜λ³΅λ¬Έμ—μ„œ ν•„μš”ν–ˆλ˜ μƒμž 더미(pile)의 μ—­ν• .

μž¬κ·€λ₯Ό μ‚¬μš©ν•΄ κ΅¬ν˜„ν•˜λ©΄, 확인해야 ν•  μƒμž 더미λ₯Ό μŠ€νƒμ— μ €μž₯ν•˜λŠ” 것과 κ°™λ‹€.

  • μš°λ¦¬κ°€ 직접 μƒμž 더미λ₯Ό λ§Œλ“€κ³  μΆ”μ ν•˜μ§€ μ•Šμ•„λ„ 되기 λ•Œλ¬Έμ— νŽΈλ¦¬ν•œ 것!

콜 μŠ€νƒμ˜ 단점

: λͺ¨λ“  정보λ₯Ό 컴퓨터 λ©”λͺ¨λ¦¬μ— μ €μž₯ν•΄μ•Ό ν•˜λ―€λ‘œ λ©”λͺ¨λ¦¬λ₯Ό 많이 μ†ŒλΉ„ν•œλ‹€.

  • ν•¨μˆ˜ ν˜ΈμΆœμ„ ν•œ 번 ν•  λ•Œλ§ˆλ‹€ λ©”λͺ¨λ¦¬λ₯Ό μ‚¬μš©ν•˜κ²Œ 됨.
  • μž¬κ·€κ°€ κΉŠμ–΄μ Έ μŠ€νƒμ΄ 컀지면, 컴퓨터가 κ³Όλ‹€ν•œ ν•¨μˆ˜ ν˜ΈμΆœμ •λ³΄λ₯Ό μ €μž₯ν•˜κ²Œ 됨
  • μž¬κ·€κ°€ κΉŠμ–΄μ§€λ©΄(특히 λ¬΄ν•œλ£¨ν”„μ— 빠지면) μŠ€νƒμ΄ 계속 μ»€μ§€λŠ”λ°, λͺ¨λ“  ν”„λ‘œκ·Έλž¨μ€ μ½œμŠ€νƒμ— ν• λ‹Ήν•  수 μžˆλŠ” λ©”λͺ¨λ¦¬ 곡간이 μ •ν•΄μ Έ μžˆμœΌλ―€λ‘œ κ·Έ 곡간을 λ‹€ μ‚¬μš©ν•˜λ©΄ μŠ€νƒ μ˜€λ²„ν”Œλ‘œμš° 였λ₯˜κ°€ λ°œμƒν•˜λ©° ν”„λ‘œκ·Έλž¨μ΄ μ’…λ£Œλœλ‹€.

ν•΄κ²° 1 : μž¬κ·€ λŒ€μ‹  반볡문으둜 μ „ν™˜

ν•΄κ²° 2 : κΌ¬λ¦¬μž¬κ·€ tail recursion 방법을 μ‚¬μš© - κ³ κΈ‰ μž¬κ·€ 방법.