您遇到的挑戰是您的函數調用和循環結構混雜在一起。這很難解開這些。
首先讓我們開始用遞歸替換流操作的所有控制。
// You'll want to start with getPermutionsR(v, n, 0, 0)
void getPermutationsR(int v[], int n, int i, int j)
{
if (i == n)
{
//Display contents of v
}
else if (j == n) {
// By doing nothing, we break out of the loop
}
else
{
// This was your recursive call inside of the loop.
// Note that I'm sending you to to the first loop iteration here.
swap (v, i, j);
getPermutationsR(v, n, i+1, i+1);
swap (v, i, j);
// And the next loop iteration
getPermutationsR(v, n, i, j+1);
}
}
接下來讓我們添加更多的狀態,這樣我們只有一個遞歸調用內部的,如果條件。
// You'll want to start with getPermutionsR(v, n, 0, 0, 1)
void getPermutationsR(int v[], int n, int i, int j, bool firstCall)
{
if (i == n)
{
//Display contents of v
}
int x = i;
int y = j+1;
if (firstCall) {
swap (v, i, j);
x = i+1;
y = i+1;
}
// My one recursive call. Note that i=n implies j=n.
if (j < n) {
getPermutationsR(v, n, x, y, !firstCall);
}
if (firstCall) {
swap (v, i, j);
}
}
既然我們已經完成了這一步,我們可以通過一種可以直接轉換爲迭代版本的形式。這裏是改造
void recursiveForm (params, recursiveState) {
topHalf...
if (cond) {
recursiveForm(...)
}
bottomHalf...
}
成爲
void iterativeForm(params) {
initializeStacks...
pushStacks...
topHalf...
while (stacks not empty) {
if (cond) {
pushStacks...
topHalf...
}
else {
bottomHalf...
popStacks...
}
}
}
因此應用此模式,我們得到如下:
// You'll want to start with getPermutionsR(v, n, 0, 0, 1)
void getPermutationsI(int v[], int n)
{
stack<int> iStack;
stack<int> jStack;
stack<bool> firstCallStack;
// pushStacks with initial value
iStack.push(0);
jStack.push(0);
firstCallStack.push(1);
// topHalf...
if (iStack.top() == n)
{
//Display contents of v
}
int x = iStack.top();
int y = jStack.top()+1;
if (firstCallStack.top()) {
swap (v, iStack.top(), jStack.top());
x = iStack.top()+1;
y = iStack.top()+1;
}
while iStack.size() > 0) {
// if (cond) {
if (jStack.top() < n) {
//pushStacks...
iStack.push(x);
jStack.push(y);
firstCallStack.push(!firstCallStack.top());
// topHalf...
if (iStack.top() == n)
{
//Display contents of v
}
x = iStack.top();
y = jStack.top()+1;
if (firstCallStack.top()) {
swap (v, iStack.top(), jStack.top());
x = iStack.top()+1;
y = iStack.top()+1;
}
}
else {
// bottomHalf...
if (firstCallStack.top()) {
swap (v, iStack.top(), jStack.top());
}
}
}
}
(警告,所有的測試的代碼,而且可能甚至不會編譯但這個想法是正確的,而且它絕對是相同的算法。)
雖然我更喜歡輕推答案顯而易見的功課問題可複製算法,派人到4卷的大部頭沒有關於這個問題的任何進一步的信息是不是一個有用的答案的。 '-1'。 – sbi
@sbi:首先,TAOCP是7卷,而不是4卷。其次,OP會問這個問題,相信通過玩遞歸解決方案可以完成正確的算法,但事實並非如此。 TAOCP是一本全面解釋問題的書,並且儘可能地分析算法。所以我的參考是唯一正確的。雖然你的意見可能會有所不同。然後---繼續並自己回答這個問題。比Knuth教授做得更好。 – Vlad
我明白你的觀點。仍然。如果您將本章的內容總結爲與問題相關的內容,然後放入該鏈接,我很樂意致力於研究。直接鏈接一些文本已經夠糟糕了。鏈接到關於文本的_article,你提到某人幾乎是惡毒的。 – sbi