Stacks এবং পুনরাবৃত্তির বর্জন নিবন্ধ যেমনটি গাদা উপর স্ট্যাক ফ্রেম externalizing ধারণা, কিন্তু একটি উপলব্ধ করা হয় না সহজবোধ্য এবং repeatable রূপান্তর করতে উপায়। নীচে এক।
পুনরাবৃত্তির কোডে রূপান্তর করার সময়, আপনাকে অবশ্যই সচেতন হতে হবে যে পুনরাবৃত্তি কলটি একটি নির্বিচারে গভীর কোড ব্লক হতে পারে। এটি কেবলমাত্র প্যারামিটারগুলিই নয়, সেই যুক্তিতে ফিরে যেতে পয়েন্টও যা মৃত্যুদন্ড কার্যকর করা থেকে যায় এবং ভেরিয়েবলের অবস্থা যা পরবর্তী শর্তে অংশ নেয়, যা গুরুত্বপূর্ণ। নীচে কমপক্ষে পরিবর্তন সহ পুনরাবৃত্ত কোডে রূপান্তর করার একটি খুব সহজ উপায়।
এই পুনরাবৃত্তির কোডটি বিবেচনা করুন:
struct tnode
{
tnode(int n) : data(n), left(0), right(0) {}
tnode *left, *right;
int data;
};
void insertnode_recur(tnode *node, int num)
{
if(node->data <= num)
{
if(node->right == NULL)
node->right = new tnode(num);
else
insertnode(node->right, num);
}
else
{
if(node->left == NULL)
node->left = new tnode(num);
else
insertnode(node->left, num);
}
}
আইট্রেটিভ কোড:
// Identify the stack variables that need to be preserved across stack
// invocations, that is, across iterations and wrap them in an object
struct stackitem
{
stackitem(tnode *t, int n) : node(t), num(n), ra(0) {}
tnode *node; int num;
int ra; //to point of return
};
void insertnode_iter(tnode *node, int num)
{
vector<stackitem> v;
//pushing a stackitem is equivalent to making a recursive call.
v.push_back(stackitem(node, num));
while(v.size())
{
// taking a modifiable reference to the stack item makes prepending
// 'si.' to auto variables in recursive logic suffice
// e.g., instead of num, replace with si.num.
stackitem &si = v.back();
switch(si.ra)
{
// this jump simulates resuming execution after return from recursive
// call
case 1: goto ra1;
case 2: goto ra2;
default: break;
}
if(si.node->data <= si.num)
{
if(si.node->right == NULL)
si.node->right = new tnode(si.num);
else
{
// replace a recursive call with below statements
// (a) save return point,
// (b) push stack item with new stackitem,
// (c) continue statement to make loop pick up and start
// processing new stack item,
// (d) a return point label
// (e) optional semi-colon, if resume point is an end
// of a block.
si.ra=1;
v.push_back(stackitem(si.node->right, si.num));
continue;
ra1: ;
}
}
else
{
if(si.node->left == NULL)
si.node->left = new tnode(si.num);
else
{
si.ra=2;
v.push_back(stackitem(si.node->left, si.num));
continue;
ra2: ;
}
}
v.pop_back();
}
}
খেয়াল করুন কীভাবে কোডটির কাঠামোটি এখনও পুনরাবৃত্ত যুক্তি অনুসারে সত্য থেকে যায় এবং পরিবর্তনগুলি ন্যূনতম হয়, ফলস্বরূপ কম সংখ্যক বাগ রয়েছে gs তুলনার জন্য, আমি পরিবর্তনগুলি ++ এবং - এর সাথে চিহ্নিত করেছি। V.push_back ব্যতীত বেশিরভাগ নতুন সন্নিবেশ করা ব্লকগুলি কোনও রূপান্তরিত পুনরাবৃত্ত যুক্তি হিসাবে সাধারণ
void insertnode_iter(tnode *node, int num)
{
+++++++++++++++++++++++++
vector<stackitem> v;
v.push_back(stackitem(node, num));
while(v.size())
{
stackitem &si = v.back();
switch(si.ra)
{
case 1: goto ra1;
case 2: goto ra2;
default: break;
}
------------------------
if(si.node->data <= si.num)
{
if(si.node->right == NULL)
si.node->right = new tnode(si.num);
else
{
+++++++++++++++++++++++++
si.ra=1;
v.push_back(stackitem(si.node->right, si.num));
continue;
ra1: ;
-------------------------
}
}
else
{
if(si.node->left == NULL)
si.node->left = new tnode(si.num);
else
{
+++++++++++++++++++++++++
si.ra=2;
v.push_back(stackitem(si.node->left, si.num));
continue;
ra2: ;
-------------------------
}
}
+++++++++++++++++++++++++
v.pop_back();
}
-------------------------
}