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;
}
?>
数を配列で除算して残りを見つける方法はありますか?
ここに私が見つけた小さな機能があります:( 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;
}
これを使用できますPHP function gmp_nextprime()
これは基本的な実装です。
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
完全なロジックのステップバイステップと視覚的アナロジーをここに: Here
素数をチェックするためにしばらく前に見つけたワンライナーです。タリーマーク(単項計算)を使用して以下を決定します。
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++;
}
遅すぎることはわかっていますが、このソリューションの方がよりエレガントであることがわかりました。
function isPrime($num)
{
if ($num < 2) {
return false;
}
for ($i = 2; $i <= $num / 2; $i++) {
if ($num % $i == 0) {
return false;
}
}
return true;
}
数学関数なし:
function isPrimeNumber($i) {
$n = 2;
while ($n < $i) {
if ($i % $n) {
$n++;
continue;
}
return false;
}
return true;
}
Sqrt()がfalseであるか、float値が素数である
以下のプログラムは、forループが2つあるシンプルなもので、反復では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 />";
}
}
}
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;
}
これは、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>";
}
<?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;
}
}
?>
<?php
$limit=100;
$i=1;
outer:while($i<=$limit){
$j=2;
while($j<$i){
if($i%$j==0){
$i++;
goto outer;
}
$j++;
}
echo $i;
echo "<br/>";
$i++;
}
?>
もう1つの非常にシンプルで静かな効果的なアプローチを次に示します。
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);
数が素数であるかどうかを確認する最良の方法は、その前の素数で割り切れるかどうかを確認することです。 Pi(x)は、私がどこでも見続けるものです... wikipedia で、Prime Countingについてもう少し情報を見ることができます。
そのため、現時点で考えられる最も効率的な方法は次のとおりです。
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 ) );
}
}
これは実際にはあまり効率的ではありません、素数のリストを作成する場合ではなく...リストを作成するより良い方法に取り組んでいます here リストをオンラインで検索して使用するのと同じくらい簡単ではるかに効率的です。
上記の使用法は次のようなものになります。
$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";
}
$n = 7;
if ($n == 1) {
echo 'Not a Prime or Composite No.';
}
$set = 0;
for ($index = 2; $index <= $n/2; $index++) {
if ($n % $index === 0) {
$set = 1;
break;
}
}
if ($set) {
echo 'Composite';
} else {
echo 'Prime';
}
<?php
function prime_number($num){
for( $j = 2; $j <= $num; $j++ )
{
for( $k = 2; $k < $j; $k++ )
{
if( $j % $k == 0 )
{
break;
}
}
if( $k == $j )
echo "Prime Number : ".$j."<br>";
}
}
prime_number(23);
?>
Array_filter()のクロージャを使用して、1〜10000の間の素数を見つけます。
$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は素数ではありません
私はこれが少し遅れていることを知っていますが、あなたが求めていることだけを行うのを助ける簡単なプログラムがあります...
<?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++;
}
?>
私はこれが少し遅れていることを知っていますが、それが誰かを助けることを願っています。
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)の例;
特にループ内の素数をチェックするために作成された@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配列の履歴が不十分になります。