การเรียกซ้ำหรือในขณะที่ลูป


123

ฉันกำลังอ่านเกี่ยวกับการสัมภาษณ์การพัฒนาโดยเฉพาะเกี่ยวกับคำถามทางเทคนิคและการทดสอบที่ถามในการสัมภาษณ์และฉันได้พบคำพูดของประเภท "ไม่กี่ครั้ง" ตกลงคุณแก้ปัญหาด้วยการวนขณะนี้คุณสามารถทำกับ การเรียกซ้ำ "หรือ" ทุกคนสามารถแก้ปัญหานี้ด้วย 100 บรรทัดในขณะที่วนซ้ำ แต่พวกเขาสามารถทำได้ในฟังก์ชั่นวนซ้ำ 5 บรรทัดหรือไม่? " เป็นต้น

คำถามของฉันคือการเรียกซ้ำโดยทั่วไปดีกว่าถ้า / ในขณะ / สำหรับการสร้างหรือไม่

ฉันคิดเสมอว่าการเรียกซ้ำไม่ควรเลือกเพราะมัน จำกัด หน่วยความจำสแต็คที่เล็กกว่าฮีปมากการทำฟังก์ชั่น / เมธอดเป็นจำนวนมากนั้นไม่ดีเท่าที่ควร แต่ฉันอาจ จะผิด...



73
ในเรื่องของการเรียกซ้ำสิ่งนี้ดูน่าสนใจทีเดียว
dan_waterworth

4
@dan_waterworth เช่นนี้จะช่วย: google.fr/…แต่ฉันมักจะสะกดคำผิดเสมอ: P
Shivan Dragon

@ShivanDragon ฉันคิดอย่างนั้น ^ _ ^ เหมาะสมมากที่ฉันโพสต์เมื่อวานนี้ :-)
Neal

2
ในสภาพแวดล้อมแบบฝังตัวที่ฉันทำงานในการเรียกซ้ำถูกดึงออกมาอย่างดีที่สุดและทำให้คุณโดนเฆี่ยนตีอย่างเลวร้ายที่สุด การใช้พื้นที่สแต็ก จำกัด ทำให้ผิดกฎหมาย
Fred Thomsen

คำตอบ:


192

การเรียกซ้ำนั้นไม่ได้ดีกว่าหรือแย่กว่าการวนซ้ำมาก - แต่ละคนมีข้อดีและข้อเสียและผู้ใช้ก็ต้องพึ่งพาภาษาการเขียนโปรแกรม

ในทางเทคนิคแล้ววนซ้ำเหมาะกับระบบคอมพิวเตอร์ทั่วไปที่ดีกว่าในระดับฮาร์ดแวร์: ที่ระดับรหัสเครื่องการวนรอบเป็นเพียงการทดสอบและการกระโดดแบบมีเงื่อนไขในขณะที่การเรียกซ้ำ (นำไปใช้อย่างไร้เดียงสา) เกี่ยวข้องกับการผลักเฟรม จากสแต็ก OTOH หลายกรณีของการเรียกซ้ำ (โดยเฉพาะอย่างยิ่งผู้ที่มีความหมายเทียบเท่ากับลูปซ้ำ) สามารถเขียนได้เพื่อให้สามารถหลีกเลี่ยงการวางซ้อน / ป๊อปอัพได้ สิ่งนี้เป็นไปได้เมื่อการเรียกฟังก์ชันแบบเรียกซ้ำเป็นสิ่งสุดท้ายที่เกิดขึ้นในร่างกายของฟังก์ชั่นก่อนกลับมาและเป็นที่รู้จักกันโดยทั่วไปว่าเป็นการเพิ่มประสิทธิภาพการโทรหาง (หรือการเพิ่มประสิทธิภาพการเรียกซ้ำแบบหาง ) ฟังก์ชั่นการเรียกซ้ำแบบเรียกซ้ำที่ได้รับการออกแบบมาอย่างเหมาะสมนั้นส่วนใหญ่เทียบเท่ากับลูปวนซ้ำที่ระดับรหัสเครื่อง

สิ่งที่ต้องพิจารณาอีกประการคือลูปแบบวนซ้ำจำเป็นต้องมีการอัปเดตสถานะที่เป็นอันตรายซึ่งทำให้พวกมันขัดกับความหมายของภาษาที่บริสุทธิ์ (ไม่มีผลข้างเคียง) นี่คือเหตุผลที่ภาษาบริสุทธิ์อย่าง Haskell ไม่มีโครงสร้างวนซ้ำและภาษาโปรแกรมการทำงานอื่น ๆ อีกมากมายขาดทั้งภาษาอย่างสมบูรณ์หรือหลีกเลี่ยงพวกมันให้มากที่สุด

เหตุผลที่คำถามเหล่านี้ปรากฏในการสัมภาษณ์มากเป็นเพราะเพื่อตอบคำถามคุณต้องมีความเข้าใจอย่างถ่องแท้เกี่ยวกับแนวคิดการเขียนโปรแกรมที่สำคัญหลายอย่าง - ตัวแปรการเรียกใช้ฟังก์ชันขอบเขตและการวนซ้ำและการวนซ้ำ - และคุณมี เพื่อนำความยืดหยุ่นทางจิตมาไว้ในตารางที่ช่วยให้คุณเข้าถึงปัญหาจากมุมที่แตกต่างกันสองมุมและย้ายไปมาระหว่างการแสดงที่แตกต่างกันของแนวคิดเดียวกัน

ประสบการณ์และการวิจัยชี้ให้เห็นว่ามีเส้นแบ่งระหว่างคนที่มีความสามารถในการเข้าใจตัวแปรพอยน์เตอร์และการเรียกซ้ำและผู้ที่ไม่เข้าใจ เกือบทุกอย่างอื่นในการเขียนโปรแกรมรวมถึงเฟรมเวิร์ก API ภาษาการเขียนโปรแกรมและกรณีขอบของพวกเขาสามารถได้รับผ่านการศึกษาและประสบการณ์ แต่ถ้าคุณไม่สามารถพัฒนาสัญชาตญาณสำหรับแนวคิดหลักสามข้อนี้คุณก็ไม่เหมาะที่จะเป็นโปรแกรมเมอร์ การแปลลูปวนซ้ำแบบง่าย ๆ เป็นเวอร์ชันแบบเรียกซ้ำเป็นวิธีที่เร็วที่สุดในการกรองผู้ที่ไม่ใช่โปรแกรมเมอร์ - แม้ว่าโปรแกรมเมอร์ที่ไม่มีประสบการณ์จะสามารถทำได้ภายใน 15 นาทีและเป็นปัญหาทางภาษาดังนั้นผู้สมัครสามารถเลือกได้ ภาษาที่พวกเขาเลือกแทนที่จะสะดุดกับความงี่เง่า

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


3
ฉันชอบคำตอบของคุณดีที่สุดเพราะมันสัมผัสกับส่วนที่สำคัญที่สุดที่คำตอบสำหรับคำถามนี้อาจจะอธิบายส่วนทางเทคนิคที่สำคัญและยังให้มุมมองซูมออกที่ดีว่าปัญหานี้เหมาะกับการเขียนโปรแกรมทรงกลม
Shivan Dragon

1
ฉันยังได้สังเกตเห็นรูปแบบในการเขียนโปรแกรมซิงค์ที่หลีกเลี่ยงการวนซ้ำเพื่อเรียกซ้ำใน iterator ที่มีวิธีการ. next () ฉันคิดว่ามันจะป้องกันไม่ให้โค้ดที่รันนานเกินไปกลายเป็นความโลภของ CPU
Evan Plaice

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

1
@tdammers คุณช่วยบอกฉันได้ไหมว่าฉันสามารถอ่านการศึกษาที่คุณพูดถึง "ประสบการณ์และการวิจัยชี้ให้เห็นว่ามีเส้นแบ่งระหว่างคน ... " นี่น่าจะน่าสนใจมากสำหรับฉัน
Yoo Matsuo

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

37

มันขึ้นอยู่กับ.

  • ปัญหาบางอย่างคล้อยตามแนวทางแก้ไขซ้ำเช่นquicksort
  • บางภาษาไม่รองรับการเรียกซ้ำเช่นFORTRAN ในช่วงต้น
  • บางภาษาถือว่าการเรียกซ้ำเป็นวิธีหลักในการวนลูปเช่นHaskell

นอกจากนี้ยังเป็นที่น่าสังเกตว่าการรองรับการเรียกซ้ำแบบหางทำให้การวนซ้ำแบบซ้ำและการวนซ้ำแบบวนซ้ำนั้นเทียบเท่ากันนั่นคือการเรียกซ้ำไม่จำเป็นต้องเสียสแต็กเสมอไป

นอกจากนี้ขั้นตอนวิธี recursive จะสามารถนำมาใช้ซ้ำโดยใช้สแต็คอย่างชัดเจน

ในที่สุดฉันจะทราบว่าโซลูชันห้าบรรทัดน่าจะดีกว่า 100 บรรทัดเสมอ (สมมติว่าเทียบเท่ากันจริง ๆ )


5
คำตอบที่ดี (+1) "โซลูชัน 5 บรรทัดน่าจะดีกว่า 100 บรรทัดเสมอ": ฉันคิดว่าความกระชับไม่ได้เป็นเพียงข้อได้เปรียบของการเรียกซ้ำ การใช้การเรียกซ้ำจะบังคับให้คุณทำการอ้างอิงการทำงานระหว่างค่าในการทำซ้ำที่แตกต่างกันอย่างชัดเจน
Giorgio

4
วิธีแก้ไขปัญหาที่สั้นกว่ามีแนวโน้มที่จะดีขึ้น แต่ก็มีบางสิ่งที่พูดสั้นเกินไป
dan_waterworth

5
@dan_waterworth เมื่อเทียบกับ "100 เส้น" มันค่อนข้างยากที่จะสุดเหวี่ยงสั้น
ริ้น

4
@Giorgio คุณสามารถทำให้โปรแกรมเล็กลงได้โดยการลบโค้ดที่ไม่จำเป็นออกหรือโดยการทำสิ่งที่ชัดเจนโดยปริยาย ตราบใดที่คุณยึดติดกับอดีตคุณก็จะพัฒนาคุณภาพ
dan_waterworth

1
@jk ฉันคิดว่านั่นเป็นอีกรูปแบบหนึ่งในการทำให้ข้อมูลชัดเจนโดยปริยาย ข้อมูลเกี่ยวกับสิ่งที่ตัวแปรที่ใช้สำหรับจะถูกลบออกจากชื่อของมันที่ชัดเจนและจะถูกผลักเข้าไปในการใช้งานของมันซึ่งเป็นนัย
dan_waterworth

17

ไม่มีการตกลงกันในระดับสากลเกี่ยวกับคำจำกัดความของ "ดีกว่า" เมื่อพูดถึงการเขียนโปรแกรม แต่ฉันจะพูดถึง "ง่ายต่อการดูแล / อ่าน"

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

ดังนั้นจากพลังงานที่มีความหมายต่ำถึงพลังงานที่มีความหมายสูงการวนลูปจะสร้างสแต็กแบบนี้:

  • ฟังก์ชั่นเรียกซ้ำที่ใช้ข้อมูลที่ไม่เปลี่ยนรูปแบบ
  • ฟังก์ชั่นวนซ้ำที่ใช้ข้อมูลที่ไม่เปลี่ยนรูปแบบ
  • ในขณะที่ลูปที่ใช้ข้อมูลที่ไม่แน่นอน
  • ฟังก์ชันเรียกซ้ำแบบหางที่ใช้ข้อมูลที่ไม่แน่นอน
  • ฟังก์ชั่นวนซ้ำที่ใช้ข้อมูลที่ไม่แน่นอน

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


1
"a while loop นั้นเทียบเท่ากับฟังก์ชัน recursive แบบหางและฟังก์ชันแบบเรียกซ้ำไม่จำเป็นต้องเป็นแบบเรียกซ้ำหาง": +1 คุณสามารถจำลองการสอบถามซ้ำโดยใช้ while + loop
Giorgio

1
ฉันไม่แน่ใจว่าฉันเห็นด้วย 100% แต่แน่นอนว่ามันเป็นมุมมองที่น่าสนใจดังนั้น +1 สำหรับสิ่งนั้น
Konrad Rudolph

+1 สำหรับคำตอบที่ยอดเยี่ยมและสำหรับการกล่าวถึงว่าบางภาษา (หรือคอมไพเลอร์) ไม่ใช้การเพิ่มประสิทธิภาพการโทร
Shivan Dragon

@Giorgio "คุณสามารถจำลองการสอบถามซ้ำโดยใช้เวลาสักครู่วนซ้ำ + สแต็ค" นี่คือเหตุผลที่ฉันพูดถึงพลังที่แสดงออก คอมพิวเตอร์มีพลังเท่าเทียมกัน
dan_waterworth

@dan_waterworth: แน่นอนและอย่างที่คุณพูดไว้ในคำตอบการเรียกซ้ำเพียงอย่างเดียวนั้นมีความหมายมากกว่าการวนลูปในขณะที่เนื่องจากคุณจำเป็นต้องเพิ่มสแต็กในขณะที่ลูปเพื่อจำลองการเรียกซ้ำ
Giorgio

7

การเรียกซ้ำบ่อยครั้งก็ชัดเจนน้อยกว่า ชัดเจนน้อยกว่าการบำรุงรักษายาก

หากคุณเขียนfor(i=0;i<ITER_LIMIT;i++){somefunction(i);}ในโฟลว์หลักคุณทำให้ชัดเจนว่าคุณกำลังเขียนลูป ถ้าคุณเขียนsomefunction(ITER_LIMIT);คุณไม่ได้ทำให้ชัดเจนว่าจะเกิดอะไรขึ้น การดูเนื้อหาเท่านั้น: การsomefunction(int x)โทรนั้นsomefunction(x-1)จะบอกคุณว่าในความเป็นจริงเป็นการวนซ้ำโดยใช้การวนซ้ำ นอกจากนี้คุณไม่สามารถวางเงื่อนไขการหลบหนีได้อย่างง่ายดายด้วยbreak;การทำซ้ำครึ่งทางคุณต้องเพิ่มเงื่อนไขที่จะผ่านไปตลอดทางหรือไม่ก็ยกเว้น (และข้อยกเว้นเพิ่มความซับซ้อนอีกครั้ง ... )

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

แน่นอนถ้ามันช่วยให้คุณประหยัด 98 บรรทัดนั่นเป็นเรื่องที่แตกต่างอย่างสิ้นเชิง

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

โดยพื้นฐานแล้วหากsomefunction(x-1)ต้องถูกเรียกจากภายในตัวเองมากกว่าหนึ่งครั้งต่อระดับให้ลืมการทำซ้ำ

... การเขียนฟังก์ชั่นซ้ำ ๆ สำหรับงานที่ทำได้ดีที่สุดโดยการเรียกซ้ำเป็นไปได้ แต่ไม่น่าพอใจ เมื่อใดก็ตามที่คุณต้องการใช้สิ่งที่คุณต้องชอบint stack<int>ฉันทำแบบฝึกหัดมากกว่าครั้งเดียวเพื่อการใช้งานจริง ฉันสามารถรับรองคุณได้เมื่อคุณเผชิญกับงานดังกล่าวคุณจะไม่มีข้อสงสัยเหมือนอย่างที่คุณแสดงออกมา


10
สิ่งที่ชัดเจนและสิ่งที่ไม่ชัดเจนขึ้นอยู่กับบางส่วนที่คุณคุ้นเคย การทำซ้ำถูกใช้บ่อยในภาษาการเขียนโปรแกรมเพราะใกล้เคียงกับวิธีการทำงานของ CPU (เช่นใช้หน่วยความจำน้อยลงและทำงานได้เร็วขึ้น) แต่ถ้าคุณคุ้นเคยกับการคิดแบบเหนี่ยวนำการเรียกซ้ำสามารถทำได้ง่าย
Giorgio

5
"หากพวกเขาเห็นคำสำคัญแบบวนรอบพวกเขารู้ว่ามันเป็นแบบวนรอบ แต่ไม่มีคำหลักแบบเรียกคืนพวกเขาสามารถรับรู้ได้เฉพาะเมื่อเห็น f (x-1) ภายใน f (x) เท่านั้น": เมื่อคุณเรียกใช้ฟังก์ชันแบบเรียกซ้ำ ไม่อยากรู้ว่ามันวนซ้ำ ในทำนองเดียวกันเมื่อคุณเรียกใช้ฟังก์ชันที่มีการวนซ้ำคุณไม่ต้องการรู้ว่ามันมีการวนซ้ำ
Giorgio

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

5
@SF: ดูเหมือนเป็นเหตุผลแบบวงกลมสำหรับฉัน: "ถ้าในสัญชาตญาณของฉันมันเป็นวงแล้วมันเป็นวง AA" mapสามารถกำหนดได้ว่าเป็นฟังก์ชั่นวนซ้ำ (ดูเช่นhaskell.org/tutorial/functions.html ) แม้ว่ามันจะชัดเจนว่าสัญชาตญาณของมันสำรวจรายการและใช้ฟังก์ชันกับสมาชิกแต่ละคนของรายการ
Giorgio

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

6

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

  • รหัสสั้น ๆ ที่สง่างามนั้นโดยทั่วไปจะเหนือกว่ารหัสที่ยาวและซับซ้อน
  • อย่างไรก็ตามจุดสุดท้ายนั้นค่อนข้างใช้งานไม่ได้หากฐานนักพัฒนาของคุณไม่คุ้นเคยกับการเรียกซ้ำและไม่เต็มใจ / ไม่สามารถเรียนรู้ได้ มันอาจกลายเป็นลบเล็กน้อยแทนที่จะเป็นบวก
  • การเรียกซ้ำอาจไม่ดีสำหรับประสิทธิภาพหากคุณต้องการการโทรที่ซ้อนกันอย่างลึกซึ้งในทางปฏิบัติและคุณไม่สามารถใช้การเรียกซ้ำแบบหาง (หรือสภาพแวดล้อมของคุณไม่สามารถปรับการเรียกซ้ำแบบหางได้)
  • การเรียกซ้ำเป็นสิ่งที่ไม่ดีในหลายกรณีหากคุณไม่สามารถแคชผลลัพธ์ระหว่างกลางได้อย่างเหมาะสม ยกตัวอย่างเช่นตัวอย่างทั่วไปของการใช้ recursion ต้นไม้ในการคำนวณตัวเลข Fibonacci ดำเนินการอย่างน่ากลัวไม่ดีถ้าคุณไม่แคช ถ้าคุณทำแคชมันง่ายรวดเร็วหรูหราและยอดเยี่ยมโดยสิ้นเชิง
  • การเรียกซ้ำไม่สามารถใช้ได้กับบางกรณีเช่นเดียวกับการทำซ้ำในผู้อื่นและจำเป็นอย่างยิ่งสำหรับผู้อื่น การดิ้นรนผ่านกฎเกณฑ์ทางธุรกิจที่ยาวเหยียดมักไม่ได้รับการช่วยเหลือจากการสอบถามซ้ำทั้งหมด การวนซ้ำผ่านสตรีมข้อมูลสามารถทำได้อย่างมีประโยชน์ด้วยการเรียกซ้ำ การวนซ้ำข้ามโครงสร้างข้อมูลแบบไดนามิกหลายมิติ (เช่น mazes, ต้นไม้วัตถุ ... ) เป็นไปไม่ได้โดยไม่ต้องเรียกซ้ำ, ชัดเจนหรือโดยปริยาย ทราบว่าในกรณีเหล่านี้เรียกซ้ำอย่างชัดเจนเป็นมากดีกว่านัย - ไม่มีอะไรที่เป็นความเจ็บปวดมากขึ้นกว่าการอ่านรหัสที่ใครสักคนที่ดำเนินการเฉพาะกิจของตัวเองที่ไม่สมบูรณ์กองรถภายในภาษาเพียงเพื่อหลีกเลี่ยงความน่ากลัว R-คำ

การแคชเกี่ยวกับการเรียกซ้ำหมายถึงอะไร
Giorgio

@Giorgio สันนิษฐานว่าอาจเป็นบันทึก
jk

Feh หากสภาพแวดล้อมของคุณไม่ปรับการเรียกหางให้เหมาะสมคุณควรหาสภาพแวดล้อมที่ดีขึ้นและหากนักพัฒนาของคุณไม่คุ้นเคยกับการเรียกซ้ำคุณควรหานักพัฒนาที่ดีกว่า มีมาตรฐานบางคน!
CA McCann

1

การเรียกซ้ำเป็นเรื่องเกี่ยวกับการโทรซ้ำเพื่อใช้งานซ้ำการวนซ้ำเป็นการกระโดดซ้ำเพื่อวางในหน่วยความจำ

ควรพูดถึงเกี่ยวกับสแต็คโอเวอร์โฟลว์ - http://en.wikipedia.org/wiki/Stack_overflow


1
การเรียกซ้ำหมายถึงฟังก์ชันที่คำนิยามหมายถึงการเรียกตนเอง
hardmath

1
ในขณะที่คำจำกัดความง่ายๆของคุณไม่ถูกต้อง 100% คุณเป็นเพียงคนเดียวที่กล่าวถึงสแต็คล้น
Qix

1

มันขึ้นอยู่กับความสะดวกหรือข้อกำหนด:

หากคุณใช้ภาษาโปรแกรมPythonจะรองรับการเรียกซ้ำ แต่โดยค่าเริ่มต้นจะมีข้อ จำกัด สำหรับความลึกของการเรียกซ้ำ (1,000) หากเกินขีด จำกัด เราจะได้รับข้อผิดพลาดหรือข้อยกเว้น ขีด จำกัด นั้นสามารถเปลี่ยนแปลงได้ แต่ถ้าเราทำเช่นนั้นเราอาจประสบกับสถานการณ์ที่ผิดปกติในภาษา

ในเวลานี้ (จำนวนการโทรมากกว่าความลึกการเรียกซ้ำ) เราต้องชอบการสร้างแบบวนซ้ำ ฉันหมายความว่าถ้าขนาดสแต็กไม่เพียงพอเราต้องชอบโครงสร้างลูป


3
นี่คือบล็อกของกุยโดแวนรอสซุมว่าทำไมเขาไม่ต้องการการปรับให้เหมาะสมแบบเรียกซ้ำใน Python (สนับสนุนความคิดที่ว่าภาษาต่าง ๆ ใช้วิธีการทางยุทธวิธีที่แตกต่างกัน)
hardmath

-1

ใช้รูปแบบการออกแบบกลยุทธ์

  • การเรียกซ้ำนั้นสะอาด
  • การวนซ้ำนั้นมีประสิทธิภาพ

ขึ้นอยู่กับโหลดของคุณ (และ / หรือเงื่อนไขอื่น ๆ ) ให้เลือก


5
รออะไร? รูปแบบกลยุทธ์สอดคล้องกับที่นี่ได้อย่างไร และประโยคที่สองดูเหมือนวลีที่ว่างเปล่า
Konrad Rudolph

@ KonradRudolph ฉันจะไปเที่ยวซ้ำ สำหรับชุดข้อมูลที่มีขนาดใหญ่มากฉันจะเปลี่ยนเป็นลูป นั่นคือสิ่งที่ฉันหมายถึง. ฉันขอโทษถ้ามันยังไม่ชัดเจน
Pravin Sonawane

3
อา ฉันยังไม่แน่ใจว่าสิ่งนี้เรียกว่า "รูปแบบการออกแบบกลยุทธ์" ซึ่งมีความหมายที่แน่นอนมากและคุณใช้มันเป็นคำเปรียบเทียบ แต่อย่างน้อยตอนนี้ฉันเห็นว่าคุณกำลังจะไปไหน
Konrad Rudolph

@ KonradRudolph เรียนรู้บทเรียนสำคัญ อธิบายอย่างลึกซึ้งถึงสิ่งที่คุณต้องการจะพูด .. ขอบคุณ .. ที่ช่วย .. :)
Pravin Sonawane

2
@Pravin Sonawane: หากคุณสามารถใช้การเพิ่มประสิทธิภาพแบบเรียกซ้ำแบบหางคุณสามารถใช้การเรียกซ้ำด้วยชุดข้อมูลขนาดใหญ่ได้เช่นกัน
Giorgio
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.