【问题标题】:Iterative / Recursion迭代/递归
【发布时间】:2019-12-10 11:43:16
【问题描述】:

我已经编写了有关如何使用 for 循环查找给定字符串的排列的代码。我遵循了教授的伪代码,但不确定如何将其转换为递归。 (不适用于、goto、while、STL 算法)。

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);
        }
    }
}

代码运行良好,只是需要帮助将其转换为递归。

【问题讨论】:

  • 呃?它在我看来已经是递归的了。
  • 这仍然是一个递归解决方案,因为您在 printpermutations 内部调用 printPermutations。您是否正在寻找不使用 for 循环的递归解决方案?您在这里有一个递归步骤和一个基本案例,基本上是您需要确定它是否递归的两件事
  • 我们不允许使用任何类型的循环,我们只允许使用 if 语句 :( 我使用 for 循环编写它,因为我不知道如何只使用 if声明。
  • 您能否提供一个示例输入和所需的输出?
  • 会的! @李子0

标签: c++ string recursion permutation


【解决方案1】:

要将循环提升到递归中,您必须将迭代变量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);
    }
}

这几乎是机械改造。首先,i0 的初始化已移至参数列表中,我们通过默认值执行此操作(必要时我们也可以让调用者显式传递零)。循环的 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 == "" 检查包含在循环中,但我们知道它保持为假,因为我们从不修改rest

【讨论】:

  • 感谢@Kaz 的帮助!
【解决方案2】:

每个循环都可以变成递归:

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 并在其闭包中指向它以便能够重复出现,然后 functionVarsum 可以是闭包变量。

【讨论】:

    猜你喜欢
    • 2012-10-17
    • 2011-11-14
    • 1970-01-01
    • 2012-04-26
    • 2012-01-23
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多