这种递归函数不可能是迭代的吗?

时间:2014-12-13 01:27:54

标签: c++ loops recursion iteration

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

//我喜欢这个新的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());
    }
}

2 个答案:

答案 0 :(得分:3)

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

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

当然,一个非尾递归的函数有时可以被重写,以便它是尾递归的。在某些情况下,您需要完全更改所使用的算法才能实现此目的。

答案 1 :(得分:1)

这个功能当然可以迭代。事实上,标准库中有一个函数可以迭代地执行: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()));
}

当然,此代码段并没有告诉您std::next_permutation是如何做到的,但很高兴有一个可能的实现描述here