我的问题是编写一个有效的算法来检查给定数字 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;
答案 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):
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;
};