Нахождение значения рекурсивной функции Аккермана

#c #recursion

#c #рекурсия

Вопрос:

Что не так в моем коде? Он не возвращает правильный ответ,

 #include <iostream>
using namespace std;

int ack(int m, int n)
{
    if (m == 0) return n   1;

    if(n == 0) return ack(m - 1, 1);

    return ack(m - 1, ack(m, n - 1));

}

int main()
{
    cout << ack(4, 1) << endl;
    return 0;
}
  

Вот результат:

введите описание изображения здесь

Спасибо.

Комментарии:

1. Я бы предположил, что ваша рекурсия идет слишком глубоко.

2. Я переписал его без рекурсии . Это становится немного медленным, но не должно привести к сбою. Она слишком медленная для запуска на godbolt, поэтому вам придется попробовать ее на своем компьютере. Убедитесь, что вы включили максимальную оптимизацию.

3. Понятия не имею. Я никогда не использовал Code::Blocks . -O3 часто встречается, если у вас есть gcc clang компилятор на основе or. Однако я бы не стал доверять оптимизации для решения этой проблемы, поскольку она может быть не в состоянии обрабатывать все входные данные, которые вы вводите в функцию. Если значения известны во время компиляции, это может быть очень успешным, но не в том случае, если значения задаются во время выполнения.

4. Это работает, большое спасибо. 🙂

5. Вы можете использовать запоминание и рекурсию одновременно.

Ответ №1:

При компиляции с помощью компилятора C вместо C ваша ack() функция вернула корректно, 65533, для меня примерно через 20 секунд.

Использование рекурсивного алгоритма из RosettaCode, который не является дважды рекурсивным, как у вас, возвращает правильное значение примерно за 10 секунд:

 int ack(int m, int n)
{
    for (; m > 0; m--) {
        n = (n == 0) ? 1 : ack(m, n - 1);
    }

    return n   1;
}
  

Поскольку вы не собираетесь достигать более высоких значений Аккермана с помощью этого кода, я не вижу смысла идти намного быстрее.