ฉันจะเขียนฟังก์ชันลูปเป็นฟังก์ชันแบบเรียกซ้ำได้อย่างไร

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

int longestSequence(int n)
{
    int u = n;

    if(u == 1)
    {
        return 1;
    }
    else 
    {
        return max(hailstoneLength(u), longestSequence(u-1));
    }
}

ส่วนที่ฉันมีปัญหาคือลำดับการเริ่มต้นที่ยาวที่สุดของฉัน:

int hailLongestSeq(int n)
{
    int k;
    int longest = 0;
    for(int j = 1; j <= n; j++)
    {
        if(hailstoneLength(j) > longest)
        {
            longest = hailstoneLength(j);
            k = j;
        }
    }
    return k;   
}

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

ผลลัพธ์ที่คาดหวังจะเป็นดังนี้:

ลำดับลูกเห็บที่ยาวที่สุดที่เริ่มต้นด้วยตัวเลขไม่เกิน 10 จะมีความยาว 20 ลำดับลูกเห็บที่ยาวที่สุดที่เริ่มต้นด้วยตัวเลขไม่เกิน 10 จะเริ่มต้นด้วย 9

เนื่องจากลำดับของ 9 มีความยาว 20 หมายเลข และยาวที่สุดตั้งแต่ 1 ถึง 10


person Zabe    schedule 23.09.2016    source แหล่งที่มา
comment
เมื่อวานไม่ได้ถามเหรอ?   -  person Ami Tavory    schedule 23.09.2016
comment
สูตรจะกล่าวถึงปัญหาใหม่ในแง่ของปัญหาย่อย: ตัวอย่าง: a for loop of n iterations เป็นการวนซ้ำบน for for loop ของการวนซ้ำ n-1   -  person perreal    schedule 23.09.2016
comment
ไม่ เมื่อวานฉันไม่ได้ถามเรื่องนี้ ฉันส่งสิ่งนี้ตอนตี 1 ของวันนี้   -  person Zabe    schedule 23.09.2016


คำตอบ (2)


ใช่ ทุก for for loop สามารถแปลเป็นการเรียกซ้ำได้ ชัดเจนเช่นนี้:

for (i=0; i<N; i++) {
  body;
}

แปลเป็น:

func(int i) {
  if (i<N) { body; func(i+1) }
  else return;
}

func(0);

สิ่งนี้สามารถขยายไปยังการคำนวณลูปใดๆ ได้อย่างง่ายดาย (เพิ่มพารามิเตอร์หากจำเป็น ส่งคืนค่า ฯลฯ)

person Jean-Baptiste Yunès    schedule 23.09.2016
comment
ว้าว. ขอบคุณ! ฉันยังคงเรียน C++ ฉันควรจะบันทึกสิ่งนี้ไว้เผื่อฉันต้องการมันอีกครั้ง - person Zabe; 23.09.2016
comment
เมื่อฉันทำสิ่งนี้ ฉันได้รับข้อผิดพลาดในการแบ่งส่วน ฉันจะแก้ไขได้อย่างไร? หรือฉันทำผิดอะไรหรือเปล่า? - person Zabe; 23.09.2016

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

int hailLongestSeq(int n, int j, int k, int longest)
{
    if(j <= n)
    {
        if(hailstoneLength(j) > longest)
        {
            longest = hailstoneLength(j);
            k = j;
        }
        k = hailLongestSeq(n, ++j, k, longest);
    }
    return k;   
}

ซึ่งอาจต้องมีการแก้ไข แต่ตรรกะยังคงเหมือนเดิม ให้ส่งตัวแปรเป็นพารามิเตอร์เพื่อรักษาค่าไว้

person Rishabh Kumar    schedule 23.09.2016
comment
เช่นเดียวกับสิ่งนี้ ฉันได้รับข้อผิดพลาดในการแบ่งส่วน - person Zabe; 23.09.2016
comment
ขออภัยฉันเพิ่ม j++ โดยไม่ตั้งใจแทน ++j ซึ่งส่งผลให้เกิดการวนซ้ำไม่สิ้นสุด ตอนนี้ฉันได้แก้ไขรหัสแล้ว คุณสามารถตรวจสอบอีกครั้งและยืนยันว่ามันใช้ได้ผลสำหรับคุณหรือไม่ - person Rishabh Kumar; 23.09.2016
comment
โอ้ใช่ มันใช้งานได้ Rishabh ขอบคุณ ขอบคุณ และถ้ามันไม่เป็นไร ฉันขอคำอธิบายเกี่ยวกับวิธีการทำงานได้ไหม ฉันกำลังทำงานกับการจำลองมือให้มากขึ้น - person Zabe; 24.09.2016
comment
จริงๆ แล้ว ฉันเพิ่งแปลงลอจิกลูปของคุณเป็นการเรียกซ้ำ สิ่งแรกที่ต้องแปลงลูปคือการสร้างเงื่อนไขตามเงื่อนไขลูปของคุณ หากตรงตามเงื่อนไข ให้เรียกใช้ฟังก์ชันอีกครั้ง มิฉะนั้นจะส่งคืนเอาต์พุต ตรวจสอบให้แน่ใจว่าตัวแปรท้องถิ่นทั้งหมดที่ใช้ในฟังก์ชันถูกส่งเป็นพารามิเตอร์ในขณะที่ทำการเรียกซ้ำ สำหรับงานที่ซับซ้อน ฉันมักจะพบว่าการเขียนลูปก่อนแล้วจึงแปลงเป็นฟังก์ชันแบบเรียกซ้ำจะดีกว่า ฝึกซ้อมต่อไป โปรดโหวตหากคุณเข้าใจประเด็น - person Rishabh Kumar; 24.09.2016
comment
ฉันเข้าใจดีว่าตอนนี้ แต่ขอโทษด้วย ฉันไม่สามารถโหวตได้เนื่องจากฉันไม่มีตัวแทน 15 คน แต่ฉันสังเกตว่ามีการอธิบายไว้ข้างต้นด้วย เมื่อฉันเดินตามทางของพวกเขา ผลลัพธ์ก็เหมือนเดิม ขอบคุณอีกครั้ง. - person Zabe; 24.09.2016