【问题标题】:Is this recursive function impossible to be iterative?这个递归函数不可能迭代吗?
【发布时间】:2015-02-11 19:25:56
【问题描述】:

我试图让这个函数迭代。这似乎是可能的,但我目前找不到这样做的方法。那么甚至有可能证明这个函数不能以任何方式迭代吗?我所说的迭代的意思是根本不使用递归函数调用。

// 我喜欢这个新的auto 关键字。

void every_permutation(const std::vector<int>& v, std::vector<std::vector<int>>& vs) {
    if (v.size() == 1) {
        vs.push_back(v);
        return;
    }
    for (auto i = v.begin(); i != v.end(); ++i) {
        std::vector<int> v_2;
        for (auto j = v.begin(); j != v.end(); ++j) {
            if (j != i) {
                v_2.push_back(*j);
            }
        }
        std::vector<std::vector<int>> vs_2;
        every_permutation(v_2, vs_2);
        for (auto j = vs_2.begin(); j != vs_2.end(); ++j) {
            j->push_back(*i);
        }
        vs.insert(vs.end(), vs_2.begin(), vs_2.end());
    }
}

【问题讨论】:

  • 理论上所有的递归算法都可以转化为带有栈的迭代算法。
  • 算法的描述会很好。

标签: c++ loops recursion iteration


【解决方案1】:

我想你要问的是这个递归函数是否是尾递归。尾递归函数可以很容易地重写为循环,并且不需要堆栈来跟踪局部变量的多个帧。这个函数不是尾递归的;事实上,任何可能在每次迭代中多次调用自身的递归函数都不可能是尾递归的。

非尾递归的递归函数仍然可以迭代编写,但您需要某种堆栈来跟踪计算的状态,以便在解决嵌套子问题后返回到它。使用的空间量至少与嵌套深度成正比。

当然,不是尾递归的函数有时可以重写为尾递归。在某些情况下,您需要完全更改所使用的算法才能完成此操作。

【讨论】:

    【解决方案2】:

    这个函数当然可以迭代。事实上,标准库中有一个函数可以迭代执行:std::next_permutation。你可以这样使用它:

                                         // v-- note: v is a copy here
    void every_permutation(std::vector<int> v, std::vector<std::vector<int>>& vs) {
      // because we need to start with a sorted vector to get all permutations.
      std::sort(v.begin(), v.end());
    
      do {
        vs.push_back(v);
      } while(std::next_permutation(v.begin(), v.end()));
    }
    

    当然,这个 sn-p 并没有告诉你 std::next_permutation 是如何做到的,但很高兴有一个描述 here 的可能实现。

    【讨论】:

      猜你喜欢
      • 2023-03-20
      • 2013-09-10
      • 2021-05-13
      • 2010-10-16
      • 1970-01-01
      • 2015-01-14
      • 1970-01-01
      • 2018-09-26
      • 1970-01-01
      相关资源
      最近更新 更多