Лучший способ сделать powerOf (int x, int n)?
Итак, заданные x и power, n, решаем для X^n
.
Там легкий способ, чтобы O(n)
...
Я могу довести его до O(n/2)
, выполнив
numSquares = n/2;
numOnes = n%2;
return (numSquares * x * x + numOnes * x);
Теперь существует решение O(log(n))
, кто-нибудь знает, как это сделать? Это можно сделать рекурсивно.
Ответы
Ответ 1
Ну, вы знаете, что x a + b= x a x b поэтому...
int pow(int x, unsigned int y)
{
if (y == 0) return 1;
if (y == 1) return x;
int a = y / 2;
int xa = pow(x, a);
if (a + a == y) // y even
return xa * xa;
else
return xa * xa * x;
}
Ответ 2
Математическая концепция, которая может быть использована, заключается в том, что x2n+1 = x2n ⋅ x
и x2n = xn ⋅ xn
.
Ответ 3
Обычная реализация - это что-то в этом направлении (вырезано из статьи в википедии):
long power(long x, unsigned long n)
{
long result = 1;
while (n > 0) {
/* n is odd, bitwise test */
if (n & 1) {
result *= x;
}
x *= x;
n /= 2; /* integer division, rounds down */
}
return result;
}
Рекурсия не нужна или (я бы сказал) особенно желательна, хотя она может победить на очевидности:
long power(long x, unsigned long n)
{
if (n == 0) return 1;
long result = power(x, n/2); // x ^ (n/2)
result *= result; // x ^ (n/2)*2
if (n & 1) result *= x; // x ^ n
return result;
}
Конечно, в любой версии вы быстро переполняете довольно быстро. Вы можете применить одни и те же алгоритмы к своему любимому представлению bigint, хотя любая библиотека bigint уже включит функцию целочисленной мощности.
Обе версии функции выше возвращают 1 для power(0,0)
. Вы можете или не можете считать это ошибкой.
Ответ 4
Здесь вы найдете объяснение: Быстрое возведение в степень. Для некоторых значений n вы можете вычислить x ^ n с меньшим количеством умножений, чем с помощью полномочий двух трюков.
Ответ 5
Стандартный трюк состоит в том, чтобы генерировать степени x в последовательности x 2 x 4 x 8 x 16 x 32,... и включают те, которые необходимы в результате.