这是一种算法,它将值N(正整数)作为输入,并检查该值是否可以以x ^ y的形式表示。我可以检索基数(x),但我不知道如何在不使用另一个循环的情况下获得指数,以免损害它的时间复杂度。
示例:N = 1024,X = 2,Y = 10
我需要检索的值是Y.
// Returns true if n can be written as x^y
bool isPower(unsigned int n)
{
// Base case
if (n <= 1) return true;
// Try all numbers from 2 to sqrt(n) as base
for (int x=2; x<=sqrt(n); x++)
{
unsigned p = x;
// Keep multiplying p with x while is smaller
// than or equal to x
while (p <= n)
{
p *= x;
if (p == n)
return true;
}
}
return false;
}
答案 0 :(得分:0)
你已经知道了。 Y是你乘以x加1倍的次数。
编辑:为了更清楚你的内循环,把它放在:
unsigned p = x;
unsigned Y = 1;
// Keep multiplying p with x while is smaller
// than or equal to x
while (p <= n)
{
p *= x;
Y++;
if (p == n)
return true; // At this point Y is your Y, no need for another loop.
}
答案 1 :(得分:0)
我认为你可以根据以下想法编写一个更高性能的算法:
如果你进行素数分解,那么因子的所有计数都必须有一个公约除数&gt;因为那时你可以把素因子分组为&#34; gcd&#34;组,所以这也是指数。
E.g。 2 ^ 6 * 3 ^ 4,gcd(4,6)= 2,这也是指数:(2 ^ 3 * 3 ^ 2)^ 2
这是Java中的一个例子:
// returns 0 if undefined and 1 if n can only be written as n^1
public static int getExponent(n) {
if (n < 2)
return 0;
int min = 0;
int prime = 2;
while (prime <= sqrt(n)) {
int count = 0;
while (n % prime == 0) {
count++;
n /= prime;
}
if (count == 1)
return 1;
if (count > 1) {
if (min == 0) {
min = count;
} else {
min = greatestCommonDivisor(min, count);
if (min == 1)
return 1;
}
if (n == 1)
return min;
}
prime = Primes.getNext(prime);
}
return 1;
}
答案 2 :(得分:0)
尝试使用此循环:
// notice that it's decrementing
for (int x=ceil(sqrt(n)); x>1; x--)
{
// the actual base of the log is unimportant, just use the same one for both
double p = log(n)/log(x);
if(floor(p) == p) return true;
}
这将找到最大的x(> 1,以排除普通解决方案),使得p ^ x = n,这相当于搜索最小的p(再次,&lt; n)。这是因为log b a = log x a / log x b。你计算这个除法,然后检查你是否得到整数结果。
有更有效的方法来查找p和x,但您具体询问如何修改现有算法以消除其内循环。