একটি পুনরাবৃত্তি ফাংশন পুনরাবৃত্তি / লুপ থাকতে পারে?


12

আমি পুনরাবৃত্ত ফাংশন সম্পর্কে অধ্যয়ন করছি এবং স্পষ্টতই, তারা নিজেরাই কল করে এমন ফাংশন এবং পুনরাবৃত্তি / লুপগুলি ব্যবহার করে না (অন্যথায় এটি পুনরাবৃত্ত ফাংশন হবে না)।

যাইহোক, উদাহরণগুলির জন্য ওয়েবে সার্ফ করার সময় (8-কুইন্স-পুনরাবৃত্তি সমস্যা), আমি এই ফাংশনটি পেয়েছি:

private boolean placeQueen(int rows, int queens, int n) {
    boolean result = false;
    if (row < n) {
        while ((queens[row] < n - 1) && !result) {
            queens[row]++;
            if (verify(row,queens,n)) {
                ok = placeQueen(row + 1,queens,n);
            }
        }
        if (!result) {
            queens[row] = -1;
        }
    }else{
        result = true;
    }
    return result;
}

whileজড়িত একটি লুপ আছে ।

... সুতরাং আমি এখন কিছুটা হারিয়েছি। আমি লুপগুলি ব্যবহার করতে পারি না?


5
এটি সংকলন করে না। হ্যাঁ. তাহলে কেন জিজ্ঞাসা করবেন?
টমাস এডিং

6
সমগ্র পুনরাবৃত্তির সংজ্ঞা এক পর্যায়ে ফাংশন হতে পারে যে তার নিজস্ব সঞ্চালনের অংশ হিসেবে পুনরায় তথাকথিত আগেই ফেরৎ আছে (কিনা এটা পুনরায় তথাকথিত নিজে অথবা অন্য কোনো ফাংশন এটা কল দ্বারা)। এই সংজ্ঞাটি সম্পর্কে কিছুই লুপিংয়ের সম্ভাবনা বাদ দেয় না।
সিএইচও

সিএইচওর মন্তব্যে সংযোজন হিসাবে, পুনরাবৃত্ত ফাংশনটি নিজের একটি সহজ সংস্করণে পুনরায় কল করা হবে (অন্যথায়, এটি চিরতরে লুপ হয়ে যাবে)। অরব্লিংয়ের উদ্ধৃতি দিতে ( ইন প্লেইন ইংরাজী থেকে, পুনরাবৃত্তি কী? ): "রিকার্সিভ প্রোগ্রামিং হ'ল ক্রমবর্ধমানভাবে একটি সমস্যা হ্রাস করার প্রক্রিয়া যা নিজের সংস্করণগুলি সমাধান করতে সহজতর হয়" " এই ক্ষেত্রে, এরতমতমতম সংস্করণ placeQueenহ'ল "8 ম রানী রাখুন" এবং এর সহজ সংস্করণ placeQueenহ'ল "স্থান 7 রানী" (তারপরে 6 রাখুন ইত্যাদি)
ব্রায়ান

ওমেগা কাজ করে এমন কোনও কিছু আপনি ব্যবহার করতে পারেন। খুব কমই সফ্টওয়্যার স্পেসিফিকেশন নির্দিষ্ট করে যে কোন স্কুলে প্রোগ্রামিং ব্যবহার করতে হবে - আপনি স্কুলে না থাকেন এবং আপনার অ্যাসাইনমেন্টটি তাই বলে।
অপুরভ খুরসিয়া

@ থমাসডিং: হ্যাঁ, অবশ্যই এটি সংকলন এবং কাজ করে। তবে আমি এই মুহুর্তে কেবল ইঞ্জিনিয়ারিং অধ্যয়ন করছি - এই মুহুর্তে আমার জন্য কী গুরুত্বপূর্ণ, তা হ'ল আজকাল প্রোগ্রামাররা যেভাবে নিয়োগ করে তা নয় strict তাই আমি জিজ্ঞাসা করছি আমার ধারণার সঠিক কিনা (যা তা নয়, তা মনে হয়)।
ওমেগা

উত্তর:


41

আপনি পুনরাবৃত্তি ভুল বুঝেছিলেন: যদিও এটি পুনরাবৃত্তি প্রতিস্থাপন করতে ব্যবহার করা যেতে পারে, পুনরাবৃত্ত ফাংশনটির নিজের মধ্যে পুনরাবৃত্তি অভ্যন্তরীণ না হওয়ার কোনও প্রয়োজন নেই।

কোন ক্রিয়াকে পুনরাবৃত্ত হিসাবে বিবেচনা করার জন্য একমাত্র প্রয়োজনীয়তা হ'ল একটি কোড পাথের অস্তিত্ব যা সে নিজেকে, প্রত্যক্ষ বা পরোক্ষভাবে কল করে। সমস্ত সঠিক রিকার্সিভ ফাংশনগুলির কোনও শর্তযুক্ত শর্ত থাকে যা এগুলি চিরতরে "পুনরাবৃত্তি" হতে বাধা দেয়।

আপনার পুনরাবৃত্ত ফাংশন ব্যাকট্র্যাকিংয়ের সাথে পুনরাবৃত্ত অনুসন্ধানের কাঠামো চিত্রিত করার জন্য আদর্শ। এটি প্রস্থান শর্তের চেক দিয়ে শুরু row < nহয় এবং পুনরাবৃত্তির পর্যায়ে অনুসন্ধানের সিদ্ধান্ত নিতে এগিয়ে যায় (অর্থাত রাণী সংখ্যার জন্য সম্ভাব্য অবস্থান বাছাই করা row)। প্রতিটি পুনরাবৃত্তির পরে, ফাংশনটি এখনও পর্যন্ত খুঁজে পাওয়া কনফিগারেশনটি তৈরি করার জন্য একটি পুনরাবৃত্তি কল করা হয়; অবশেষে, এটি "বোতল আউট" যখন পুনরাবৃত্ত কলগুলিতে rowপৌঁছে nযায় যা nস্তরগুলি গভীর।


1
"সঠিক" রিকার্সিভ ফাংশনগুলির জন্য +1 এর শর্তসাপেক্ষ রয়েছে, প্রচুর পরিমাণে ভুল রয়েছে যা হি করে না
জিমি হোফা ২

6
+1 চিরতরে "পুনরাবৃত্তি" `টার্টল () {টার্টেল ();}
মিঃমিন্দর

1
@ মিঃ মাইন্ডর আমি "এটি সমস্ত ভাবেই কচ্ছপ রয়েছে" উদ্ধৃতিটি
ভালবাসি

এটি আমাকে
হাসিয়ে দিয়েছে

2
"সমস্ত সঠিক রিকার্সিভ ফাংশনগুলিরও কিছু শর্তযুক্ত শর্তসাপেক্ষ থাকে, এগুলি চিরতরে" পুনরাবৃত্তি "থেকে বাধা দেয়" " অ-কঠোর মূল্যায়নের সাথে সত্য নয়।
পাব্বি

12

পুনরাবৃত্তির ক্রিয়াকলাপের সাধারণ কাঠামো এরকম কিছু:

myRecursiveFunction(inputValue)
begin
   if evaluateBaseCaseCondition(inputValue)=true then
       return baseCaseValue;
   else
       /*
       Recursive processing
       */
       recursiveResult = myRecursiveFunction(nextRecursiveValue); //nextRecursiveValue could be as simple as inputValue-1
       return recursiveResult;
   end if
end

আমি যে পাঠ্যটিকে চিহ্নিত করেছি /*recursive processing*/তা কোনও কিছুই হতে পারে। এটি একটি লুপ অন্তর্ভুক্ত করতে পারে, যদি সমস্যার সমাধানের সমস্যাটির প্রয়োজন হয় এবং এটি পুনরাবৃত্ত কলগুলিও অন্তর্ভুক্ত করতে পারে myRecursiveFunction


1
এটি বিভ্রান্তিমূলক, কারণ এর থেকে বোঝা যায় যে কেবলমাত্র একটি পুনরাবৃত্তি কল রয়েছে এবং এটি অনেকগুলি কেস বাদ দেয় যেখানে পুনরাবৃত্ত কলটি নিজেই একটি লুপের মধ্যে থাকে (যেমন বি-ট্রি ট্রভারসাল)।
পিটার টেলর

@ পিটারটেলর: হ্যাঁ, আমি এটিকে সহজ রাখার চেষ্টা করছিলাম।
হতাশ

এমনকি কোনও লুপ ছাড়াই একাধিক কল, যেমন একটি সরল বাইনারি গাছের সন্ধানের মতো, যেখানে প্রতিটি নোডের 2 টি বাচ্চা হওয়ার কারণে আপনার 2 টি কল থাকে।
ইজকাটা

6

আপনি অবশ্যই একটি পুনরাবৃত্তি ফাংশনে লুপগুলি ব্যবহার করতে পারেন। কোন ফাংশনকে পুনরাবৃত্তকারী করে তোলে কেবল এটি হ'ল ফাংশনটি সম্পাদনের পথে কোনও সময়ে নিজেকে কল করে। তবে আপনার অসীম পুনরাবৃত্তি কলগুলি রোধ করার জন্য আপনার কিছু শর্ত থাকা উচিত যা থেকে আপনার ফাংশনটি ফিরে আসতে পারে না।


1

পুনরাবৃত্ত কল এবং লুপগুলি পুনরাবৃত্ত গণনা বাস্তবায়নের জন্য কেবল দুটি উপায় / কনস্ট্রাক্ট।

একটি whileলুপ একটি লেজ-পুনরাবৃত্তির কলের সাথে সম্পর্কিত (যেমন দেখুন এখানে ), অর্থাত্ একটি পুনরাবৃত্তি যাতে আপনাকে দুটি পুনরাবৃত্তির মধ্যে মধ্যবর্তী ফলাফলগুলি সংরক্ষণ করার দরকার নেই (আপনি যখন পরবর্তী চক্রটিতে প্রবেশ করেন তখন একটি চক্রের সমস্ত ফলাফল প্রস্তুত থাকে)। যদি আপনাকে মধ্যবর্তী ফলাফলগুলি সংরক্ষণ করতে হয় যা পরে আপনি আবার ব্যবহার করতে পারেন তবে আপনি হয় whileস্ট্যাকের সাথে একটি লুপ ব্যবহার করতে পারেন ( এখানে দেখুন ), অথবা একটি নন টেইল-রিকার্সিভ (অর্থাত্ স্বেচ্ছাচারী) পুনরাবৃত্তি কল।

অনেক ভাষাগুলি আপনাকে উভয় প্রক্রিয়া ব্যবহারের অনুমতি দেয় এবং আপনি যেটি আপনার পক্ষে উপযুক্ত তা বেছে নিতে পারেন এবং এমনকি আপনার কোডে এগুলি একসাথে মিশ্রিত করতে পারেন। সি, সি ++, জাভা ইত্যাদি অনুজ্ঞাসূচক ভাষায় আপনি সাধারণত একটি ব্যবহার whileবা forযখন আপনি একটি স্ট্যাক প্রয়োজন হবে না লুপ, এবং আপনি রিকার্সিভ কল ব্যবহার যখন আপনি একটি স্ট্যাক (আপনি পরোক্ষভাবে রান-টাইম স্ট্যাক ব্যবহার করুন) প্রয়োজন। হাস্কেল (একটি কার্যকরী ভাষা) একটি পুনরাবৃত্তি নিয়ন্ত্রণ কাঠামো সরবরাহ করে না যাতে আপনি কেবল পুনরাবৃত্তি সম্পাদন করতে পুনরাবৃত্ত কলগুলি ব্যবহার করতে পারেন।

আপনার উদাহরণে (আমার মন্তব্য দেখুন):

// queens should have type int [] , not int.
private boolean placeQueen(int row, int [] queens, int n)
{
    boolean result = false;
    if (row < n)
    {
        // Iterate with queens[row] = 1 to n - 1.
        // After each iteration, you either have a result
        // in queens, or you have to try the next column for
        // the current row: no intermediate result.
        while ((queens[row] < n - 1) && !result)
        {
            queens[row]++;
            if (verify(row,queens,n))
            {
                // I think you have 'result' here, not 'ok'.
                // This is another loop (iterate on row).
                // The loop is implemented as a recursive call
                // and the previous values of row are stored on
                // the stack so that we can resume with the previous
                // value if the current attempt finds no solution.
                result = placeQueen(row + 1,queens,n);
            }
        }
        if (!result) {
            queens[row] = -1;
        }
    }else{
        result = true;
    }
    return result;
}

1

পুনরাবৃত্তি এবং পুনরাবৃত্তি বা লুপিংয়ের মধ্যে একটি সম্পর্ক রয়েছে বলে আপনি মনে করেন ঠিক। পুনরাবৃত্ত আলগোরিদিমগুলি প্রায়শই ম্যানুয়ালি বা এমনকি স্বয়ংক্রিয়ভাবে লেজ কল অপ্টিমাইজেশন ব্যবহার করে পুনরাবৃত্ত সমাধানগুলিতে রূপান্তরিত হয়।

আটটি রানীতে, পুনরাবৃত্তকারী অংশটি ব্যাক ট্র্যাকিংয়ের জন্য প্রয়োজনীয় ডেটা সংরক্ষণ করার সাথে সম্পর্কিত। যখন আপনি পুনরাবৃত্তির কথা ভাবেন, তখন স্ট্যাকের উপরে কী চাপানো হয় তা চিন্তা করা মূল্যবান। স্ট্যাকটিতে মান প্যারামিটার এবং স্থানীয় ভেরিয়েবলগুলি পাস থাকতে পারে যা অ্যালগরিদমে মূল ভূমিকা পালন করে, বা কখনও কখনও এমন জিনিসপত্র যা প্রত্যাবর্তনের ঠিকানার মতো স্পষ্টত প্রাসঙ্গিক হয় না বা এই ক্ষেত্রে, রানীর সংখ্যার সাথে একটি পাস করা মান ব্যবহৃত হয় তবে অ্যালগরিদম দ্বারা পরিবর্তন করা হয়নি।

আটটি রানীতে যে ক্রিয়াকলাপটি ঘটে তা হ'ল মূলত আমাদের প্রথম কয়েকটি কলামে কিছু সংখ্যক কুইনের আংশিক সমাধান দেওয়া হয় যা থেকে আমরা বর্তমান কলামে বৈধ-এতদূর পর্যন্ত পছন্দগুলি নির্ধারণ করি যা আমরা পুনরাবৃত্তির সাথে মূল্যায়নের জন্য পাস করি the অবশিষ্ট কলাম। স্থানীয়ভাবে আটটি রানী কোন সারিটি চেষ্টা করছে তা ট্র্যাক করে রাখে এবং যদি পিছনের ট্র্যাকিং ঘটে থাকে তবে এটি বাকী সারিগুলির মধ্য দিয়ে যাওয়ার জন্য বা অন্য কোনও সারিটি কাজ করতে পারে না তবে কেবল ফিরে এসে আরও ট্র্যাক করতে প্রস্তুত।


0

"সমস্যার একটি ছোট সংস্করণ তৈরি করুন" অংশটিতে লুপ থাকতে পারে। যতক্ষণ পদ্ধতিটি নিজেকে ছোট আকারের পরামিতি হিসাবে ক্ষণস্থায়ী হিসাবে কল করে, ততক্ষণ পদ্ধতিটি পুনরাবৃত্তিযোগ্য। অবশ্যই একটি প্রস্থান শর্ত, যখন সমস্যার ক্ষুদ্রতম সম্ভাব্য সংস্করণটি সমাধান হয়ে যায় এবং পদ্ধতিটি কোনও মান দেয়, স্ট্যাক ওভারফ্লো শর্ত এড়াতে অবশ্যই সরবরাহ করতে হবে।

আপনার প্রশ্নের পদ্ধতিটি পুনরাবৃত্ত।


0

পুনরাবৃত্তি মূলত আপনার ফাংশনটিকে আবার কল করে এবং পুনরাবৃত্তির প্রধান সুবিধা স্মৃতি সাশ্রয় করে। পুনরাবৃত্তির এতে লুপ থাকতে পারে তারা অন্য কোনও ক্রিয়াকলাপ সম্পাদন করতে ব্যবহৃত হয়।


পৃথক প্রার্থনা করা. অনেকগুলি অ্যালগরিদম পুনরাবৃত্তিমূলক বা পুনরাবৃত্ত হতে পারে এবং যদি আপনি ফেরত ঠিকানা, প্যারামিটার এবং স্থানীয় ভেরিয়েবলগুলি স্ট্যাকের উপরে চাপানো হয় তবে এটি গণনা করা হলে পুনরাবৃত্ত সমাধানটি অনেক বেশি মেমরি নিবিড় থাকে। কিছু ভাষা লেজ পুনরাবৃত্তি বা লেজ কল অপ্টিমাইজেশানের জন্য অনুকূলকরণ সনাক্ত এবং সহায়তা করে, তবে এটি কখনও কখনও ভাষা বা কোড নির্দিষ্ট specific
বিকাশকারীরা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.