スタックをすぐにいっぱいにする再帰アルゴリズムがいくつかあります。1 つの解決策は、スタックを明示的にして、アルゴリズムを反復的なものにすることです。
しかし、明示的なスタックを使用すると、アルゴリズムがかなり遅くなることに気付きました (これはおそらく驚くべきことではありませんでした)。明示的なスタックを高速化するための一般的な C++ ガイドラインはありますか? 元の再帰アルゴリズムよりも高速に実行できますか?
編集:私が明示的なスタックを書いた関数は以下のとおりです。反復コードも貼り付けました。なんらかの理由で、std::vector
ではなくを使用する方std::stack
が高速であり、これは非常に驚くべきことです。
// A(m, n) = n + 1 if m = 0
// = A(m - 1, 1) if m > 0 and n = 0
// = A(m - 1, A(m, n - 1)) if m, n > 0
int A(int m, int n, long& iterations,
std::vector<std::pair<int, int> >& stack)
{
stack.push_back(std::make_pair(m, n));
long result = 0;
bool result_available = false;
while (stack.size() > 0)
{
iterations += 1;
if (result_available) {
stack.back().second = result;
result_available = false;
}
m = stack.back().first;
n = stack.back().second;
stack.pop_back();
if (m == 0) {
result = n + 1;
result_available = true;
}
else if (m > 0 && n == 0) {
stack.push_back(std::make_pair(m - 1, 1));
}
else if (m > 0 && n > 0) {
stack.push_back(std::make_pair(m - 1, n));
stack.push_back(std::make_pair(m, n - 1));
}
}
return result;
}