Формула за намиране на прости числа в цикъл

Трябва да намеря прости числа с цикъл for или while

Написах това, но това е грешно

<?php
$i = 1;
while($i<5)
{
    for($j=1; $j<=$i; $j++)
    {
        if ($j != 1 && $j != $i)
        {
            echo $i . "/" . $j . "=" . $i%$j . "<br />";
            if ($i%$j != 0)
            {
                echo $i . "<br />";
            }
        }
    }
    echo "<br />";
    $i += 1;
}
?>

Има ли начин да се раздели число с масив, за да се намери оставащото?


person Mohammad Masoudian    schedule 26.05.2013    source източник


Отговори (17)


Ето една малка функция, която намерих: (http://icdif.com/computing/2011/09/15/check-number-prime-number/) Изглежда, че работи за мен!

function isPrime($num) {
    //1 is not prime. See: http://en.wikipedia.org/wiki/Prime_number#Primality_of_one
    if($num == 1)
        return false;

    //2 is prime (the only even number that is prime)
    if($num == 2)
        return true;

    /**
     * if the number is divisible by two, then it's not prime and it's no longer
     * needed to check other even numbers
     */
    if($num % 2 == 0) {
        return false;
    }

    /**
     * Checks the odd numbers. If any of them is a factor, then it returns false.
     * The sqrt can be an aproximation, hence just for the sake of
     * security, one rounds it to the next highest integer value.
     */
    $ceil = ceil(sqrt($num));
    for($i = 3; $i <= $ceil; $i = $i + 2) {
        if($num % $i == 0)
            return false;
    }

    return true;
}
person Farkie    schedule 26.05.2013
comment
Изисква ли се получаването на тавана на корен квадратен или подът е достатъчен? Имам проблеми с измислянето на число, което би се делило на тавана на числото с квадратен корен - person Curtis W; 22.04.2014
comment
... $sqrt = ceil(sqrt($num)); ... ако изчислите sqrt извън for цикъла, това ще ускори нещата с ~400%, особено когато проверявате много големи числа - person nimmneun; 24.12.2015
comment
Здравей @Farkie, опита ли го? neun@mono:~$ php test.php float(7.9089679718018) neun@mono:~$ php test2.php float(2.5886662006378) ` - person nimmneun; 07.02.2016
comment
Може да се запише и като: for($i = 3; $i <= $ceil; $i += 2) { - person Oliver Tappin; 28.12.2016
comment
Има ли смисъл да се проверява /9, когато числото не /3? Искам да кажа, че няма смисъл от $num % $i, където $i не е самото просто число. - person iXCray; 12.08.2017

Можете да използвате тази PHP функция gmp_nextprime()

person happy    schedule 26.05.2013
comment
Въпреки че не винаги е наличен :/ - person fejese; 27.05.2013
comment
Имате нужда от инсталиране на GNU Multiple Precision (GMP) Mathematical Extension - person itsazzad; 01.02.2014
comment
В моите тестове също е доста бавен - не очаквах това. :/ Получаването на простите числа до 100, 10 000 пъти, отне почти 2 секунди под PHP 5.6. Добрите отговори тук с for-цикли постигат това за 200 - 400 ms. - person Dennis98; 30.10.2018

Ето един ред, който намерих преди време, за да проверя за прости числа. Той използва отметки (унарна математика), за да определи:

function is_prime_via_preg_expanded($number) {
    return !preg_match('/^1?$|^(11+?)\1+$/x', str_repeat('1', $number));
}

Проверете всички числа последователно за прости числа:

$i=2; // start here (2 is the first prime)
while (1) { // neverending loop
    if (is_prime_via_preg_expanded($i)) echo $i." <br />\n";
    $i++;
}

За да проверите само диапазон от числа за прости числа, като в предоставения пример:

$start = 2; // start here (2 is the first prime)
$end = 100;

$i=$start;
while ($i<=$end) {
    if (is_prime_via_preg_expanded($i)) echo $i." <br />\n";
    $i++;
}
person Jeff Clayton    schedule 15.07.2014
comment
Това е проклет СТРАХОТЕН Джеф! - person pim; 04.06.2015
comment
Този е страхотен за еднократни проверки. Но тази функция е много по-бавна от предоставените алтернативи, използващи цикли. - person Julius Š.; 01.07.2017
comment
Никога не съм правил сравнения, така че е много възможно. Това е по-скоро за интерес, че е кратък едноредов с доста уникален метод за решаване на проблема. - person Jeff Clayton; 03.04.2020

Това е основно изпълнение:

function prima($n){

  for($i=1;$i<=$n;$i++){  //numbers to be checked as prime

          $counter = 0; 
          for($j=1;$j<=$i;$j++){ //all divisible factors


                if($i % $j==0){ 

                      $counter++;
                }
          }

        //prime requires 2 rules ( divisible by 1 and divisible by itself)
        if($counter==2){

               print $i." is Prime <br/>";
        }
    }
} 

prima(20);  //find prime numbers from 1-20

Това ще изведе

 2 is Prime 
 3 is Prime 
 5 is Prime 
 7 is Prime 
 11 is Prime 
 13 is Prime 
 17 is Prime 
 19 is Prime 

Пълна логика стъпка по стъпка и визуална аналогия тук: Тук

person ngakak    schedule 07.04.2014

Без математическа функция:

function isPrimeNumber($i) {
    $n = 2;
    while ($n < $i) {
        if ($i % $n) {
            $n++;
            continue;
        }

        return false;
    }

    return true;
}
person ghaliano    schedule 30.01.2015

Знам, че е твърде късно, но открих, че това решение е по-елегантно.

function isPrime($num)
{
    if ($num < 2) {
        return false;
    }
    for ($i = 2; $i <= $num / 2; $i++) {
        if ($num % $i == 0) {
            return false;
        }
    }

    return true;
}
person Nik Latkin    schedule 17.10.2016
comment
Най-добрият отговор, най-простото решение. - person Thomas; 17.09.2018
comment
Всъщност използвайки $i ‹= $num / 3; може да ускори това особено за големи числа, но никога няма да се конкурира с gmp_nextprime(), който ми предостави 664579 прости числа за 39 секунди :) - person Jack; 27.01.2019

Всичко, което е sqrt(), е невярно или която и да е стойност с плаваща единица е просто число

person Nikba    schedule 14.05.2014
comment
това не е точно така. помислете за 6, чието sqrt() е плаващо число, но самото то не е просто число. трябва да бъде; sqrt() на просто число винаги е float, което можете да използвате, за да ускорите процеса на вземане на решение, когато преминавате през много числа. - person keune; 14.09.2014
comment
@keune Това е вярно в примера за четно число, но функцията не ги взема предвид в този случай. Прав си обаче; като се вземат предвид всички числа, това твърдение не стои само по себе си. - person dsimer; 22.01.2015

Вярвам, че това е доста ефективна процедура, която изброява всички прости числа до 1000.

Той тества всяко число ($x), за да види дали има някакви фактори (освен себе си и 1, разбира се).

Математически не е необходимо да се тестват всички по-малки числа като възможни множители, а само по-ниски прости числа до корен квадратен от $x. Това е активирано чрез съхраняване на прости числа, както се намират в масив (което според мен е стратегията, за която OP се отнася).

Веднага щом бъде намерен първият прост множител, ние знаем, че $x не е прост, така че не е необходимо допълнително тестване на тази стойност на $x и можем да излезем от цикъла foreach.

$primes = array();
for ($x = 2; $x <= 1000; $x++) {
    $xIsPrime = TRUE;
    $sqrtX = sqrt($x);
    foreach ($primes as $prime) if ($prime > $sqrtX || ((!($x % $prime)) && (!$xIsPrime = FALSE))) break;
    if ($xIsPrime) echo ($primes[] = $x)  . "<br>";
}
person WebSmithery    schedule 26.10.2013

Sieve_of_Eratosthenes е прост и по-бърз алгоритъм за намиране на прости числа.

function getPrimes($finish)
    {
        $number = 2;
        $range = range($number,$finish);
        $primes = array_combine($range,$range);
        while($number*$number < $finish){
            for($i=$number; $i<=$finish; $i+=$number){
                if($i==$number){
                    continue;
                }
                unset($primes[$i]);
            }
            $number = next($primes);
        }
        return $primes;
    }
person mocak    schedule 25.07.2014
comment
getPrimes(25) връща 25 като просто число, същото за getPrimes(49) и 49. Изглежда, че се случва само когато крайната точка е квадратно число, но не за всички. - person DevFox; 22.09.2016
comment
Браво, един от най-бързите отговори тук! :) - person Dennis98; 30.10.2018

<?php

    $n = 11;
    $o = $_POST["maxprime"];
    echo 'The script calculated the next primenumbers:</br>';
    echo '2, 3, 5, 7, ';
    while (true) { 
        $t = 6;
        while (true) { 
            if ($n % ($t - 1) == 0) {
                break;
            } 
            if ($n % ($t + 1) == 0) {
                break;
            }
            if ($t > sqrt($n)) {
                echo("$n,  "); 
                break;
            } 
            $t += 6; 
        }
        if (($n + 1) % 6 == 0) {
            $n += 2;
        } else {
            $n += 4;
        } 
        if ($n > $o) {
            break;
        }
    }

?>

http://www.primenumbergenerator.com/

person Community    schedule 30.11.2016

Програмите по-долу са прости с два цикъла for и игнорират 1 и собствените стойности при итерация. Той ще отпечата простите числа,

function get_primenumbers($length) {
    //Ignore 1
    for($i = 2; $i <= $length; $i++){
        $prime = true;
        for($j = 2; $j <= $i; $j++){
            //Ignore same number
            if(($i != $j) && ($i % $j == 0)){
                $prime = false;
                break;
            }
        }

        if(!$prime){
            echo "$i is not prime <br />";
        }else{
            echo "$i is prime <br />";
        }
    }
}
person Naveen    schedule 05.06.2019

Знам, че идва малко късно, но се надявам да помогне на някого.

    function prime_number_finder($range)
    {
        $total_count=0;//intitialize the range keeper

        $i=1;//initialize the numbers to check

        while ($total_count<=$range)
        {
           $count=0;//initialize prime number inner count
           $k=$i;
           while ($k!=0)
           {

             if(($i%$k)==0)
             {
              $count++;
             }
              $k--;
           }
           //condition to check if a number is prime 
          if($count==2 || $count==1)
           {
            echo $i."</br>";//output the prime number;
            $total_count++;
            $i++;

           }
           //number is not prime
           if($count>2)
           {
             //$total_count++;
            $i++;
           }

        }
    }

//пример prime_number_finder(200);

person lukkystunt    schedule 09.04.2014
comment
Бихте ли обяснили какъв е последният ред от отговора ви? //пример prime_number_finder(200); - person 2rs2ts; 09.04.2014
comment
prime_number_finder(200) е само пример за това как работи функцията, примерът получава първите 200 прости числа от естествените числа. - person lukkystunt; 09.04.2014
comment
Искате да кажете, че се опитвате да го извикате? - person 2rs2ts; 09.04.2014
comment
да...за извикване на функцията - person lukkystunt; 09.04.2014
comment
Добре, трябва да го направите по-ясно следващия път. Добре дошли в SO! - person 2rs2ts; 09.04.2014

Намерете прости числа между 1 и 10000, като използвате затваряне в array_filter():

$start = 2;
$step = 10000;

$stop = $start + $step;
$candidates = range($start, $stop);    
for($num = 2; $num <= sqrt($stop); ++$num){                        
    $candidates = array_filter($candidates,
        function ($v) use (&$num){
             return ($v % $num) != 0 || $v == $num ;
        }
    );
}
print_r($candidates);

Редактиране: 1 не е просто число

person user3396065    schedule 02.11.2015
comment
Хубаво, освен че дава 1 като просто число. - person DevFox; 24.08.2016
comment
Просто започнете от 2 вместо от 1, благодаря за докладването! - person user3396065; 24.08.2016

Най-добрият начин да проверите дали едно число е просто е да видите дали се дели на някое просто число преди него. Pi(x) е този, който продължавам да виждам навсякъде... Можете да видите малко повече информация за простото броене на wikipedia.

Така че най-ефективният начин, за който се сещам в момента, е следният:

class prime
{
    public $primes = [ 2, 3, 5, 7 ];
    public $not_prime = [ 1, 4, 6, 8, 9 ];
    public function is_prime( int $n )
    {
        if ( $n <= 1 ) return false;
        if ( in_array( $n, $this->primes ) ) return true;
        if ( in_array( $n, $this->not_prime ) ) return false;
        for( $i = 0; $i < count( array_slice( $this->primes, 0, $this->prime_count( $n ) ) ) || $i == $n; $i++ )
        {
            if ( $n % $this->primes[ $i ] == 0 ) return false;
        }
        return true;
    }
    public function build_primes_to( int $n )
    {
        for ( $i = end( $this->primes ) + 1; $i <= $n; $i++ )
        {
            if ( $this->is_prime( $i ) )
            {
                $this->primes[] = $i;
            }
            else
            {
                $this->not_prime[] = $i;
            }
        }
    }
    public function prime_count( $n )
    {
        $ln = log( $n );
        if ( $ln == 0 ) return 1;
        return intval( ceil( $n / $ln ) );
    }
}

Което всъщност не е много ефективно, добре, не и когато става дума за съставяне на списък с прости числа... Работя върху по-добър начин за съставяне на списъка тук, въпреки че би било също толкова лесно и много по-ефективно да намерите списък онлайн и да го използвате.

Използването на горното би било по следния начин:

$find_to = 1000;
$prime = new prime();
$prime->build_primes_to( $find_to );
print "<pre>";
for ( $i = 1; $i < $find_to; $i++ )
{
    print "$i is " . ( !$prime->is_prime( $i ) ? "not " : "" ) . "prime\n";
}
person Alexander Holman    schedule 12.10.2016

Знам, че това идва малко късно, но ето една проста програма, която да ви помогне да направите точно това, което искате...

<?php 
 //Prime Function
 function fn_prime($number) {
    $i = 2; $result = TRUE;
    while($i < $number) {
        if(!($number%$i)) {
            $result = FALSE;
        }
        $i++;
    }
    return $result;
 }

//Declare integer variable...
$k = 0;

//Start Loop up to any number of your choice for e.g. 200
while($k < 200) {
    if(fn_prime($k)) {
        echo "$k is a prime number<br/>";
    } else {
        echo "$k is not a prime number!<br/>";
    }
    $k++;
}

?>
person Chigozie Orunta    schedule 28.07.2017

Подобрена версия на отговора @Farkie, направена специално за проверка на прости числа в цикли.

function isPrime_v2($num) {
    static $knownPrimes=[3]; // array to save known primes

    if($num == 1)
        return false;

    if($num == 2 || $num == 3) //added '3'
        return true;

    if($num % 2 == 0)
        return false;

    $ceil = ceil(sqrt($num)); //same purpose, good point from Farkie

    // Check against known primes to shorten operations
    // There is no sense to check agains numbers in between
    foreach($knownPrimesas $prime){
        if ($prime>$ceil)
            break;
        if($num===$prime)
            return true;
        if($num % $prime == 0)
            return false;
    }


    /**
     * end($knownPrimes) % 2 !==0 - mathematically guaranteed
     * start with latest known prime
     */
    for($i = end($knownPrimes)+2; $i <= $ceil; $i = $i + 2) {
        if($num % $i == 0)
            return false;
    }
    $knownPrimes[]=$num;
    return true;
}

Бенчмарк с phpfiddle.org. V1 - Farkie отговор, V2 - Подобрена версия

V1 (1 to 5,000,000): divisions=330 929 171; primes=348 513; time=21.243s
V2 (1 to 5,000,000): divisions=114 291 299; primes=348 513; time=10.357s

ЗАБЕЛЕЖКА! Функцията isPrime_v2 е приложима САМО в случай на зацикляне от 3. В противен случай запазеният масив $knownPrimes няма да има достатъчно история.

person iXCray    schedule 11.08.2017
comment
В крайна сметка ще ви свърши паметта, ако стартирате това толкова голямо, но ще бъде по-бързо (кеширане) :) - person Farkie; 12.08.2017

Ето още един много прост, но тих ефективен подход:

function primes($n){

    $prime = range(2 , $n);

    foreach ($prime as $key => $value) {

        for ($i=2; $i < $value ; $i++) { 

            if (is_int($value / $i)) {

                unset($prime[$key]);
                break;
            }
        }
    }

    foreach ($prime as $value) {
        echo $value.'<br>';
    }
}

primes(1000);
person Rmy5    schedule 14.09.2017