ตัวอย่างการเรียกซ้ำในโลกแห่งความเป็นจริง [ปิด]


98

อะไรคือปัญหาในโลกแห่งความจริงที่วิธีการวนซ้ำเป็นวิธีแก้ปัญหาที่เป็นธรรมชาตินอกเหนือจากการค้นหาในเชิงลึกก่อน (DFS)

(ผมไม่ได้พิจารณาหอคอยฮานอย , จำนวนฟีโบนักชีหรือปัญหาที่เกิดขึ้นจริงในโลกแฟกทอ. พวกเขาเป็นบิต contrived ในใจของฉัน.)


2
ขอบคุณสำหรับคำแนะนำทั้งหมด แต่ทุกคนแนะนำการสำรวจต้นไม้ / เครือข่าย โดยพื้นฐานแล้วนี่คือตัวอย่างทั้งหมดของ Depth-First-Search (หรือ BFS ฉันเดา) ฉันกำลังมองหาอัลกอริทึม / ปัญหาที่มีแรงจูงใจอย่างดีอื่น ๆ
redfood

10
ฉันชอบคำถามนี้! "บอกการใช้เทคนิค X ทั้งหมดยกเว้นการใช้เทคนิค X ในทางปฏิบัติหลัก"
Justin Standard

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

6
เลือกนิยายผจญภัยของคุณเอง! ฉันต้องการอ่านเนื้อหาทั้งหมดและการเรียกซ้ำเป็นวิธีที่ดีที่สุดในการทำเช่นนั้น
Andres

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

คำตอบ:


43

มีตัวอย่างมากมายที่นี่ แต่คุณต้องการตัวอย่างโลกแห่งความเป็นจริงดังนั้นด้วยการคิดสักนิดนี่อาจเป็นสิ่งที่ดีที่สุดที่ฉันสามารถเสนอได้:

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

สิ่งนี้สร้างคลื่นแห่งความหายนะที่ค่อนข้างน่ารำคาญเมื่อประเภท B ติดเชื้อประเภท A จำนวนมาก

งานของคุณคือการติดตาม Bs ทั้งหมดและสร้างภูมิคุ้มกันเพื่อหยุดกระดูกสันหลังของโรค น่าเสียดายที่คุณไม่สามารถให้การรักษาทั่วประเทศกับทุกคนได้เพราะคนที่เป็นประเภท A ก็แพ้ยาที่เหมาะกับประเภท B

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

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

ทำซ้ำจนกว่าคิวผู้ติดเชื้อจะกลายเป็น 0 แล้วรอการระบาดอีก ..

(ตกลงนี่เป็นการทำซ้ำเล็กน้อย แต่เป็นวิธีการแก้ปัญหาซ้ำซากในกรณีนี้การข้ามผ่านฐานประชากรครั้งแรกอย่างกว้าง ๆ ที่พยายามค้นหาเส้นทางที่เป็นไปได้ของปัญหาและนอกจากนี้การแก้ปัญหาแบบวนซ้ำมักจะเร็วกว่าและมีประสิทธิภาพมากกว่า และฉันบังคับให้ลบการเรียกซ้ำทุกที่จนกลายเป็นสัญชาตญาณ .... ไอ้บ้า!)


2
ขอบคุณ - นี่ยังคงเป็นการส่งผ่านกราฟ แต่เป็นแรงจูงใจที่ดีและสมเหตุสมผลสำหรับผู้ที่ไม่ใช่โปรแกรมเมอร์
redfood

ฉันเชื่อว่าการค้นหาผู้ป่วย 0 จะเป็นตัวอย่างที่ดีกว่า พิจารณาปฏิกิริยาทั้งหมดที่อาจทำให้เกิดการติดเชื้อ ทำซ้ำกับทุกคนที่เกี่ยวข้องซึ่งเป็นโรคติดต่อในขณะที่มีปฏิสัมพันธ์จนกว่าจะไม่พบโรคติดต่อ
William FitzPatrick

7
ตัวอย่างในโลกแห่งความจริงนี้รู้สึกคุ้นเคยมากในตอนนี้ :(
haroldolivieri

110

ตัวอย่างการเกิดซ้ำในโลกแห่งความเป็นจริง

ดอกทานตะวัน


13
เขียนซ้ำโดยสถาปนิก Matrix :)
Marcel

3
การวนซ้ำนี้เป็นอย่างไร? รับรองว่าสวยแน่นอน แต่เรียกซ้ำ? กะหล่ำปลีเศษส่วนน่าจะใช้งานได้ดี แต่ฉันไม่เห็นความคล้ายคลึงกันในตัวเองในดอกไม้นี้
Clément

1
มันเป็นเรื่องเล็กน้อยที่แก้ม แต่เป็นตัวอย่างของ phyllotaxis ซึ่งสามารถอธิบายได้ด้วยลำดับ Fibonacci ซึ่งโดยทั่วไปจะใช้ผ่านการเรียกซ้ำ
Hans Sjunnesson

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

65

เกี่ยวกับสิ่งที่เกี่ยวข้องกับโครงสร้างไดเร็กทอรีในระบบไฟล์ การค้นหาไฟล์ซ้ำ ๆ การลบไฟล์การสร้างไดเร็กทอรี ฯลฯ

นี่คือการใช้งาน Java ที่พิมพ์ซ้ำเนื้อหาของไดเร็กทอรีและไดเร็กทอรีย่อย

import java.io.File;

public class DirectoryContentAnalyserOne implements DirectoryContentAnalyser {

    private static StringBuilder indentation = new StringBuilder();

    public static void main (String args [] ){
        // Here you pass the path to the directory to be scanned
        getDirectoryContent("C:\\DirOne\\DirTwo\\AndSoOn");
    }

    private static void getDirectoryContent(String filePath) {

        File currentDirOrFile = new File(filePath);

        if ( !currentDirOrFile.exists() ){
            return;
        }
        else if ( currentDirOrFile.isFile() ){
            System.out.println(indentation + currentDirOrFile.getName());
            return;
        }
        else{
            System.out.println("\n" + indentation + "|_" +currentDirOrFile.getName());
            indentation.append("   ");

            for ( String currentFileOrDirName : currentDirOrFile.list()){
                getPrivateDirectoryContent(currentDirOrFile + "\\" + currentFileOrDirName);
            }

            if (indentation.length() - 3 > 3 ){
                indentation.delete(indentation.length() - 3, indentation.length());
            }
        }       
    }

}

2
ระบบไฟล์ให้แรงจูงใจ (ซึ่งดีขอบคุณ) แต่นี่เป็นตัวอย่างเฉพาะของ DFS
redfood

4
ฉันไม่ได้รับตัวย่อ "DFS" - ไม่นานมานี้ฉันนั่งอยู่ในห้องเรียน
Matt Dillard

5
การค้นหาในเชิงลึกก่อน: dfs (โหนด) {foreach child ในโหนด {visit (child); }}
Haoest

ตัวอย่างโค้ดง่ายๆดูเช่นstackoverflow.com/questions/126756/…
Jonik

มีข้อผิดพลาดในรหัสนี้หรือไม่? ไม่ควร getPrivateDirectoryContent () ถูกแทนที่ด้วย getDirectoryContent ()?
Shn_Android_Dev


16

ตัวอย่างของ Matt Dillard เป็นสิ่งที่ดี โดยทั่วไปแล้วการเดินของต้นไม้โดยทั่วไปสามารถจัดการได้โดยการเรียกซ้ำได้อย่างง่ายดาย ตัวอย่างเช่นการรวบรวมต้นไม้แยกวิเคราะห์การเดินผ่าน XML หรือ HTML เป็นต้น


ฉันพบว่า "การรวบรวมต้นไม้แยกวิเคราะห์" เป็นคำตอบที่เหมาะสมซึ่งเกี่ยวข้องกับต้นไม้ แต่ก็ยังไม่ใช่ปัญหาในการค้นหาตามที่ผู้ถามต้องการ อาจกล่าวได้ทั่วไปถึงแนวคิดทั่วไปเกี่ยวกับการรวบรวมหรือการตีความภาษา นอกจากนี้ยังอาจเป็นการ "ตีความ" (ความเข้าใจการฟัง) ภาษาที่เป็นธรรมชาติตัวอย่างเช่นภาษาอังกฤษ
imz - Ivan Zakharyaschev

16

recursion มักจะใช้ในการใช้งานของอัลกอริทึมย้อนรอย สำหรับแอปพลิเคชั่น "โลกแห่งความเป็นจริง" แล้วนักแก้ซูโดกุล่ะ?


อาร์เรย์สถานะและค่าต่ำสามารถเร่งความเร็วได้
BCS

13

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

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


11

แน่นอนว่าคอมไพเลอร์จำนวนมากใช้การเรียกซ้ำอย่างหนัก ภาษาคอมพิวเตอร์เป็นภาษาที่เรียกซ้ำโดยเนื้อแท้ (กล่าวคือคุณสามารถฝังคำสั่ง 'if' ไว้ในคำสั่ง 'if' อื่น ๆ ได้)


ฝังตัวหากคำสั่งไม่ถูกเรียกซ้ำ
John Meagher

แต่การแยกวิเคราะห์จำเป็นต้องมีการเรียกซ้ำจอห์น
Apocalisp

2
จอห์นความจริงที่ว่าคุณสามารถซ้อนคำสั่งได้ว่าคำจำกัดความของภาษา (และน่าจะเป็นตัวแยกวิเคราะห์ภาษา) เป็นแบบวนซ้ำ
Derek Park

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

คำตอบของ Cody Brocious ที่กล่าวถึง "compiling parse trees" ยังชี้ไปที่ประเด็นนี้ด้วย: การวิเคราะห์ภาษา / การตีความ / การเรียบเรียง
imz - Ivan Zakharyaschev

9

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

public static void SetReadOnly(Control ctrl, bool readOnly)
{
    //set the control read only
    SetControlReadOnly(ctrl, readOnly);

    if (ctrl.Controls != null && ctrl.Controls.Count > 0)
    {
        //recursively loop through all child controls
        foreach (Control c in ctrl.Controls)
            SetReadOnly(c, readOnly);
    }
}

8

มีชื่อเสียง Eval / สมัครรอบจาก SICP

ข้อความแสดงแทน
(ที่มา: mit.edu )

นี่คือคำจำกัดความของ eval:

(define (eval exp env)
  (cond ((self-evaluating? exp) exp)
        ((variable? exp) (lookup-variable-value exp env))
        ((quoted? exp) (text-of-quotation exp))
        ((assignment? exp) (eval-assignment exp env))
        ((definition? exp) (eval-definition exp env))
        ((if? exp) (eval-if exp env))
        ((lambda? exp)
         (make-procedure (lambda-parameters exp)
                         (lambda-body exp)
                         env))
        ((begin? exp) 
         (eval-sequence (begin-actions exp) env))
        ((cond? exp) (eval (cond->if exp) env))
        ((application? exp)
         (apply (eval (operator exp) env)
                (list-of-values (operands exp) env)))
        (else
         (error "Unknown expression type - EVAL" exp))))

นี่คือคำจำกัดความของการใช้:

(define (apply procedure arguments)
  (cond ((primitive-procedure? procedure)
         (apply-primitive-procedure procedure arguments))
        ((compound-procedure? procedure)
         (eval-sequence
           (procedure-body procedure)
           (extend-environment
             (procedure-parameters procedure)
             arguments
             (procedure-environment procedure))))
        (else
         (error
          "Unknown procedure type - APPLY" procedure))))

นี่คือคำจำกัดความของลำดับการประเมิน:

(define (eval-sequence exps env)
  (cond ((last-exp? exps) (eval (first-exp exps) env))
        (else (eval (first-exp exps) env)
              (eval-sequence (rest-exps exps) env))))

eval-> apply-> eval-sequence->eval


7

การเรียกซ้ำใช้ในสิ่งต่างๆเช่นต้นไม้ BSP สำหรับการตรวจจับการชนกันในการพัฒนาเกม (และพื้นที่อื่น ๆ ที่คล้ายคลึงกัน)


7

ผู้คนมักจะจัดเรียงเอกสารหลายชุดโดยใช้วิธีเรียกซ้ำ ตัวอย่างเช่นสมมติว่าคุณกำลังจัดเรียงเอกสาร 100 ฉบับโดยมีชื่อกำกับอยู่ วางเอกสารลงในกองตามตัวอักษรตัวแรกจากนั้นเรียงแต่ละกอง

การค้นหาคำในพจนานุกรมมักดำเนินการโดยใช้เทคนิคการค้นหาแบบไบนารีซึ่งเป็นแบบวนซ้ำ

ในองค์กรหัวหน้ามักจะให้คำสั่งกับหัวหน้าแผนกซึ่งจะให้คำสั่งแก่ผู้จัดการและอื่น ๆ


5

ความต้องการในโลกแห่งความจริงที่ฉันได้รับเมื่อเร็ว ๆ นี้:

ข้อกำหนด A: ใช้คุณลักษณะนี้หลังจากทำความเข้าใจข้อกำหนด A อย่างถี่ถ้วนแล้ว


4

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


4

การเรียกซ้ำจะใช้กับปัญหา (สถานการณ์) ซึ่งคุณสามารถแยกมันออก (ลด) เป็นส่วนย่อย ๆ และแต่ละส่วนจะมีลักษณะคล้ายกับปัญหาเดิม

ตัวอย่างที่ดีว่าสิ่งที่มีส่วนเล็ก ๆ คล้ายกับตัวมันเองอยู่ที่ใด:

  • โครงสร้างต้นไม้ (กิ่งก้านก็เหมือนต้นไม้)
  • รายการ (ส่วนหนึ่งของรายการยังคงเป็นรายการ)
  • ตู้คอนเทนเนอร์ (ตุ๊กตารัสเซีย)
  • ลำดับ (ส่วนหนึ่งของลำดับดูเหมือนถัดไป)
  • กลุ่มของวัตถุ (กลุ่มย่อยคือกลุ่มของวัตถุ)

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

อัลกอริธึมการเรียงลำดับแบบวนซ้ำอัลกอริทึมการเดินบนต้นไม้แผนที่ / อัลกอริธึมการลดขั้นตอนการแบ่งและพิชิตเป็นตัวอย่างทั้งหมดของเทคนิคนี้

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

  • แบ่งปัญหาออกเป็นชิ้นเล็ก ๆ ==> เรียกตัวเองจากชุดย่อยที่เล็กกว่าของข้อมูลดั้งเดิม)
  • ติดตามการแบ่งชิ้นส่วน ==> call stack,
  • เย็บผลลัพธ์กลับ ==> ผลตอบแทนตามสแต็ก


4

ตัวอย่างที่ดีของการเรียกซ้ำพบได้ในภาษาโปรแกรมที่ใช้งานได้ ในภาษาโปรแกรมที่ใช้งานได้ ( Erlang , Haskell , ML / OCaml / F #เป็นต้น) เป็นเรื่องปกติมากที่จะมีการเรียกใช้การประมวลผลรายการซ้ำ

เมื่อจัดการกับรายการในภาษาสไตล์ OOP ที่จำเป็นโดยทั่วไปมักจะเห็นรายการที่ใช้เป็นรายการที่เชื่อมโยงกัน ([item1 -> item2 -> item3 -> item4]) อย่างไรก็ตามในภาษาการเขียนโปรแกรมที่ใช้งานได้บางภาษาคุณจะพบว่ามีการนำรายการนั้นมาใช้ซ้ำโดยที่ "ส่วนหัว" ของรายการจะชี้ไปที่รายการแรกในรายการและ "หาง" จะชี้ไปยังรายการที่มีรายการที่เหลืออยู่ ( [item1 -> [item2 -> [item3 -> [item4 -> []]]]]) มันค่อนข้างสร้างสรรค์ในความคิดของฉัน

การจัดการรายการนี้เมื่อรวมกับการจับคู่รูปแบบจะมีประสิทธิภาพมาก สมมติว่าฉันต้องการรวมรายการตัวเลข:

let rec Sum numbers =
    match numbers with
    | [] -> 0
    | head::tail -> head + Sum tail

โดยพื้นฐานแล้วจะบอกว่า "ถ้าเราถูกเรียกด้วยรายการว่างให้ส่งกลับ 0" (อนุญาตให้เราแบ่งการเรียกซ้ำ) มิฉะนั้นจะคืนค่าของส่วนหัว + ค่าของ Sum ที่เรียกพร้อมกับรายการที่เหลือ (ดังนั้นการเรียกซ้ำของเรา)

ตัวอย่างเช่นฉันอาจมีรายการไฟล์ URLฉันคิดว่าแยก URL ทั้งหมดที่แต่ละ URL เชื่อมโยงไปจากนั้นฉันจะลดจำนวนลิงก์ทั้งหมดที่ไปยัง / จาก URL ทั้งหมดเพื่อสร้าง "ค่า" สำหรับเพจ (แนวทางที่ Google ใช้กับPageRankและคุณสามารถค้นหาได้กำหนดไว้ในกระดาษMapReduceดั้งเดิม) คุณสามารถทำได้เพื่อสร้างจำนวนคำในเอกสารด้วย และอื่น ๆ อีกมากมายเช่นกัน

คุณสามารถขยายรูปแบบการทำงานนี้เป็นรหัสMapReduceประเภทใดก็ได้ที่คุณสามารถจดรายการบางสิ่งบางอย่างเปลี่ยนรูปแบบและส่งคืนสิ่งอื่น (ไม่ว่าจะเป็นรายการอื่นหรือคำสั่ง zip ในรายการ)


3

XML หรือข้ามผ่านอะไรก็ได้ที่เป็นต้นไม้ แม้ว่าตามจริงแล้วฉันไม่เคยใช้การเรียกซ้ำในงานของฉันเลย


ไม่แม้แต่หางซ้ำ?
Apocalisp

ฉันใช้การเรียกซ้ำครั้งเดียวในอาชีพของฉันและเมื่อกรอบการทำงานเปลี่ยนไปฉันก็กำจัดมัน 80% ของสิ่งที่เราทำคือ CRUD
Charles Graham

1
การกล่าวถึง "XML" ในตอนแรกนั้นค่อนข้างแปลก ไม่ใช่เรื่องธรรมดาไม่ใช่สิ่งที่คนทั่วไปที่คุณจะสอนต้องรับมือในชีวิตประจำวัน แต่ความคิดนี้ค่อนข้างสมเหตุสมผล
imz - Ivan Zakharyaschev

3

คำติชมจะวนซ้ำในองค์กรตามลำดับชั้น

หัวหน้าระดับสูงบอกให้ผู้บริหารระดับสูงรวบรวมความคิดเห็นจากทุกคนใน บริษัท

ผู้บริหารแต่ละคนรวบรวมรายงานโดยตรงของตนและบอกให้รวบรวมข้อเสนอแนะจากรายงานโดยตรงของตน

และลงเส้น

ผู้ที่ไม่มีรายงานโดยตรง - โหนดใบไม้ในต้นไม้ - ให้ข้อเสนอแนะ

ข้อเสนอแนะจะเดินทางกลับไปที่ต้นไม้โดยผู้จัดการแต่ละคนจะเพิ่มข้อเสนอแนะของตนเอง

ในที่สุดคำติชมทั้งหมดก็กลับไปที่หัวหน้าระดับสูง

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


2

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

สมมติว่า {ผู้ใช้ | ลูกค้า | ลูกค้า | เจ้านาย} ของคุณร้องขอให้คุณวางเส้นทางเบรดครัมบ์ในทุกหน้าเพื่อแสดงตำแหน่งที่คุณอยู่ในแผนภูมิ

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

แน่นอนว่าคุณกดปุ่ม db หลายครั้งต่อหน้าในตัวอย่างนั้นดังนั้นคุณอาจต้องการใช้นามแฝง SQL ที่คุณค้นหา page-table เป็น a และ page-table อีกครั้งเป็น b และเข้าร่วม a.id ด้วย b.parent เพื่อให้คุณสร้างฐานข้อมูลทำการรวมแบบเรียกซ้ำ เป็นเวลานานแล้วดังนั้นไวยากรณ์ของฉันอาจไม่เป็นประโยชน์

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

อย่างไรก็ตามนั่นคือ $ .02 ของฉัน


2

คุณมีโครงสร้างองค์กรที่ลึก N ระดับ มีการตรวจสอบโหนดหลายโหนดและคุณต้องการขยายเฉพาะโหนดที่ได้รับการตรวจสอบ

นี่คือสิ่งที่ฉันเขียนโค้ดจริงๆ ดีและง่ายด้วยการเรียกซ้ำ


2

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

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



2
  • การแยกวิเคราะห์ไฟล์XML
  • การค้นหาที่มีประสิทธิภาพในพื้นที่หลายมิติ เช่น. ต้นไม้รูปสี่เหลี่ยมในแบบ 2 มิติ, ต้นไม้แปดเหลี่ยมใน 3 มิติ, ต้นไม้ kd เป็นต้น
  • การจัดกลุ่มตามลำดับชั้น
  • ลองคิดดูการสำรวจโครงสร้างแบบลำดับชั้นใด ๆ โดยธรรมชาติจะยืมตัวเองไปสู่การวนซ้ำ
  • การเขียนโปรแกรมเทมเพลตใน C ++ โดยที่ไม่มีการวนซ้ำและการเรียกซ้ำเป็นวิธีเดียว

"XML" ไม่จำเป็นสำหรับแนวคิดของคำตอบนี้ (และการกล่าวถึง XML โดยเฉพาะอาจทำให้คนที่คุณกำลังสอนน่าขยะแขยง / น่าเบื่อ) เพียงแค่ภาษาทั่วไป (ภาษาคอมพิวเตอร์หรือภาษาธรรมชาติ) จะเป็นตัวอย่างสำหรับปัญหาการแยกวิเคราะห์ซ้ำ
imz - Ivan Zakharyaschev

ผู้โพสต์ถามถึง "ปัญหาในโลกแห่งความเป็นจริงที่วิธีการวนซ้ำเป็นวิธีแก้ปัญหาตามธรรมชาติ" การแยกวิเคราะห์ไฟล์ xml นั้นเป็นปัญหาในโลกแห่งความเป็นจริงอย่างแน่นอนและจะทำให้เกิดการเรียกซ้ำตามธรรมชาติ ความจริงที่ว่าคุณดูเหมือนจะเกลียด XML แปลก ๆ ไม่ได้เปลี่ยนความจริงที่ว่ามันถูกใช้กันอย่างแพร่หลาย
Dima


2

ตัวอย่างที่ดีที่สุดที่ฉันรู้คือQuicksortมันง่ายกว่ามากด้วยการเรียกซ้ำ ดูที่:

shop.oreilly.com/product/9780596510046.do

www.amazon.com/Beautiful-Code-Leading-Programmers-Practice/dp/0596510047

(คลิกที่คำบรรยายแรกใต้บทที่ 3: "รหัสที่สวยที่สุดที่ฉันเคยเขียน")


1
และ MergeSort ก็ง่ายกว่าด้วยการเรียกซ้ำ
Matthew Schinckel

1
ลิงค์เสีย เพิ่มชื่อหนังสือได้ไหม
Peter Mortensen

@PeterMortensen หนังสือเล่มนี้คือ Beautiful Code โดย Greg Wilson และ Andy Oram ฉันอัปเดตลิงก์แม้ว่า O'Reilly จะไม่อนุญาตให้มองเข้าไปข้างในอีกต่อไป แต่คุณสามารถดูที่ Amazon
Fabio Ceconello

1

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

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


1

การให้เหตุผลโดยอุปนัยกระบวนการของการสร้างแนวคิดนั้นเกิดขึ้นซ้ำซากในธรรมชาติ สมองของคุณทำงานตลอดเวลาในโลกแห่งความเป็นจริง


1

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


1

การคูณจำนวนธรรมชาติเป็นตัวอย่างของการเกิดซ้ำในโลกแห่งความเป็นจริง:

To multiply x by y
  if x is 0
    the answer is 0
  if x is 1
    the answer is y
  otherwise
    multiply x - 1 by y, and add x
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.