检查一个数字是** b

时间:2014-01-04 16:06:27

标签: c algorithm math

我的问题是编写一个有效的算法来检查给定数字 n 的形式是 a b 其中 a, b 是整数> = 2.我尝试过以下但不是时间效率。

int cnt = 0;
long long i, sq = sqrt(n);
for (i = 2; i <= sq; i++) {
    if (n % i == 0) {
        cnt++;
        n = n / i;
        while (n % i == 0) {
            n /= i;
            cnt++;

        }
        if (n == 1) {
            break;
        }
    }
}
if (cnt >= 2) {
    return true;
}
return false;

3 个答案:

答案 0 :(得分:3)

我假设您的意思是pow(a, b)而不是a^b,因为C / C ++中的^XOR运算符。

您的问题被称为检测perfect powers ,您可以在互联网上找到很多文献。

例如:Daniel Bernstein的Detecting perfect powers in linear time

答案 1 :(得分:3)

您可以通过替换以下内容来修复代码并加快速度:

if (n == 1) break;

return (n == 1);

然后,由于你遇到了计算sqrt(n)的麻烦,不妨早日退出完美广场:

if (n == sq * sq) return true;

答案 2 :(得分:0)

点子:

if n = 3^5 then:
     ln(n) / ln(3)   = 5
exp( ln(n) /    5  ) = 3

示例JavaScript代码,打开检查器/控制台获取结果(可轻松转换为C):

http://jsfiddle.net/8wuUK/

function powerSplit( n ){
  console.log('n =', n);
  var log = Math.log, exp = Math.exp, abs = Math.abs,
      floor = Math.floor, round = Math.round;
  var epsilon = 0.001;
  var logn = log( n );
  var pow = floor( log(n) / log(2) ) + 1;
  do{
    pow --;
    var base = exp( logn / pow );
    var intbase = round( base );
    if( abs( base - intbase ) > epsilon ) continue;
    //console.log( base, intbase, pow, isExactPower( n, intbase ) );
    if( isExactPower( n, intbase ))  return 'n = ' + intbase +' ^ ' + pow;
  }while( pow >= 1 );
  return 'n is not a power';
}

function isExactPower( n, base ){
  while( n > 1 ){
    if( n % base ) return false;
    n /= base;
  };
  return true;
};