C ++ рекурсия с большими числами, чтобы найти мод

Вы также можете использовать метод compareTo() для сравнения двух строк. Если результат compareTo равен 0, то две строки равны, в противном случае сравниваемые строки не равны.

== сравнивает ссылки и не сравнивает фактические строки. Если вы создали каждую строку, используя new String(somestring).intern(), вы можете использовать оператор == для сравнения двух строк, в противном случае могут использоваться только методы equals () или compareTo.

0
задан Artem Khizhnyak 10 March 2019 в 03:20
поделиться

2 ответа

Вы возвращаетесь на глубину 4400, что вызывает проблемы. Также в этом нет необходимости, поскольку вы можете реализовать тот же алгоритм с помощью цикла:

while (n >= m) n -= m ;
return n ;
0
ответ дан TonyK 10 March 2019 в 03:20
поделиться

Если рекурсия слишком глубокая, программе не хватает памяти стека. Это называется переполнением стека.

int modulo(int n, int m) 
{ 
    if (n < m) return n; 
    else return modulo(n - m, m); 
}

Например, modulo(1000000, 2) вызывает modulo(999998, 2), что вызывает modulo(999996, 2), и так далее, пока в конце modulo(0, 2) не будет 500001 активных функций modulo в стеке. Два целых числа, адрес возврата и указатель кадра, должны занимать не менее 16 байт на вызов функции в любой разумной системе. Всего 8 мегабайт стекового пространства, что обычно превышает максимальный размер стека.

Каждый вызов функции должен ждать результатов следующей функции, пока он не завершит свой расчет и не вернется. До его возвращения в стеке должны были храниться все переменные, параметры и адрес возврата. Адрес возврата - это место в программе, где программа должна возобновить работу после оператора return.

Эти вызовы заполняют стек до тех пор, пока не будет достигнут его максимальный предел и программа не завершится.

В некоторых случаях компилятор может преобразовать рекурсию в цикл. В этом случае, поскольку рекурсия находится в операторе return, она может просто goto перейти к началу функции, вообще не выполняя вызов. Это называется оптимизация хвостового вызова :

int modulo(int n, int m) 
{ 
    start:
    if (n < m) return n; 
    else {
       n -= m;
       goto start;
    }
}

Если бы вы включили оптимизацию (-O2 в clang или G ++ или режим выпуска в Visual C ++), не было бы сбоя, так как компилятор создал бы цикл вместо рекурсии. Чтобы избежать сбоя, просто включите оптимизацию.

Обратите внимание, что компилятор не обязан оптимизировать это, и не всегда может. Вот почему не рекомендуется иметь такую ​​глубокую рекурсию.

0
ответ дан Michael Veksler 10 March 2019 в 03:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: