পুনরাবৃত্তি কি এবং আমি কখন এটি ব্যবহার করব?


121

মেলিং তালিকাগুলি এবং অনলাইন আলোচনায় নিয়মিত উঠে আসা বিষয়গুলির মধ্যে একটি হ'ল কম্পিউটার সায়েন্স ডিগ্রি করার যোগ্যতা (বা এর অভাব)। একটি যুক্তি যা মনে হয় নেতিবাচক পক্ষের জন্য বার বার আসতে পারে যে তারা বেশ কয়েক বছর ধরে কোডিং করে আসছে এবং তারা কখনও পুনরাবৃত্তি ব্যবহার করে নি।

সুতরাং প্রশ্নটি হ'ল:

  1. পুনরাবৃত্তি কি?
  2. আমি কখন পুনরাবৃত্তি ব্যবহার করব?
  3. লোকেরা পুনরাবৃত্তি কেন ব্যবহার করে না?

9
এবং হয়ত এই সাহায্য করে: stackoverflow.com/questions/126756/...
kennytm

3
এই সাহায্য করতে পারে ধারণা উপলব্ধি: এই পৃষ্ঠায় প্রশ্ন দ্বিতীয় মন্তব্যে দেওয়া সংযোগে নেভিগেট করুন এবং কি মন্তব্য করতে বলে যে, stackoverflow.com/questions/3021/...
dtmland

উত্তর:


86

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

কেন তা দেখতে, উপরের ভাষাগুলি কোনও ফাংশন কল করতে যে পদক্ষেপগুলি ব্যবহার করে তা অনুসরণ করুন:

  1. ফাংশনটির আর্গুমেন্ট এবং স্থানীয় ভেরিয়েবলগুলির জন্য স্ট্যাকের উপরে স্থানটি খচিত করা হয়
  2. ফাংশনের যুক্তিগুলি এই নতুন জায়গায় অনুলিপি করা হয়েছে
  3. নিয়ন্ত্রণ ফাংশন জাম্প
  4. ফাংশনের কোড চালায়
  5. ফাংশনের ফলাফলটি একটি ফিরতি মূল্যে অনুলিপি করা হয়
  6. স্ট্যাকটি তার আগের অবস্থানে ফিরে আসে
  7. ফাংশনটি যেখানে ডাকা হয়েছিল সেখানে গিয়ে জাম্প চাপুন

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

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

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

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

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


1
পুনরাবৃত্তির সহজাত ওভারহেডের ব্যাখ্যা দেখতে ভাল see আমি আমার উত্তরেও এটি স্পর্শ করেছি। তবে আমার কাছে, পুনরাবৃত্তির সাথে বড় শক্তি হ'ল আপনি কল স্ট্যাকটি দিয়ে যা করতে পারেন। আপনি পুনরাবৃত্তির সাথে একটি সংক্ষিপ্ত অ্যালগরিদম লিখতে পারেন যা বারবার শাখা করে, আপনাকে ক্রমবর্ধমান হায়ারারচি (পিতামাতার / সন্তানের সম্পর্ক) এর মতো কাজগুলি সহজেই করতে সক্ষম করে। একটি উদাহরণের জন্য আমার উত্তর দেখুন।
স্টিভ ওয়ারথাম

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

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

63

পুনরাবৃত্তি সহজ ইংরেজী উদাহরণ।

A child couldn't sleep, so her mother told her a story about a little frog,
    who couldn't sleep, so the frog's mother told her a story about a little bear,
         who couldn't sleep, so the bear's mother told her a story about a little weasel... 
            who fell asleep.
         ...and the little bear fell asleep;
    ...and the little frog fell asleep;
...and the child fell asleep.

1
হৃদয় ছোঁয়ার জন্য আপ + :)
সুহেল মমতাজ আওয়ান

ছোট বাচ্চাদের জন্য এই জাতীয় গল্প রয়েছে, যারা চাইনিজ লোককাহিনীগুলিতে ঘুমোবেন না, আমি কেবল এটির কথা স্মরণ করেছি এবং এটি আমাকে স্মরণ করিয়ে দেয় যে আসল বিশ্ব পুনরাবৃত্তি কীভাবে কাজ করে।
হার্ভে লিন

49

সবচেয়ে বেসিক কম্পিউটার বিজ্ঞানের অর্থে, পুনরাবৃত্তি একটি ফাংশন যা নিজেকে কল করে। বলুন আপনার লিঙ্কযুক্ত তালিকার কাঠামো রয়েছে:

struct Node {
    Node* next;
};

এবং আপনি জানতে চান যে কোনও লিঙ্কযুক্ত তালিকাটি আপনি কতক্ষণ পুনরাবৃত্তি সহ এটি করতে পারেন:

int length(const Node* list) {
    if (!list->next) {
        return 1;
    } else {
        return 1 + length(list->next);
    }
}

(এটি অবশ্যই লুপের জন্যও করা যেতে পারে তবে ধারণার উদাহরণ হিসাবে কার্যকর)


@ ক্রিস্টোফার: এটি পুনরাবৃত্তির একটি দুর্দান্ত, সহজ উদাহরণ। বিশেষত এটি লেজ পুনরাবৃত্তির একটি উদাহরণ। যাইহোক, আন্দ্রেস যেমন বলেছেন, এটি সহজেই (আরও দক্ষতার সাথে) একটি ফর লুপ দিয়ে আবারও লেখা যায়। আমি আমার উত্তরে যেমন বর্ণনা করেছি, পুনরাবৃত্তির আরও ভাল ব্যবহার রয়েছে।
স্টিভ ওয়ারথাম

2
আপনার কি এখানে অন্য একটি বিবৃতি দরকার?
অ্যাড্রিয়েন

1
না, এটি কেবল স্পষ্টতার জন্য রয়েছে।
আন্দ্রেয়াস ব্রিন্ক

@ স্টিভওয়ার্থাম: এটি লিখিতভাবে লেজ-পুনরাবৃত্তি নয়; length(list->next)তবুও ফিরতে হবে length(list)যাতে পরিণামে ফলাফলটিতে 1 যোগ করতে পারে। এটি কি দৈর্ঘ্য-দূরত্বে পাস করার জন্য লেখা ছিল, তবেই আমরা কলারটির অস্তিত্ব ভুলতে পারি। লাইক int length(const Node* list, int count=0) { return (!list) ? count : length(list->next, count + 1); }
সিএওও

46

যখনই কোনও ফাংশন নিজেকে কল করে, একটি লুপ তৈরি করে, তখনই পুনরাবৃত্তি। যে কোনও কিছুর সাথে পুনরাবৃত্তির জন্য ভাল ব্যবহার এবং খারাপ ব্যবহার রয়েছে।

এর সর্বাধিক সাধারণ উদাহরণ হল লেজ পুনরাবৃত্তি যেখানে ফাংশনের একেবারে শেষ লাইনটি নিজের কাছে কল:

int FloorByTen(int num)
{
    if (num % 10 == 0)
        return num;
    else
        return FloorByTen(num-1);
}

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

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

এখানে চিত্র বর্ণনা লিখুন

আপনি খুব সহজেই পুনরাবৃত্তি নিয়ে তাদের মধ্যে একটি আঁকতে পারেন, যেখানে কলটি তিনটি দিকের শাখা:

private void BuildVertices(double x, double y, double len)
{
    if (len > 0.002)
    {
        mesh.Positions.Add(new Point3D(x, y + len, -len));
        mesh.Positions.Add(new Point3D(x - len, y - len, -len));
        mesh.Positions.Add(new Point3D(x + len, y - len, -len));
        len *= 0.5;
        BuildVertices(x, y + len, len);
        BuildVertices(x - len, y - len, len);
        BuildVertices(x + len, y - len, len);
    }
}

যদি আপনি পুনরাবৃত্তির সাথে একই জিনিসটি করার চেষ্টা করেন তবে আমার মনে হয় আপনি এটি পেতে আরও অনেক কোড লাগবে।

অন্যান্য সাধারণ ব্যবহারের ক্ষেত্রে ট্র্যাভারিং হায়ারারচিগুলি অন্তর্ভুক্ত থাকতে পারে, যেমন ওয়েবসাইট ক্রলার, ডিরেক্টরি তুলনা ইত্যাদি etc.

উপসংহার

ব্যবহারিক ভাষায়, পুনরাবৃত্তি সর্বাধিক অর্থপূর্ণ হয় যখনই আপনার পুনরাবৃত্ত শাখা প্রয়োজন।


27

পুনরাবৃত্তি হ'ল বিভাজন এবং মানসিকতার উপর নির্ভর করে সমস্যাগুলি সমাধান করার একটি পদ্ধতি। মূল ধারণাটি হ'ল আপনি আসল সমস্যাটি গ্রহণ করেন এবং এটিকে নিজের ছোট (আরও সহজে সমাধান করা) দৃষ্টান্তগুলিতে ভাগ করে নিন, সেই ছোট উদাহরণগুলি (সাধারণত আবার একই অ্যালগরিদম ব্যবহার করে) সমাধান করুন এবং তারপরে তাদের চূড়ান্ত সমাধানে পুনরায় সংযুক্ত করুন।

ক্যানোনিকাল উদাহরণ হ'ল এন এর ফ্যাক্টরিয়াল উত্পন্ন করার একটি রুটিন। N এর ফ্যাক্টরিয়ালটি 1 এবং n এর মধ্যে সমস্ত সংখ্যাকে গুণ করে গণনা করা হয়। সি # তে একটি পুনরাবৃত্তি সমাধান এর মতো দেখাচ্ছে:

public int Fact(int n)
{
  int fact = 1;

  for( int i = 2; i <= n; i++)
  {
    fact = fact * i;
  }

  return fact;
}

পুনরাবৃত্তি সমাধান সম্পর্কে অবাক করার মতো কিছু নেই এবং এটি সি # এর সাথে পরিচিত প্রত্যেকেরই বোধ করা উচিত।

নবম কারকটি n * ফ্যাক্ট (এন -1) এটি স্বীকৃতি দিয়ে পুনরাবৃত্ত সমাধানটি পাওয়া যায়। অথবা এটি অন্য কোনও উপায়ে বলতে গেলে, যদি কোনও নির্দিষ্ট কারক সংখ্যাটি আপনি কী জানেন তবে আপনি পরবর্তীটি গণনা করতে পারেন। এখানে সি # তে পুনরাবৃত্ত সমাধান রয়েছে:

public int FactRec(int n)
{
  if( n < 2 )
  {
    return 1;
  }

  return n * FactRec( n - 1 );
}

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

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

// In FactRec(5)
return 5 * FactRec( 5 - 1 );

// which is
return 5 * FactRec(4);

যদি আমরা 4 টি প্যারামিটার দিয়ে পদ্ধতিটি পুনরায় প্রবেশ করি তবে আমরা আবার গার্ড ক্লজটি বন্ধ করে দেব না এবং তাই আমরা এখানে পৌঁছে যাই:

// In FactRec(4)
return 4 * FactRec(3);

আমরা যদি এই রিটার্ন মানটিকে উপরের রিটার্ন ভ্যালুতে প্রতিস্থাপন করি

// In FactRec(5)
return 5 * (4 * FactRec(3));

এটি আপনাকে চূড়ান্ত সমাধানটি কীভাবে পৌঁছেছে সে সম্পর্কে একটি সূত্র দেওয়া উচিত তাই আমরা দ্রুত ট্র্যাক করব এবং নীচের পথে প্রতিটি পদক্ষেপ প্রদর্শন করব:

return 5 * (4 * FactRec(3));
return 5 * (4 * (3 * FactRec(2)));
return 5 * (4 * (3 * (2 * FactRec(1))));
return 5 * (4 * (3 * (2 * (1))));

বেস কেস ট্রিগার করা হলে চূড়ান্ত প্রতিস্থাপনটি ঘটে। এই মুহুর্তে আমাদের কাছে সমাধানের জন্য একটি সাধারণ অ্যালগ্রেব্রিক সূত্র রয়েছে যা প্রথম স্থানে ফ্যাক্টরিয়ালগুলির সংজ্ঞার সাথে সরাসরি সমান হয়।

এটি লক্ষণীয় যে শিক্ষাপ্রতিষ্ঠানের প্রতিটি কল একটি বেস কেসটিকে ট্রিগার করে বা একই পদ্ধতিতে কল দেয় যেখানে প্যারামিটারগুলি বেস কেস (যার প্রায়শই পুনরাবৃত্তি কল নামে পরিচিত) এর কাছাকাছি থাকে in যদি এটি না হয় তবে পদ্ধতিটি চিরকালের জন্য চলবে।


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

1
@ স্টিভওয়ার্থাম: এটি পুচ্ছ পুনরাবৃত্তি নয়। পুনরাবৃত্তির পদক্ষেপে, ফলাফলটি ফিরে আসার আগে FactRec()বহুগুণ করতে হয় n
rvighne

12

পুনরাবৃত্তি নিজেকে কল করে এমন একটি ফাংশন দিয়ে কোনও সমস্যার সমাধান করছে। এর একটি ভাল উদাহরণ একটি ফ্যাক্টরিয়াল ফাংশন। ফ্যাক্টরিয়াল একটি গণিত সমস্যা যেখানে উদাহরণস্বরূপ 5 এর ফ্যাক্টরিয়াল হয় 5 * 4 * 3 * 2 * 1। এই ফাংশনটি এটি সি # তে ইতিবাচক পূর্ণসংখ্যার জন্য সমাধান করে (পরীক্ষিত হয় না - কোনও বাগ থাকতে পারে)।

public int Factorial(int n)
{
    if (n <= 1)
        return 1;

    return n * Factorial(n - 1);
}

9

পুনরাবৃত্তি এমন একটি পদ্ধতিকে বোঝায় যা সমস্যার সমস্যার একটি ছোট সংস্করণ সমাধান করে এবং তারপরে ফলাফলটি এবং আরও কিছু মূলক ব্যবহার করে মূল সমস্যার উত্তর তৈরি করতে সমস্যা সমাধান করে। প্রায়শই, ছোট সংস্করণটি সমাধান করার প্রক্রিয়াতে, পদ্ধতিটি সমস্যার একটি আরও ছোট সংস্করণ সমাধান করবে এবং ঠিক ততক্ষণ এটি "বেইস কেস" না পৌঁছাবে যা সমাধানের পক্ষে তুচ্ছ।

উদাহরণস্বরূপ, সংখ্যার জন্য একটি ফ্যাক্টরিয়াল গণনা Xকরতে, কেউ এটি হিসাবে এটি উপস্থাপন করতে পারে X times the factorial of X-1। সুতরাং, পদ্ধতিটির পুনরুদ্ধারটির সন্ধানের জন্য "পুনরাবৃত্তি" করে X-1এবং তারপরে Xএকটি চূড়ান্ত উত্তর দেওয়ার জন্য যা পাওয়া যায় তার বহুগুণ । অবশ্যই, এর ফ্যাক্টরিয়ালটি সন্ধান করার জন্য X-1, এটি প্রথমে এর ফ্যাক্টরিয়াল গণনা করবে X-2এবং আরও অনেক কিছু। বেস কেসটি X0 বা 1 হবে যখন এই ক্ষেত্রে এটি 1যেহেতু ফিরে আসতে জানে 0! = 1! = 1


1
আমি মনে করি তোমার কি refereing হয় পুনরাবৃত্তির কিন্তু <a href=" en.wikipedia.org/wiki/... এবং Conquer</a> নয় অ্যালগরিদম নকশা নীতি। <একটি href = "এ উদাহরণস্বরূপ দেখুন en.wikipedia। org / wiki / Ackermann_function "> একারম্যানস ফাংশন </a>
গ্যাব্রিয়েল Ščerbák

2
না, আমি ডিঅ্যান্ডসি'র কথা উল্লেখ করছি না। ডি অ্যান্ড সি ইঙ্গিত দেয় যে 2 বা ততোধিক সাব-প্রবলেমগুলি উপস্থিত রয়েছে, নিজেই পুনরাবৃত্তি হয় না (উদাহরণস্বরূপ, এখানে বর্ণিত ঘটনাগত উদাহরণটি ডি অ্যান্ড সি নয় - এটি সম্পূর্ণ রৈখিক)। ডি অ্যান্ড সি মূলত পুনরাবৃত্তির একটি উপসেট।
অ্যাম্বার

3
সঠিক নিবন্ধ থেকে উদ্ধৃত আপনি লিঙ্ক: "একজন ডিভাইড এবং জয় করো অ্যালগরিদম কাজ দ্বারা যাও recursively মধ্যে একটি সমস্যা ভেঙ্গে দুই বা ততোধিক উপ-সমস্যার একই (বা সম্পর্কিত) ধরনের,"
অ্যাম্বার

আমি মনে করি না যে এটি একটি দুর্দান্ত ব্যাখ্যা, কারণ পুনরাবৃত্তি কঠোরভাবে বলতে গেলে সমস্যাটির মোটেও সমাধান করতে হয় না। আপনি কেবল নিজেকে কল করতে পারেন (এবং উপচে পড়া)।
ইউ কে-

আমি পিএইচপি মাস্টারের পক্ষে লিখছি এমন নিবন্ধে আপনার ব্যাখ্যাটি আমি ব্যবহার করছি যদিও আমি এটি আপনাকে দায়ী করতে পারি না। আশা করি আপত্তি করবেন না।
হিমশীতল

9

একটি পুরানো, সুপরিচিত সমস্যা বিবেচনা করুন :

গণিতে, দুই বা ততোধিক অ-শূন্য পূর্ণ পূর্ণসংখ্যার সবচেয়ে বড় সাধারণ বিভাজক (জিসিডি) হ'ল বৃহত্তম ধনাত্মক পূর্ণসংখ্যা যা বাকী ছাড়াই সংখ্যাগুলি ভাগ করে দেয়।

গিসিডির সংজ্ঞাটি আশ্চর্যজনকভাবে সহজ:

gcd সংজ্ঞা

যেখানে মোড হল মডুলো অপারেটর (এটি হল পূর্ণসংখ্যা বিভাগের পরে অবশিষ্ট)।

ইংরেজিতে এই সংজ্ঞা কোন সংখ্যা সাধারণ গুণনীয়ক বক্তব্য এবং শূন্য যে সংখ্যা, এবং দুটি সংখ্যার সাধারণ গুণনীয়ক হয় মি এবং এন সাধারণ গুণনীয়ক হয় এন এবং বিভাজক পর বাকি মি দ্বারা এন

আপনি কেন এটি কাজ করে তা জানতে চাইলে ইউক্লিডিয়ান অ্যালগরিদমের উইকিপিডিয়া নিবন্ধটি দেখুন ।

উদাহরণস্বরূপ gcd (10, 8) গণনা করা যাক। প্রতিটি পদক্ষেপের ঠিক আগে তার সমান:

  1. জিসিডি (10, 8)
  2. জিসিডি (10, 10 মডি 8)
  3. জিসিডি (8, 2)
  4. জিসিডি (8, 8 মড 2)
  5. জিসিডি (2, 0)
  6. 2

প্রথম ধাপে 8 টি শূন্যের সমান হয় না, সুতরাং সংজ্ঞাটির দ্বিতীয় অংশটি প্রযোজ্য। 10 মোড 8 = 2 কারণ 8 টি একবারে 2 এর অবশিষ্টাংশের সাথে 10 এ যায় 3 ধাপ 3 এ, দ্বিতীয় অংশটি আবার প্রয়োগ হয়, তবে এবার 8 মড 2 = 0 কারণ 2 টির সাথে বাকী অংশ ছাড়াই 8 ভাগ করে। 5 ধাপে, দ্বিতীয় তর্কটি 0 হয়, সুতরাং উত্তরটি 2 হয়।

আপনি কি খেয়াল করেছেন যে সমান চিহ্নটির বাম এবং ডানদিক উভয় দিকেই জিসিডি উপস্থিত হয়েছে? একজন গণিতবিদ বলবেন যে এই সংজ্ঞাটি পুনরাবৃত্ত হয় কারণ আপনি যে অভিব্যক্তিটি সংজ্ঞায়িত করছেন তার সংজ্ঞাটির ভিতরে পুনরাবৃত্তি ঘটে

পুনরাবৃত্ত সংজ্ঞা মার্জিত হতে থাকে। উদাহরণস্বরূপ, তালিকার যোগফলের জন্য একটি পুনরাবৃত্ত সংজ্ঞা

sum l =
    if empty(l)
        return 0
    else
        return head(l) + sum(tail(l))

headতালিকার প্রথম উপাদানটি কোথায় এবং তালিকার tailবাকি অংশ। নোট করুন যে sumএর সংজ্ঞাটি শেষে শেষ হয় urs

পরিবর্তে আপনি তালিকার সর্বোচ্চ মানটিকে পছন্দ করতে পারেন:

max l =
    if empty(l)
        error
    elsif length(l) = 1
        return head(l)
    else
        tailmax = max(tail(l))
        if head(l) > tailmax
            return head(l)
        else
            return tailmax

এটিকে সংযোজনগুলির একটি সিরিজে পরিণত করার জন্য আপনি অ-নেতিবাচক পূর্ণসংখ্যার পুনরাবৃত্তভাবে সংজ্ঞা দিতে পারেন:

a * b =
    if b = 0
        return 0
    else
        return a + (a * (b - 1))

গুণকে সংযোজনগুলির একটি সিরিজে রূপান্তরিত করার বিষয়ে যদি সেই বিটটি বোঝা যায় না, এটি কীভাবে কাজ করে তা দেখার জন্য কয়েকটি সাধারণ উদাহরণ প্রসারিত করার চেষ্টা করুন।

মার্জ সাজানোর একটি সুন্দর পুনরাবৃত্ত সংজ্ঞা রয়েছে:

sort(l) =
    if empty(l) or length(l) = 1
        return l
    else
        (left,right) = split l
        return merge(sort(left), sort(right))

আপনি কী কী সন্ধান করবেন তা যদি জানা থাকে তবে পুনরাবৃত্তি সংজ্ঞাগুলি চারদিকে রয়েছে। লক্ষ্য করুন যে এই সমস্ত সংজ্ঞায় কীভাবে খুব সাধারণ বেস কেস রয়েছে, যেমন , gcd (m, 0) = m। পুনরাবৃত্তির ক্ষেত্রে সহজ উত্তর পেতে নামার জন্য সমস্যাটি দূরে সরে যায়।

এই বোঝার সাথে, আপনি এখন পুনরাবৃত্তি সম্পর্কিত উইকিপিডিয়ায় নিবন্ধের অন্যান্য অ্যালগরিদমগুলির প্রশংসা করতে পারেন !


8
  1. একটি ফাংশন যা নিজেকে কল করে
  2. যখন কোনও ফাংশন (সহজেই) কোনও সাধারণ অপারেশন এবং সমস্যার কিছু ছোট অংশে একই ক্রিয়ায় বিভক্ত হতে পারে। আমার বলা উচিত, বরং এটি পুনরাবৃত্তির জন্য ভাল প্রার্থী করে তোলে।
  3. তারা করে!

ক্যানোনিকাল উদাহরণটি হ'ল ফ্যাক্টরিয়াল যা দেখে মনে হয়:

int fact(int a) 
{
  if(a==1)
    return 1;

  return a*fact(a-1);
}

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


6

একটি পুনরাবৃত্তি ফাংশন হ'ল যা নিজেকে কল করে। এটি ব্যবহার করার সর্বাধিক সাধারণ কারণ হ'ল গাছের কাঠামোকে অনুসরণ করা। উদাহরণস্বরূপ, আমার যদি চেকবক্সগুলি সহ একটি ট্রিভিউ থাকে (নতুন প্রোগ্রামের ইনস্টলেশন মনে করুন, "পৃষ্ঠা ইনস্টল করার জন্য বৈশিষ্ট্যগুলি চয়ন করুন"), আমি একটি "চেক অল" বোতামটি চাই যা এটি (সিউডোকোড) এর মতো হতে পারে:

function cmdCheckAllClick {
    checkRecursively(TreeView1.RootNode);
}

function checkRecursively(Node n) {
    n.Checked = True;
    foreach ( n.Children as child ) {
        checkRecursively(child);
    }
}

সুতরাং আপনি দেখতে পাচ্ছেন যে চেকআরসিউসিভলিটি প্রথমে নোডটি যা পাস হয়েছে তা পরীক্ষা করে, তারপরে সেই নোডের প্রতিটি বাচ্চার জন্য নিজেকে কল করে।

পুনরাবৃত্তি সম্পর্কে আপনার কিছুটা সতর্ক হওয়া দরকার। আপনি যদি একটি অসীম পুনরাবৃত্তীয় লুপে প্রবেশ করেন তবে আপনি স্ট্যাক ওভারফ্লো ব্যতিক্রম পাবেন :)

যখন উপযুক্ত হয় তখন লোকেরা কেন এটি ব্যবহার করবেন না এমন কোনও কারণ আমি ভাবতে পারি না। এটি অন্য পরিস্থিতিতে নয়, কিছু পরিস্থিতিতে কার্যকর।

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


5

পুনরাবৃত্তি প্রত্যক্ষ বা অপ্রত্যক্ষভাবে নিজেকে উল্লেখ করে এমন একটি অভিব্যক্তি।

সরল উদাহরণ হিসাবে পুনরাবৃত্তি সংক্ষিপ্ত নাম বিবেচনা করুন:

  • জিএনইউ মানে জিএনইউর নট ইউনিক্স
  • পিএইচপি পিএইচপি বলতে বোঝায় : হাইপারটেক্সট প্রিপ্রসেসর
  • ওয়াইএএমএল এর অর্থ দাঁড়ায় ওয়াইএএমএল নয় মার্কআপ ল্যাঙ্গুয়েজ
  • WINE এর অর্থ দাঁড়ায় ওয়াইন ইজ নট এমুলেটর
  • ভিসা ঘোরা ভিসা আন্তর্জাতিক পরিষেবা এসোসিয়েশন

উইকিপিডিয়ায় আরও উদাহরণ


4

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

লোকেরা বিভিন্ন কারণে পুনরাবৃত্তি এড়ায়:

  1. বেশিরভাগ লোক (নিজের অন্তর্ভুক্ত) কার্যনির্বাহী প্রোগ্রামিংয়ের বিপরীতে প্রক্রিয়াজাতীয় বা অবজেক্ট ভিত্তিক প্রোগ্রামিংয়ে তাদের প্রোগ্রামিং দাঁতগুলি কেটে দেন। এই জাতীয় লোকের কাছে, পুনরাবৃত্তি পদ্ধতি (সাধারণত লুপগুলি ব্যবহার করে) আরও প্রাকৃতিক বোধ করে।

  2. আমরা যারা প্রক্রিয়াজাতীয় বা অবজেক্ট ভিত্তিক প্রোগ্রামিংয়ে আমাদের প্রোগ্রামিং দাঁতগুলি কাটা করি তাদের প্রায়শই পুনরাবৃত্তি এড়াতে বলা হয়েছে কারণ এটি ত্রুটিযুক্ত।

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

  4. কমপক্ষে কয়েকটি প্রোগ্রামিং ল্যাঙ্গুয়েজ আমি ব্যবহার করেছি, আমি মনে করি শুনার প্রস্তাবগুলি যদি নির্দিষ্ট গভীরতার বাইরে চলে যায় তবে পুনরাবৃত্তিটি ব্যবহার করবেন না কারণ এর স্ট্যাকটি এত গভীর নয়।


4

একটি পুনরাবৃত্ত বিবৃতি এমন একটি যা আপনি ইনপুটগুলির সংমিশ্রণ হিসাবে এবং ইতিমধ্যে আপনি যা করেছেন তার প্রক্রিয়াটি সংজ্ঞায়িত করে।

উদাহরণস্বরূপ, ফ্যাক্টরিয়াল নিন:

factorial(6) = 6*5*4*3*2*1

তবে ফ্যাকটোরিয়াল (6) দেখতে এটিও সহজ:

6 * factorial(5) = 6*(5*4*3*2*1).

সুতরাং সাধারণত:

factorial(n) = n*factorial(n-1)

অবশ্যই, পুনরাবৃত্তি সম্পর্কে জটিল জিনিস হ'ল আপনি যদি ইতিমধ্যে যা করেছেন তার নিরিখে জিনিসগুলি সংজ্ঞায়িত করতে চান তবে কিছুটা শুরু করার দরকার আছে।

এই উদাহরণে, আমরা কেবল ফ্যাকটোরিয়াল (1) = 1 সংজ্ঞায়িত করে একটি বিশেষ কেস তৈরি করি।

এখন আমরা এটিকে নীচ থেকে উপরে দেখছি:

factorial(6) = 6*factorial(5)
                   = 6*5*factorial(4)
                   = 6*5*4*factorial(3) = 6*5*4*3*factorial(2) = 6*5*4*3*2*factorial(1) = 6*5*4*3*2*1

যেহেতু আমরা ফ্যাকটোরিয়াল (1) = 1 সংজ্ঞায়িত করেছি তাই আমরা "নীচে" পৌঁছেছি।

সাধারণত বলতে গেলে, পুনরাবৃত্তির পদ্ধতির দুটি অংশ রয়েছে:

1) পুনরাবৃত্ত অংশ, যা একই পদ্ধতির মাধ্যমে আপনি "ইতিমধ্যে সম্পন্ন" করেছেন এর সাথে মিলিত নতুন ইনপুটগুলির শর্তে কিছু প্রক্রিয়া সংজ্ঞায়িত করে। (অর্থাত্ factorial(n) = n*factorial(n-1))

2) একটি বেস অংশ, যা নিশ্চিত করে যে প্রক্রিয়াটি শুরু করার জন্য কিছু জায়গা দিয়ে চিরতরে পুনরাবৃত্তি করে না (যেমন factorial(1) = 1 )

প্রথমে আপনার মাথা পেতে এটি কিছুটা বিভ্রান্ত হতে পারে তবে কেবল কয়েকটি উদাহরণ দেখুন এবং এটি সমস্ত একসাথে হওয়া উচিত। আপনি যদি ধারণাটির আরও গভীর ধারণা চান, তবে গাণিতিক আনয়ন অধ্যয়ন করুন। এছাড়াও, সচেতন থাকুন যে কিছু ভাষাগুলি পুনরাবৃত্ত কলগুলির জন্য অপ্টিমাইজ করে যখন অন্যরা তা করে না। আপনি যদি সতর্ক না হন তবে অত্যন্ত ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে आम्हाला নামਾਂ।

আশাকরি এটা সাহায্য করবে...


4

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

আমি স্টিভ ম্যাককনেলস কোড কমপ্লিটে পুনর্বিবেচনার আলোচনাটিও পছন্দ করি যেখানে তিনি পুনরাবৃত্তি সম্পর্কিত কম্পিউটার বিজ্ঞানের বইগুলিতে ব্যবহৃত উদাহরণগুলির সমালোচনা করেন।

ফ্যাকটোরিয়াল বা ফিবোনাচি সংখ্যার জন্য পুনরাবৃত্তি ব্যবহার করবেন না

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

আমি ভেবেছিলাম এটি উত্থাপনের জন্য একটি খুব আকর্ষণীয় পয়েন্ট এবং পুনরাবৃত্তি প্রায়শই ভুল বোঝাবুঝির কারণ হতে পারে।

সম্পাদনা: ডেভের উত্তরের এটি কোনও খোঁড়াখুলি ছিল না - আমি এই পোস্ট করার সময় এই উত্তরটি দেখিনি


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

আমি সম্মত হই - আমি যখন বইটি পড়ছিলাম তখনই আমি জানতে পেরেছিলাম যে এটি পুনরাবৃত্তি সম্পর্কিত একটি বিভাগের মাঝখানে উত্থাপন করার জন্য একটি আকর্ষণীয় বিষয় ছিল
রববেন_ফোর্ড_ফ্যান_বয়ে

4

1.) কোনও পদ্ধতি পুনরাবৃত্ত হয় যদি এটি নিজেকে কল করতে পারে; হয় সরাসরি:

void f() {
   ... f() ... 
}

বা পরোক্ষভাবে:

void f() {
    ... g() ...
}

void g() {
   ... f() ...
}

২) পুনরাবৃত্তি কখন ব্যবহার করবেন

Q: Does using recursion usually make your code faster? 
A: No.
Q: Does using recursion usually use less memory? 
A: No.
Q: Then why use recursion? 
A: It sometimes makes your code much simpler!

৩) লোকেরা কেবল তখনই পুনরাবৃত্তি ব্যবহার করে যখন পুনরুক্তি কোডটি লেখা খুব জটিল। উদাহরণস্বরূপ, ট্রি ট্রভারসাল কৌশলগুলি প্রাক অর্ডার, পোস্টর্ডার উভয়ই পুনরাবৃত্ত এবং পুনরাবৃত্ত হতে পারে। তবে সাধারণত আমরা এর সরলতার কারণে পুনরাবৃত্ত ব্যবহার করি।


পারফস সম্পর্কিত বিভাজন এবং বিজয় যখন জটিলতা হ্রাস সম্পর্কে?
এমফ্রেচেট

4

এখানে একটি সাধারণ উদাহরণ: একটি সেটে কয়টি উপাদান। (জিনিসগুলি গণনা করার আরও ভাল উপায় রয়েছে তবে এটি একটি দুর্দান্ত সহজ পুনরাবৃত্ত উদাহরণ))

প্রথমত, আমাদের দুটি বিধি প্রয়োজন:

  1. সেটটি খালি থাকলে সেটে আইটেমের সংখ্যা শূন্য (ডুহ!)।
  2. যদি সেটটি খালি না থাকে তবে একটি আইটেম সরানোর পরে সেটটিতে আইটেমের সংখ্যাটি একটি হয় plus

ধরুন আপনার কাছে এর মতো একটি সেট রয়েছে: [এক্সএক্সএক্সএক্স]। আসুন গণনা করুন কত আইটেম আছে।

  1. সেটটি [এক্সএক্সএক্সএক্স] যা খালি নয়, তাই আমরা বিধি ২ প্রয়োগ করি items আইটেমের সংখ্যা হ'ল [xx] এ আইটেমের সংখ্যা (যেমন আমরা একটি আইটেম সরিয়েছি)।
  2. সেটটি [xx], সুতরাং আমরা আবার নিয়ম 2 প্রয়োগ করি: [x] এ আইটেমের একটি + সংখ্যা।
  3. সেটটি [x], যা এখনও নিয়মের সাথে মেলে 2: এক + আইটেমের সংখ্যা []।
  4. এখন সেটটি [], যা নিয়মের সাথে মেলে 1: গণনাটি শূন্য!
  5. এখন যেহেতু আমরা পদক্ষেপ 4 (0) এ উত্তরটি জানি, আমরা পদক্ষেপ 3 (1 + 0) সমাধান করতে পারি
  6. তেমনি, এখন আমরা পদক্ষেপ 3 (1) এ উত্তরটি জানি, আমরা পদক্ষেপ 2 (1 + 1) সমাধান করতে পারি
  7. এবং অবশেষে এখন যেহেতু আমরা পদক্ষেপ 2 (2) এ উত্তরটি জানি, আমরা পদক্ষেপ 1 (1 + 2) সমাধান করতে পারি এবং [xxx] এ আইটেমের সংখ্যা পেতে পারি, যা 3 হুর!

আমরা এটিকে প্রতিনিধিত্ব করতে পারি:

count of [x x x] = 1 + count of [x x]
                 = 1 + (1 + count of [x])
                 = 1 + (1 + (1 + count of []))
                 = 1 + (1 + (1 + 0)))
                 = 1 + (1 + (1))
                 = 1 + (2)
                 = 3

একটি পুনরাবৃত্ত সমাধান সমাধান করার সময়, আপনার সাধারণত কমপক্ষে 2 টি বিধি থাকে:

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

যদি আমরা উপরেরটি সিউডোকোডে অনুবাদ করি তবে আমরা পাই:

numberOfItems(set)
    if set is empty
        return 0
    else
        remove 1 item from set
        return 1 + numberOfItems(set)

আরও অনেক দরকারী উদাহরণ রয়েছে (উদাহরণস্বরূপ একটি গাছকে অনুসরণ করা) যা আমি নিশ্চিত যে অন্যান্য লোকেরাও এটি আবরণ করবে।


3

ভাল, এটি আপনার কাছে একটি সুন্দর শালীন সংজ্ঞা। এবং উইকিপিডিয়া একটি ভাল সংজ্ঞা আছে। সুতরাং আমি আপনার জন্য আরও একটি (সম্ভবত আরও খারাপ) সংজ্ঞা যুক্ত করব।

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


3

একটি উদাহরণ: সিঁড়িটির পুনরাবৃত্তি সংজ্ঞাটি হ'ল: একটি সিঁড়িটি রয়েছে: - একটি একক পদক্ষেপ এবং একটি সিঁড়ি (পুনরাবৃত্তি) - বা কেবল একটি একক পদক্ষেপ (সমাপ্তি)


2

সমাধান করা সমস্যার পুনরাবৃত্তি করতে: কিছুই করবেন না, আপনি শেষ করেছেন।
একটি উন্মুক্ত সমস্যার পুনরাবৃত্তি করতে: পরবর্তী পদক্ষেপটি করুন, তারপরে বাকী অংশে পুনরাবৃত্তি করুন।


2

সাধারণ ইংরেজী ভাষায়: ধরে নিন আপনি 3 টি জিনিস করতে পারেন:

  1. একটি আপেল নিন
  2. ট্যালি চিহ্ন লিখুন
  3. ট্যালি চিহ্নগুলি গণনা করুন

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

start
  Is the table empty?
  yes: Count the tally marks and cheer like it's your birthday!
  no:  Take 1 apple and put it aside
       Write down a tally mark
       goto start

আপনার কাজ শেষ না হওয়া পর্যন্ত একই জিনিসটির পুনরাবৃত্তি করার প্রক্রিয়াটিকে পুনরাবৃত্তি বলা হয়।

আমি আশা করি এটি আপনি "সাদামাটা ইংলিশ" উত্তরটি খুঁজছেন!


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

যদি আপনি স্থল থেকে একটি আপেল নিয়ে যান (প্রক্রিয়া চলাকালীন সেখানে এটি রাখেন) এবং প্রতিবার তালিকার একটি টালি চিহ্ন স্ক্র্যাচ করে প্রতিবার টেবিলে রাখুন যতক্ষণ না কোনও টাল চিহ্ন থাকে না, আমি নিশ্চিত আমি নিশ্চিত আপনি টেবিলের উপরে প্রচুর পরিমাণে আপেল পাবেন যা আপনি পেয়েছিলেন তার সংখ্যার তুলনায় marks তাত্ক্ষণিক সাফল্যের জন্য এখন কেবল সেই আপেলগুলি গণনা করুন! (দ্রষ্টব্য: এই প্রক্রিয়াটি আর পুনরাবৃত্তি নয়, তবে একটি অসীম লুপ)
বাসটিয়ান লিন্ডারস

2

একটি পুনরাবৃত্তি ফাংশন একটি ফাংশন যা নিজের কাছে একটি কল থাকে। একটি রিকার্সিভ স্ট্রাক্ট এমন একটি স্ট্রাক যা নিজের একটি উদাহরণ থাকে। আপনি একটি পুনরাবৃত্ত শ্রেণীর হিসাবে দুটি একত্রিত করতে পারেন। পুনরাবৃত্ত আইটেমের মূল অংশটি হ'ল এটিতে নিজের একটি দৃষ্টান্ত / কল রয়েছে।

একে অপরের মুখোমুখি দুটি আয়না বিবেচনা করুন। আমরা তাদের পরিষ্কার ঝরঝরে প্রভাব দেখেছি। প্রতিটি প্রতিবিম্ব একটি আয়না একটি উদাহরণ, যা একটি আয়না ইত্যাদির মধ্যে অন্তর্ভুক্ত, ইত্যাদি। নিজের প্রতিচ্ছবি থাকা আয়না পুনরাবৃত্তি।

একটি বাইনারি অনুসন্ধান ট্রি পুনরাবৃত্তির একটি ভাল প্রোগ্রামিং উদাহরণ। কাঠামোটি নোডের 2 টি দৃষ্টান্তযুক্ত প্রতিটি নোডের সাথে পুনরাবৃত্ত হয়। বাইনারি অনুসন্ধান গাছে কাজ করার কাজগুলিও পুনরাবৃত্ত হয়।


2

এটি একটি পুরানো প্রশ্ন, তবে আমি লজিস্টিকাল দৃষ্টিকোণ থেকে একটি উত্তর যুক্ত করতে চাই (অর্থাত্ অ্যালগরিদমের নির্ভুলতা দৃষ্টিকোণ বা কার্য সম্পাদনের দিক থেকে নয়)।

আমি কাজের জন্য জাভা ব্যবহার করি এবং জাভা নেস্টেড ফাংশন সমর্থন করে না। এই হিসাবে, যদি আমি পুনরাবৃত্তি করতে চাই, তবে আমাকে একটি বাহ্যিক ফাংশন সংজ্ঞায়িত করতে হতে পারে (যা কেবলমাত্র জাভা এর আমলাতান্ত্রিক নিয়মের বিরুদ্ধেই আমার কোডটি বাধা দেয় কারণ), বা আমাকে পুরোপুরি কোডটি রিফ্যাক্ট করতে হতে পারে (যা আমি সত্যিই ঘৃণা করি)।

সুতরাং, আমি প্রায়শই পুনরাবৃত্তি এড়ানো এবং তার পরিবর্তে স্ট্যাক অপারেশন ব্যবহার করি, কারণ পুনরাবৃত্তি নিজেই মূলত স্ট্যাক অপারেশন।


1

আপনার গাছের কাঠামো যে কোনও সময় আপনি এটি ব্যবহার করতে চান। এটি এক্সএমএল পড়তে খুব কার্যকর।


1

প্রোগ্রামিংয়ের ক্ষেত্রে যেমন পুনরাবৃত্তি প্রযোজ্য তেমন কোনও কাজ সম্পাদনের জন্য বিভিন্ন পরামিতি সহ মূলত তার নিজস্ব সংজ্ঞা (নিজের ভিতরে) থেকে একটি ফাংশন কল করা হয়।


1

"যদি আমার হাতুড়ি থাকে তবে সবকিছুই পেরেকের মতো দেখান" "

পুনরাবৃত্তি হ'ল বিশাল সমস্যাগুলির জন্য সমস্যা সমাধানের কৌশল , যেখানে প্রতিটি পদক্ষেপে "দুটি ছোট জিনিসকে একটি বড় জিনিসে পরিণত করুন" প্রতিবার একই হাতুড়ি দিয়ে।

উদাহরণ

ধরুন আপনার ডেস্কটি 1024 টি কাগজগুলিতে একটি অগোছালো জঞ্জাল দ্বারা আবৃত। পুনরাবৃত্তিটি ব্যবহার করে আপনি কীভাবে মেস থেকে একটি পরিষ্কার, পরিষ্কার কাগজপত্র তৈরি করবেন?

  1. ভাগ করুন: সমস্ত শীট ছড়িয়ে দিন, যাতে আপনার প্রতিটি "স্ট্যাক" এ কেবল একটি শীট থাকে।
  2. বশীভূত:
    1. প্রতিটি শীটকে অন্য একটি শীটের উপরে রাখুন around আপনার কাছে এখন ২ টি স্ট্যাক রয়েছে।
    2. ঘুরে দেখুন, প্রতিটি 2-স্ট্যাককে অন্য 2-স্ট্যাকের উপরে রাখুন। আপনার এখন 4 টি স্ট্যাক রয়েছে।
    3. ঘুরে দেখুন, প্রতিটি 4-স্ট্যাককে অন্য 4-স্ট্যাকের উপরে রাখুন। আপনার এখন 8 টি স্ট্যাক রয়েছে।
    4. ... এবং এ ...
    5. আপনার কাছে এখন 1024 টি শীটের একটি বিশাল স্ট্যাক!

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


6
আপনি বিভাজন এবং বিজয় বর্ণনা করছেন। যদিও এটি পুনরাবৃত্তির উদাহরণ , এটি কোনওভাবেই একমাত্র নয়।
কনরাড রুডল্ফ

সেটা ঠিক আছে. আমি এখানে একটি বাক্যে [পুনরাবৃত্তির জগত] [1] ক্যাপচার করার চেষ্টা করছি না। আমি একটি স্বজ্ঞাত ব্যাখ্যা চাই। [1]: facebook.com/pages/Recursion- প্রথম
269711978049

1

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


1

আরে, দুঃখিত যদি আমার মতামত কারও সাথে একমত হয়, আমি কেবল সহজ সরল ইংরেজিতে পুনরাবৃত্তি ব্যাখ্যা করার চেষ্টা করছি।

মনে করুন আপনার তিনজন পরিচালক আছেন - জ্যাক, জন এবং মরগান। জ্যাক 2 প্রোগ্রামার, জন - 3 এবং মরগান - পরিচালনা করে 5 আপনি প্রতিটি ম্যানেজারকে 300 to দিতে যাচ্ছেন এবং এটির জন্য কী খরচ হবে তা জানতে চান। উত্তরটি সুস্পষ্ট - তবে মর্গান-এর 2 জন কর্মচারী যদি পরিচালকও হন তবে কী হবে?

এখানে পুনরাবৃত্তি আসে। আপনি শ্রেণিবিন্যাসের শীর্ষ থেকে শুরু করুন। সারাংশ ব্যয় 0 $ আপনি জ্যাক দিয়ে শুরু করেন, তারপরে কর্মচারী হিসাবে তার কোনও পরিচালক আছে কিনা তা পরীক্ষা করে দেখুন। আপনি যদি তাদের কোনওটি খুঁজে পান তবে তাদের কর্মচারী হিসাবে কোনও পরিচালক রয়েছে কিনা তা পরীক্ষা করুন। আপনি যখনই কোনও পরিচালক খুঁজে পান প্রতিবারের জন্য সামারি ব্যয়টিতে 300। যোগ করুন। আপনি যখন জ্যাকটি শেষ করেন, জন, তাঁর কর্মচারীদের এবং তারপরে মরগানে যান।

আপনি কখনই জানতে পারবেন না, উত্তর পাওয়ার আগে আপনি কতগুলি চক্র চলবেন, যদিও আপনি জানেন যে আপনার কতজন পরিচালক আছেন এবং আপনি কতগুলি বাজেট ব্যয় করতে পারেন।

পুনরাবৃত্তি একটি গাছ যা শাখা এবং পাতার সাথে যথাক্রমে অভিভাবক এবং শিশুদের বলে। আপনি যখন পুনরাবৃত্তি অ্যালগরিদম ব্যবহার করেন, আপনি কমবেশি সচেতনভাবে ডেটা থেকে একটি গাছ তৈরি করছেন।


1

সরল ইংরেজিতে, পুনরাবৃত্তি মানে বারবার কিছুটা পুনরাবৃত্তি করা।

প্রোগ্রামিংয়ে একটি উদাহরণ হ'ল ফাংশনটিকে নিজের মধ্যে কল করা।

একটি সংখ্যার ফ্যাকটোরিয়াল গণনা করার জন্য নিম্নলিখিত উদাহরণটি দেখুন:

public int fact(int n)
{
    if (n==0) return 1;
    else return n*fact(n-1)
}

1
সরল ইংরেজিতে, বারবার কোনও কিছুর পুনরাবৃত্তি করতে তাকে পুনরাবৃত্তি বলে।
toon81

1

যে কোনও অ্যালগরিদম ডেটাটাইপে স্ট্রাকচারাল পুনরাবৃত্তি প্রদর্শন করে যদি মূলত ডেটাটাইপের প্রতিটি ক্ষেত্রে একটি মামলা সহ একটি স্যুইচ-বিবৃতি থাকে।

উদাহরণস্বরূপ, আপনি যখন কোনও ধরণের কাজ করছেন তখন

  tree = null 
       | leaf(value:integer) 
       | node(left: tree, right:tree)

একটি কাঠামোগত পুনরাবৃত্তির অ্যালগরিদমের ফর্মটি থাকবে

 function computeSomething(x : tree) =
   if x is null: base case
   if x is leaf: do something with x.value
   if x is node: do something with x.left,
                 do something with x.right,
                 combine the results

ডেটা স্ট্রাকচারে কাজ করে এমন কোনও অ্যালগরিদ লিখার পক্ষে এটিই সবচেয়ে স্পষ্ট উপায়।

এখন, আপনি পেনো অ্যাক্সিমগুলি ব্যবহার করে সংজ্ঞায়িত হিসাবে পূর্ণসংখ্যার (ভাল, প্রাকৃতিক সংখ্যা) দিকে তাকান

 integer = 0 | succ(integer)

আপনি দেখতে পাচ্ছেন যে পূর্ণসংখ্যার উপর একটি কাঠামোগত পুনরাবৃত্তির অ্যালগরিদম এর মতো দেখাচ্ছে

 function computeSomething(x : integer) =
   if x is 0 : base case
   if x is succ(prev) : do something with prev

খুব সুপরিচিত ফ্যাক্টরিয়াল ফাংশনটি এই ফর্মের সবচেয়ে তুচ্ছ উদাহরণের মধ্যে রয়েছে।


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.