#c #algorithm #recursion
#c #алгоритм #рекурсия
Вопрос:
Я пытаюсь найти мощность числа, используя рекурсию, но в моем дереве рекурсии много повторений. Пожалуйста, помогите мне, как я могу использовать запоминание в своем коде, чтобы повысить эффективность моего кода.
double myPow(double x, int n) {
if(n==0)
return 1;
if(n==-1)
return 1/x;
if(n==1)
return x;
if(n%2==0)
return myPow(x,n/2)*myPow(x,n/2);
else
if(n>0)
return myPow(x,n/2)*myPow(x,n/2 1);
else
return myPow(x,n/2)*myPow(x,n/2-1);
}
**Constraints:**
-100.0 < x < 100.0
-2^31 <= n <= 2^31-1
-10^4 <= x^n <= 10^4
Комментарии:
1. в вашем коде есть два вида чрезмерных повторений. Один предназначен для одного вызова, например
myPow(3.141,20)
, другой для нескольких вызовов. Первое вы можете легко выполнить, в то время как второе у меня есть сомнения, стоит ли это усилий. Какой из них вас беспокоит?2. Будет действительно полезно, если вы сообщите им обоим.
Ответ №1:
Я обычно использую один из двух подходов для решения подобной проблемы.
- Передайте по карте в параметр кэша-> пары результатов
- Рекурсия вверх, это обычно может привести к одной «строке» рекурсивных вызовов, а не к ветвлению.
Для 1 вы можете изменить свой код следующим образом:
double myPow(double x, int n, map<int, double> amp;cache) {
if(n==0)
return 1;
if(n==-1)
return 1/x;
if(n==1)
return x;
auto it = cache.find(n);
if(it != cache.end()){
return it->second;
}
double result = 0;
if(n%2==0)
result = myPow(x,n/2)*myPow(x,n/2);
else
if(n>0)
result = myPow(x,n/2)*myPow(x,n/2 1);
else
result = myPow(x,n/2)*myPow(x,n/2-1);
cache.emplace(n,result);
return resu<
}
Для подхода 2 вы можете начать вычисления при n = 1 и выполнить рекурсию вверх до переданного параметра.
Комментарии:
1. Я что-то здесь упускаю или кэш не должен быть больше похож
map<pair<int, double>, double>
, потому что кэшированное значение зависит как от экспонентыn
, так и от основанияx
? Кажется, что ваш кеш учитывает только показатель степени.2. действительно, ваш кеш предназначен только для экспоненты. И это не нужно, если вы измените
result = myPow(x,n/2)*myPow(x,n/2)
значение наtemp = myPow(x,n/2); result = temp*temp;
(плюс позаботитесь о четных нечетных случаях)3. @Striezel, да, я бы создал оболочку, в которой я объявил карту, а затем передал ее для этой конкретной базы. Конечно, можно кэшировать пару, но вероятность попадания в кэш при удвоении очень низкая.