[英]Iterative / Recursion
我已經編寫了有關如何使用for循環查找給定字符串的排列的代碼。 我遵循了教授的偽代碼,但是不知道如何轉換它以便遞歸。 (對於STL算法,goto除外)。
void perms(string prefix, string rest)
{
// Followed Format of Pseudocode that Professor gave us
// If nothing remains in the rest string cout what we have for prefix
if (rest == "")
{
cout << prefix << endl;
}
else
{
for (int i = 0; i < rest.length(); i++)
{
string prefix2 = prefix + rest[i];
string rest2 = rest.substr(0, i) + rest.substr(i + 1);
perms(prefix2, rest2);
}
}
}
該代碼運行良好,只需要幫助將其轉換為遞歸即可。
要將循環提升為遞歸,必須將迭代變量i
轉換為參數:
第1步:
void printPermutations(string prefix, string rest, int i = 0)
第2步:
void printPermutations(string prefix, string rest, int i = 0)
{
// Followed Format of Pseudocode that Professor gave us
// If nothing remains in the rest string cout what we have for prefix
if (rest == "")
{
cout << prefix << endl;
}
else if (i < rest.length())
{
// original loop body
string prefix2 = prefix + rest[i];
string rest2 = rest.substr(0, i) + rest.substr(i + 1);
// true original recursion with different prefix and tail.
printPermutations(prefix2, rest2);
// loop continuation via tail recursion: original prefix, next i.
printPermutations(prefix, rest, i + 1);
}
}
這幾乎是機械的轉變。 首先,將i
初始化為0
已進入參數列表,在列表中我們通過默認設置進行了設置(必要時,我們也可以使調用者顯式傳遞零)。 刪除了循環的for
循環頭,僅將其替換為循環保護條件,該條件轉換為if
條件。 然后,循環的延續僅通過尾部調用來完成,在該調用中我們傳遞i + 1
,這成為i
的下一個值。
可以想象這個中間版本仍然是迭代的:
void printPermutations(string prefix, string rest)
{
int i = 0;
topOfFunction:
// Followed Format of Pseudocode that Professor gave us
// If nothing remains in the rest string cout what we have for prefix
if (rest == "")
{
cout << prefix << endl;
}
else if (i < rest.length())
{
// original loop body
string prefix2 = prefix + rest[i];
string rest2 = rest.substr(0, i) + rest.substr(i + 1);
// true original recursion with different prefix and tail.
printPermutations(prefix2, rest2);
// loop continuation via tail recursion: original prefix, next i.
i = i + 1;
goto topOfFunction;
}
}
請注意,盡管rest == ""
檢查包含在循環中,但我們知道它保持為false,因為我們從不修改rest
。
每個循環都可以轉換為遞歸:
void test() {
int functionVar = 10;
int sum = 0;
for (int i=0, int j=2; i<10; i = i - 1, j = j + 2) {
sum = sum + someFun(i, functionVar);
}
// Do something with sum
cout << sum << endl;
}
可以很容易地這樣重寫:
int forReplacement(int i, int j, int sum, functionVar) {
if (i < 2) {
return forReplacement(i - 1, j + 2, sum + someFun(i, functionVar), functionVar);
}
return sum;
}
void test() {
int functionVar = 10;
int sum = forReplacemenrt(0, 0, 0, functionVar);
// Do something with sum
cout << sum << endl;
}
您可以將forReplacement
lambda並在其閉包中對其進行引用以使其能夠重復出現,然后functionVar
和sum
可以是閉包變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.