将递归排列生成器转换为迭代生成器
我在将这种用于显示给定整数集的所有排列的递归算法转换为迭代算法时遇到了一些困难。
void getPermutationsR(int v[], int n, int i)
{
if (i == n)
{
//Display contents of v
}
else
{
for (int j=i; j<n; j++)
{
swap (v, i, j);
getPermutationsR(v, n, i+1);
swap (v, i, j);
}
}
}
这是我当前的尝试,它是完全错误的,但如果不使用本机迭代算法来解决问题,我看不到任何方法来纠正它。我的一半尝试是“弹出”多于“推送”(当我尝试访问空堆栈中的元素时导致错误),另一半尝试“推送”多于“弹出”(无限循环)。
void getPermutationsI(int v[], int n, int i)
{
stack<int> iStack;
stack<int> jStack;
iStack.push(i);
jStack.push(i);
while(iStack.size() > 0)
{
if (iStack.top() == n)
{
jStack.pop();
iStack.pop();
//Display contents of v
}
else
{
for (int j = iStack.top(); j < n; j++)
{
//swap
//something to do with jStack
}
//swap
iStack.push(i+1);
}
}
}
I'm having some difficulty converting this recursive algorithm for displaying all the permutations of a given set of integers into an iterative one.
void getPermutationsR(int v[], int n, int i)
{
if (i == n)
{
//Display contents of v
}
else
{
for (int j=i; j<n; j++)
{
swap (v, i, j);
getPermutationsR(v, n, i+1);
swap (v, i, j);
}
}
}
This is my current attempt, it's completely wrong but I can't see any way to correct it without using a natively iterative algorithm for the problem . Half my attempts have had me 'popping' more than 'pushing' (Leads to an error as I attempt to access elements in an empty stack) and the other half I'm 'pushing' more than 'popping' (infinite loop).
void getPermutationsI(int v[], int n, int i)
{
stack<int> iStack;
stack<int> jStack;
iStack.push(i);
jStack.push(i);
while(iStack.size() > 0)
{
if (iStack.top() == n)
{
jStack.pop();
iStack.pop();
//Display contents of v
}
else
{
for (int j = iStack.top(); j < n; j++)
{
//swap
//something to do with jStack
}
//swap
iStack.push(i+1);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以使用STL:
未测试。
You can use STL:
Not tested.
您需要阅读TAOCP的第7.2.1.2章。
编辑:
根据评论中的讨论,基于堆栈的递归消除也很好(尽管在我看来这不是纯粹的迭代方法)。
这是基于堆栈的版本的草稿:
You need to read the chapter 7.2.1.2 of the TAOCP.
EDIT:
According to the discussion in the comments, a stack-based recursion elimination is good, too (although in my opinion it's not a pure iterative approach).
Here is a draft of a stack-based version:
您可以使用堆栈来使其迭代。在此堆栈中存储您的
j
变量。这应该有效。You can use a stack to make it iterative. In this stack you store your
j
variable. This should work.在Python中:
In Python:
您遇到的挑战是函数调用和循环结构混合在一起。很难理清这些问题。
首先,我们首先用递归替换所有流操作的控制。
接下来,我们添加更多状态,以便 if 条件内只有一次递归调用。
既然我们已经完成了这一点,我们就可以以一种简单的方式将其转换为迭代版本的形式。这里是转换
变成
所以应用该模式我们得到类似的东西:(
警告,所有代码都未经测试,甚至很可能无法编译。但这个想法是正确的。而且它绝对是相同的算法。)
The challenge you are encountering is that you've got function calls and loop constructs intermingled. It is hard to disentangle those.
First let's start by replacing all control of flow operations with recursion.
Next let's add more state so that we only have one recursive call inside of an if condition.
Now that we've accomplished this, we have it in a form where we can transform it into an iterative version in a straightforward way. Here is the transformation
becomes
So applying that pattern we get something like:
(Warning, all code untested, and may well not even compile. But the idea is correct. And it is definitely the same algorithm.)