查找数字X是否为任意幂的算法

时间:2016-04-05 01:44:52

标签: algorithm

我基本上需要一个函数,发现X是^ b的结果,并显示a和b,但我不能使用数学库中的任何可用方法。

2 个答案:

答案 0 :(得分:0)

朴素解(伪代码),循环遍历a(这是指数时间):

for (a = 2; a <= sqrt(X); ++a) {
    b = round ( log ( X ) / log( a ) )
    if (a^b == X) {
         output solution
         exit
    }
}
output no solution found

更好的解决方案(伪代码),循环遍历b(这是多项式时间):

for (b = 2; b <= log(X)/log(2); ++b) {
    a = round ( exp ( log(X)/b ) )
    if (a^b == X) {
         output solution
         exit
    }
}
output no solution found

Python中更好的解决方案:

import math

def inv_power(x):
    upper_limit = math.log(x)/math.log(2)
    b = 2
    while b <= upper_limit:
        a = int(round( math.exp ( math.log(x)/b ) ) )
        if a**b == x:
            return a,b
        b = b + 1
    return None

好问题。我很失望,很多人都投了票。

答案 1 :(得分:0)

我假设整数(来自评论)所以没有蛮力我会试试这个:

  1. 使用Eratosthenes的筛子O(X.log(log(X)))

    最多sqrt(X)或半位X个数1<<(bits(X)>>1)来找到您需要的素数。

  2. 扫描所有找到的素数p(i)并检查您可以将X除以它的次数。 m=~X/ln(X); O(m)

    请记住n的分割数量。如果n<=1则忽略此素数p(i)并继续下一个p(i+1)。如果n>1,则将素数p(i)及其n添加到某个列表中;

  3. list降序排列n

  4. 现在扫描O(m.log(m))以获取解决方案list

    因此q<=m; O(q^2)除以list中的每个条目,现在以相同的方式检查X'=X/list[j].p^list[j].n(仅使用具有相同X'的条目)。如果您有n,请停止检查并输出找到的结果(使用功率X'=1n是所有使用的素数的乘法)。您需要检查具有相同root的素数的所有组合,以便进行递归。如果找不到具有相同n的条目组合而导致n,则转移到具有不同条目的条目 X'=1再次从n开始。

  5. 递归可能如下所示:

    X

    其中 bool check(int X,int n,int j,int &a) { int i,x; for (;(list[j].n==n)&&(j<list.size);j++) // scan all primes with the same `n` { for (x=X,i=0;i<n;i++) x/=list[j].p; // x=X/p^n if (x==1) { a*=list[j].p; return true; }// stop you hit the result if (check(x,n,j+1,a)) return true; // recursion } return false; } 是要检查的数字,X实际上是检查权限,n是在找到的列表中开始输入(无需测试之前的条目,因为它们已经被检查过)并且j是power的基础。如果找到解决方案,则返回true,否则返回false。

    所以现在你只需检查所有找到的功率并输出/停止首先找到的解决方案:

    a

    您可以将其中一些步骤组合在一起,尤其是#1,#2 (甚至避免递归)。如果您需要浮点或定点方法或想要为整数添加一些额外的想法,请参阅和子链接:

    这里非常类似 Q / A ,其中C ++解决方案涵盖了您的问题: