Php 对于给定的整数Z,检查Z是否可以写成P^Q,其中Q和P是正整数

Php 对于给定的整数Z,检查Z是否可以写成P^Q,其中Q和P是正整数,php,math,exponential,Php,Math,Exponential,这是我尝试过的,但它给了我错误的输出。有人能指出是什么错误吗 function superPower($n) { $response = false; $n = abs($n); if ($n < 2) { $response = true; } for ($i=2;$i<$n;$i++) { for ($j=2;$j<$n;$j++) { if (pow($i,$j) ==

这是我尝试过的,但它给了我错误的输出。有人能指出是什么错误吗

function superPower($n) {
    $response = false;
    $n = abs($n);
    if ($n < 2) { 
       $response = true;
    }
    for ($i=2;$i<$n;$i++) {    
        for ($j=2;$j<$n;$j++) {
            if (pow($i,$j) == $n) {
                $response = true;
            }
        }
    }  

    return $response;   
}
功能超能力($n){
$response=false;
$n=绝对值($n);
如果($n<2){
$response=true;
}

对于($i=2;$i)来说,通过使用超级力量,你基本上是在试图对攻击的力量进行某种防御,看看它是否有效。这可以比你现在使用的暴力方法更有效

function superPower( $hp) { // Niet used Superpower!
    if( $hp <= 1) return true;

    for( $def = floor(sqrt($hp)); $def > 1; $def--) { // Niet's Defence fell
        for( $atk = ceil(log($hp)/log($def)); $atk > 1; $atk--) { // Niet's Attack fell
            if( pow($def,$atk) == $hp) return true;
            break;
            // you don't need the $atk loop, but I wanted to make a Pokémon joke. Sorry.
        }
        // in fact, all you really need here is:
        // $atk = log($hp)/log($def);
        // if( $atk-floor($atk) == 0) return true;
    }
    return false;
}
function superPower($hp){//Niet使用了superPower!
如果($hp 1;$def--){//Niet的防御能力下降
对于($atk=ceil(log($hp)/log($def));$atk>1;$atk--){//Niet的攻击失败了
if(pow($def,$atk)=$hp)返回true;
打破
//你不需要$atk循环,但我想开个神奇宝贝的玩笑。对不起。
}
//事实上,您真正需要的是:
//$atk=log($hp)/log($def);
//如果($atk floor($atk)==0),则返回true;
}
返回false;
}

公认答案上的数学运算绝对精彩,但解决方案中存在两个问题:

  • 对于以下所有输入,函数错误地返回
    true
    monkey
    -3
    0
    (从技术上讲
    0
    是无符号的,因此无法通过将一个正整数取另一个正整数的幂来获得它。任何负输入也是如此。)

  • 该函数将浮点数与整数(
    floor()
    ceil()
    return
    float
    )进行比较,这应该像瘟疫一样避免。要了解原因,请尝试运行
    php-r'$n=((4.42-5))/0.29;echo“n=={$n}\n”。($n==2?“确定”:“惊喜”)“\n”

以下解决方案通过解决上述所有问题改进了该想法:

function superPower($value)
{
    // Fail if supplied value is not numeric
    if (!is_numeric($value)) {
        // throw new InvalidArgumentException("Value is not numeric: $value");
        return false;
    }

    // Normalise numeric input
    $number = abs($value);

    // Fail if supplied number is not an integer
    if (!is_int($number)) {
        // throw new InvalidArgumentException("Number is not an integer: $number");
        return false;
    }

    // Exit early if possible
    if ($number == 1) {
        // 1 to the power of any positive integer is one
        return true;
    } elseif ($number < 1) {
        // X to the power of Y is never less then 1, if X & Y are greater then 0
        return false;
    }

    // Determine the highest logarithm base and work backwards from it
    for ($base = (int) sqrt($number); $base > 1; $base--) {
        $coefficient = log($number)/log($base);

        // Check that the result of division is a whole number
        if (ctype_digit((string) $coefficient)) {
            return true;
        }
    }

    return false;
}
功能超级能力($value)
{
//如果提供的值不是数字,则失败
如果(!是数值($value)){
//抛出新的InvalidArgumentException(“值不是数字:$Value”);
返回false;
}
//标准化数字输入
$number=abs($value);
//如果提供的数字不是整数,则失败
如果(!is_int($number)){
//抛出新的InvalidArgumentException(“数字不是整数:$Number”);
返回false;
}
//如果可能,尽早退出
如果($number==1){
//1乘以任何正整数的幂等于1
返回true;
}elseif($number<1){
//如果X&Y大于0,则X与Y的幂之比决不小于1
返回false;
}
//确定最高的对数基数并从中向后计算
对于($base=(int)sqrt($number);$base>1;$base--){
$系数=对数($number)/对数($base);
//检查除法结果是否为整数
if(ctype_数字((字符串)$系数)){
返回true;
}
}
返回false;
}

我看到的参数名为
$Z
,但没有分配给
$n
。我遗漏了什么吗?也许使用对数可能会加快事情的进行,而且迭代次数太多。最大
$I
应为
sqrt($n)
,最大
$j
应为
ln($n)/ln($I)
(这样I^j>=n)如果($NH您如何检查结果?我刚刚尝试了该函数(没有修改,正如问题中定义的那样)我得到了以下结果:
25->true
26->false
…所以一切似乎都正常。谢谢你!这是一个更好的方法。你可能想防止对函数的无效输入!请注意,OP中提供的函数中没有错误处理,所以@Niet只是模仿了最初的行为如果由于输入无效而要抛出异常,则应抛出一个。@Arjan这是真的,OPs函数中缺少错误处理,但问题确实明确规定了函数应工作的条件:“对于给定的整数Z…”。至于例外情况,我将更新答案以包含您的建议。嗯,我倾向于不同意避免“像瘟疫一样”进行
ceil/floor int
比较。一般来说,是的,浮点不精确意味着与int进行比较是个坏主意。但是在这种情况下,
ceil/floor
返回一个整数(这恰好是浮点数形式,以减少将51位尾数剪裁为32位整数的风险),因此是精确的(除非整数无论如何都不能表示极高的数字)