Формула для поиска простых чисел в цикле

Мне нужно найти простые числа с помощью цикла 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) - person itsazzad; 01.02.2014
comment
В моих тестах это тоже немного медленно - не ожидал этого. :/ Получение простых чисел до 100 в 10 000 раз заняло почти 2 секунды в PHP 5.6. Хорошие ответы здесь с циклами for достигают этого за 200–400 мс. - 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() простого числа всегда является числом с плавающей запятой, которое можно использовать для ускорения процесса принятия решения при переборе большого количества чисел. - person keune; 14.09.2014
comment
@keune Это верно в примере с четным числом, но в этом случае функция не учитывает их. Однако вы правы; учитывая все цифры, это утверждение не стоит само по себе. - person dsimer; 22.01.2015

Я считаю, что это довольно эффективная процедура, которая перечисляет все простые числа до 1000.

Он проверяет каждое число ($x), чтобы увидеть, есть ли у него какие-либо делители (кроме самого себя и 1, конечно).

Математически нет необходимости проверять все меньшие числа как возможные факторы, только меньшие простые числа до квадратного корня из $x. Это достигается за счет хранения простых чисел по мере их нахождения в массиве (я думаю, что это стратегия, на которую ссылался ОП).

Как только первый простой множитель найден, мы знаем, что $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 и self в итерации. Он напечатает простые числа,

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
Хорошо, вы должны сделать это более ясно в следующий раз. Добро пожаловать в СО! - 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

Лучший способ проверить, является ли число простым, — посмотреть, делится ли оно на какое-либо простое число перед ним. Пи (х) — это тот, который я постоянно вижу повсюду... Вы можете увидеть немного больше информации о простом подсчете на википедия.

Итак, наиболее эффективный способ, который я могу придумать на данный момент, заключается в следующем:

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 - Фарки ответ, 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