Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

Python Recursion: คู่มือการใช้งาน Recursion ใน Python

วิธีใช้ Python Recursion

Python recursion เป็นหัวข้อที่น่ากลัวสำหรับผู้เริ่มต้น มาถอดมายาความเชื่อว่าการเรียกซ้ำ (recursion) ยากลำบากโดยการกำหนดคำจำกัดความ Recursion คือวิธีการเขียนโปรแกรมที่ฟังก์ชันเรียกตัวเอง

聽起來简单, 对吧? 当你掌握了它, 递归并不是一个困难的概念。

ในบทช่วยสอน Python นี้ เราจะพูดถึง recursion และวิธีการทำงาน เราจะเดินทางผ่านตัวอย่างของ recursion โดยใช้ฟังก์ชันแฟกทอเรียลเพื่อช่วยให้คุณเริ่มต้นกับวิธีการเขียนโปรแกรมนี้ได้

Recursion คืออะไร?

Recursion คือการที่คุณกำหนดสิ่ง gìในรูปแบบของตัวมันเอง

ฟังก์ชันเรียกซ้ำแก้ปัญหาโดยการเรียกตัวเองซ้ำอีกครั้ง พฤติกรรมนี้รองรับในภาษาโปรแกรมมิ่งหลักๆ เช่น Python พวกมันเป็นส่วนสำคัญของวิทยาการคอมพิวเตอร์และวิทยาการข้อมูล

Recursion มีประโยชน์เมื่อคำตอบของปัญหาสามารถหาได้โดยการแยกมันออกเป็นปัญหาย่อยๆ ซึ่งทั้งหมดใช้สูตรเดียวกัน ปัญหาเหล่านี้มักเรียกว่า "recursive algorithms" กุญแจสู่การแก้ไขอยู่ที่ชื่อ!

Iterative vs. Recursive

มีสองวิธีในการแก้อัลกอริทึม: แบบวนซ้ำ (iteratively) หรือแบบเรียกซ้ำ (recursively)

วิธีแก้ปัญหาแบบวนซ้ำถูกมองว่า "มีพลังแต่ไม่สวยงาม" พวกมันทำงานเสร็จ แต่ไม่ได้ทำในวิธีที่ซับซ้อนที่สุด เพื่อเข้าใจ recursive algorithms อย่างถูกต้อง เราต้อง看ฟังก์ชันแบบวนซ้ำ

ฟังก์ชันแบบวนซ้ำคือฟังก์ชันที่แก้ปัญหาโดยใช้ลูป มันจะ execute โค้ดภายในลูปจนกว่าลูปจะเสร็จ ฟังก์ชันเรียกซ้ำคือฟังก์ชันที่แยกปัญหาออกเป็นส่วนย่อยและแก้แต่ละส่วนโดยการเรียกตัวเอง

แฟกทอเรียล: ตัวอย่างแบบวนซ้ำ (Iterative Example)

แฟกทอเรียลเป็นวิธีที่ดีในการสาธิต recursion และการคิดแบบวนซ้ำ ในคณิตศาสตร์ แฟกทอเรียลคือผลรวมของตัวเลขและทุกตัวเลขก่อนหน้าคูณรวมกัน

แฟกทอเรียลของ 5 เท่ากับ 5 * 4 * 3 * 2 * 1 แฟกทอเรียลของ 2 เท่ากับ 2 * 1

เพื่อคำนวณแฟกทอเรียล เราสามารถเขียนฟังก์ชันแบบวนซ้ำได้:

def factorial(number): total = 1 for n in range(1, number + 1): total = total * n return total

ฟังก์ชันนี้ใช้ลูป for เพื่อวนซ้ำผ่านตัวเลขทั้งหมดในช่วงของ 1 และตัวเลขที่เราระบุบวก 1 สำหรับแต่ละการวนซ้ำ ตัวเลขที่ลูปกำลังวนซ้ำจะถูกคูณกับ total มาเรียกฟังก์ชันของเราเพื่อหาแฟกทอเรียล:

answer = factorial(4) print(answer)

โค้ดของเราคืนค่า: 24 เพื่อให้ได้คำตอบนี้ โค้ดของเรารัน:

  • 1 * 1 = 1
  • 2 * 2 = 4
  • 4 * 3 = 8
  • 8 * 4 = 24

ตามที่เห็น โค้ดของเราคูณ 4 กับตัวเลขทั้งหมดที่ต่ำกว่ามันและตัวมันเอง

โค้ดนี้ทำงานได้ ข้อเสียเพียงอย่างเดียวคือมันไม่ได้สวยงามเท่าที่ควร นี่คือที่ที่ฟังก์ชันเรียกซ้ำเข้ามาช่วย

แฟกทอเรียล: ตัวอย่าง Recursion

มาเขียนฟังก์ชันเรียกซ้ำที่คำนวณแฟกทอเรียล เปิดไฟล์ Python ใหม่และวางโค้ดต่อไปนี้:

def factorial(number): if number == 1: return 1 else: return (number * factorial(number - 1))

โค้ดนี้ใช้วิธีแบบเรียกซ้ำ เมื่อฟังก์ชันนี้รัน คำสั่ง "if" จะถูก execute คำสั่งนี้ตรวจสอบว่าตัวเลขที่ส่งให้ฟังก์ชันเท่ากับ 1 หากใช่ ฟังก์ชันของเราคืนค่า 1 มิฉะนั้น แฟกทอเรียลของตัวเลขของเราจะถูกคำนวณ

การคำนวณนี้ทำงานโดยการคูณตัวเลขที่ส่งให้ฟังก์ชันด้วยแฟกทอเรียลของตัวเลขก่อนหน้า ฟังก์ชันนี้ถูกเรียกซ้ำๆ จนกว่า "number" จะเท่ากับ 1 ทุกครั้งที่ฟังก์ชันถูกเรียก ค่าของ "number" จะลดลง 1

มาให้โค้ดของเราลองกับตัวเลข 4:

answer = factorial(4) print(answer)

คำตอบ 24 ถูกคืนค่า คำตอบของเราถูกต้อง เหมือนกับตัวอย่างก่อนหน้า เราได้หาคำตอบของปัญหานี้แบบเรียกซ้ำแทนที่จะเป็นแบบวนซ้ำ

คุณยังต้องการความช่วยเหลือเล็กน้อย? มาเดินทางผ่านตัวอย่างอีกตัวอย่างของ recursion

Recursion กับลำดับฟีโบนัชชี (Fibonacci Sequence)

ลำดับฟีโบนัชชีเป็นลำดับคณิตศาสตร์ที่ตัวเลขแต่ละตัวคือผลรวมของสองตัวเลขก่อนหน้า ลำดับนี้เริ่มต้นด้วย: 0, 1, 1, 2, 3, 5, 8, 13, และต่อไป

ลำดับนี้บวกสองตัวเลขเพื่อหาตัวเลขถัดไป ทำให้มันเหมาะสำหรับ recursion

เปิดไฟล์ Python และวางโค้ดนี้:

def fibonacci(number): if number <= 1: return number else: return(fibonacci(number - 1) + fibonacci(number - 2))

โค้ดนี้จะคำนวณผลรวมของสองตัวเลขก่อนหน้าในรายการ ตราบใดที่ "number" มากกว่า 1 มิฉะนั้น "number is returned" ตอนนี้ มาเรียกฟังก์ชันของเรา:

executions = 5 print("Fibonacci Sequence:") for number in range(executions): print(fibonacci(number))

ตัวแปร executions ติดตามว่าต้องการคำนวณตัวเลขในลำดับฟีโบนัชชีกี่ตัว เราใช้มันเพื่อสร้างลูป for ซึ่งเรียกฟังก์ชัน fibonacci() ของเราสำหรับแต่ละตัวเลขในช่วงของ 1 และค่าของ "executions"

ก่อนที่ลูป for จะเริ่ม เราพิมพ์ "Fibonacci Sequence:" ไปยังคอนโซล ในตัวอย่างนี้ ลูป "for" ของเรา execute:

fibonacci(1) fibonacci(2) fibonacci(3) fibonacci(4) fibonacci(5)

มารันโค้ดของเราทั้งหมดและ看看发生什么:

Fibonacci Sequence: 0 1 1 2 3

โค้ดของเราคำนวณตัวเลขห้าตัวแรกในลำดับฟีโบนัชชี เราสามารถคำนวณตัวเลขมากขึ้นได้โดยเพิ่มค่าของ "executions"

ความลึกของ Recursion และเงื่อนไขฐาน (Base Conditions)

ฟังก์ชันเรียกซ้ำต้องมีเงื่อนไขฐาน (base condition) นี่คือเงื่อนไขที่หยุด recursion เมื่อกรณีฐาน (base case) เฉพาะเจาะจงถูกตอบสนอง โดยไม่มีฟังก์ชันฐาน ลูปไม่รู้จบจะถูกสร้างขึ้น

ฟังก์ชันเรียกซ้ำสามารถ execute ตัวเองได้ไม่เกิน 1,000 ครั้งโดยค่าเริ่มต้น เมื่อถึงขีดจำกัดนี้ ข้อผิดพลาดแบบนี้จะปรากฏ:

RecursionError: maximum recursion depth exceeded

นี่คือเงื่อนไขฐานสำหรับโปรแกรมฟีโบนัชชีของเรา:

... if number <= 1: return number …

เงื่อนไขนี้ตรวจสอบว่าค่าของ "number" ภายในโปรแกรมฟีโบนัชชีของเราเท่ากับหรือน้อยกว่า 1 หากใช่ ค่าของ "number" จะถูกคืนค่า มิฉะนั้น ฟังก์ชันเรียกซ้ำจะเริ่มต้น

ทำไมควรใช้ Recursion?

ข้อได้เปรียบของการใช้ recursion เหนือฟังก์ชันแบบวนซ้ำคืออะไร? ทางเทคนิค ทั้งสองวิธีสามารถบรรลุผลลัพธ์เดียวกันได้ ข้อได้เปรียบของ recursion คือมันอ่านง่ายกว่า

เมื่อคุณเห็นฟังก์ชันเรียกซ้ำ มันชัดเจนว่าคำตอบของปัญหาอยู่ที่การแยกมันออกเป็นส่วนย่อย ในขณะที่ลูปแบบวนซ้ำบางครั้งอาจเร็วกว่า ฟังก์ชันเรียกซ้ำมักถูกเลือกเนื่องจากความอ่านง่าย

เพราะฟังก์ชันเรียกซ้ำอ่านง่าย จึงง่ายต่อการบำรุงรักษาและแก้ไขข้อบกพร่อง (debug)ด้วย นี่มีประโยชน์โดยเฉพาะเมื่อคุณเขียนอัลกอริทึมซับซ้อนที่อาจเข้าใจยาก

สรุป

ฟังก์ชันเรียกซ้ำคือฟังก์ชันที่เรียกตัวเองเพื่อหาคำตอบของปัญหา 

ฟังก์ชันเรียกซ้ำแยกปัญหาออกเป็นหลายส่วนและแก้ส่วนหนึ่งของปัญหาต่อการวนซ้ำ ฟังก์ชันเรียกซ้ำมักใช้คำนวณแฟกทอเรียลและตัวเลขในลำดับฟีโบนัชชี พวกมันยังใช้ในอัลกอริทึมหลายอย่าง

ตอนนี้คุณพร้อมที่จะเริ่มทำงานกับฟังก์ชันเรียกซ้ำใน Python แล้ว