私はこのトピックについて多くのコードを熟読しましたが、それらのほとんどは、入力数までの素数である数を生成します。しかし、与えられた入力数が素数かどうかをチェックするだけのコードが必要です。
これが私が書いたものですが、うまくいきません:
void primenumber(int number)
{
if(number%2!=0)
cout<<"Number is prime:"<<endl;
else
cout<<"number is NOt prime"<<endl;
}
誰かが私にこれを適切に機能させる方法についてアドバイスをいただければ幸いです。
Forループのすべての数値をチェックするように変更しました。
void primenumber(int number)
{
for(int i=1; i<number; i++)
{
if(number%i!=0)
cout<<"Number is prime:"<<endl;
else
cout<<"number is NOt prime"<<endl;
}
}
さらにチェックを行う必要があります。現時点では、数値が2で割り切れるかどうかを確認しているだけです。2、3、4、5、6、...、number
まで同じように実行します。ヒント:ループを使用します。
これを解決したら、最適化を探してみてください。ヒント:数値の平方根までのすべての数値をチェックするだけです
bool isPrime(int number){
if(number < 2) return false;
if(number == 2) return true;
if(number % 2 == 0) return false;
for(int i=3; (i*i)<=number; i+=2){
if(number % i == 0 ) return false;
}
return true;
}
私の独自のIsPrime()関数は、有名なRabin-Millerアルゴリズムの決定論的バリアントに基づいて作成され、最適化されたステップブルートフォーシングと組み合わせて、最速の素数テスト関数の1つを提供します。
__int64 power(int a, int n, int mod)
{
__int64 power=a,result=1;
while(n)
{
if(n&1)
result=(result*power)%mod;
power=(power*power)%mod;
n>>=1;
}
return result;
}
bool witness(int a, int n)
{
int t,u,i;
__int64 prev,curr;
u=n/2;
t=1;
while(!(u&1))
{
u/=2;
++t;
}
prev=power(a,u,n);
for(i=1;i<=t;++i)
{
curr=(prev*prev)%n;
if((curr==1)&&(prev!=1)&&(prev!=n-1))
return true;
prev=curr;
}
if(curr!=1)
return true;
return false;
}
inline bool IsPrime( int number )
{
if ( ( (!(number & 1)) && number != 2 ) || (number < 2) || (number % 3 == 0 && number != 3) )
return (false);
if(number<1373653)
{
for( int k = 1; 36*k*k-12*k < number;++k)
if ( (number % (6*k+1) == 0) || (number % (6*k-1) == 0) )
return (false);
return true;
}
if(number < 9080191)
{
if(witness(31,number)) return false;
if(witness(73,number)) return false;
return true;
}
if(witness(2,number)) return false;
if(witness(7,number)) return false;
if(witness(61,number)) return false;
return true;
/*WARNING: Algorithm deterministic only for numbers < 4,759,123,141 (unsigned int's max is 4294967296)
if n < 1,373,653, it is enough to test a = 2 and 3.
if n < 9,080,191, it is enough to test a = 31 and 73.
if n < 4,759,123,141, it is enough to test a = 2, 7, and 61.
if n < 2,152,302,898,747, it is enough to test a = 2, 3, 5, 7, and 11.
if n < 3,474,749,660,383, it is enough to test a = 2, 3, 5, 7, 11, and 13.
if n < 341,550,071,728,321, it is enough to test a = 2, 3, 5, 7, 11, 13, and 17.*/
}
使用するには、コードをコピーしてプログラムの上部に貼り付けます。それを呼び出すと、BOOL値(trueまたはfalse)が返されます。
if(IsPrime(number))
{
cout << "It's prime";
}
else
{
cout<<"It's composite";
}
「__int64」でのコンパイルで問題が発生した場合は、「long」に置き換えてください。 VS2008およびVS2010で正常にコンパイルされます。
仕組み:関数には3つの部分があります。パーツは、それがまれな例外(負の数、1)の1つであるかどうかを確認し、プログラムの実行をインターセプトします。
番号が1373653よりも小さい場合、パート2が始まります。これは、理論的には、Rabin Millerアルゴリズムが私の最適化されたブルートフォース機能を打ち負かす数です。次に、必要な目撃者の数を最小限に抑えるように設計された2つのレベルのRabin Millerがあります。テストする数値のほとんどは40億を下回るので、目撃者2、7、および61を確認することにより、確率論的ラビンミラーアルゴリズムを確定的にすることができます。40億を超える必要がある場合は、番号ライブラリを使用して、モジュラスまたはビットシフトの変更をpower()関数に適用します。
ブルートフォースメソッドを主張する場合、最適化されたブルートフォースIsPrime()関数を次に示します。
inline bool IsPrime( int number )
{
if ( ( (!(number & 1)) && number != 2 ) || (number < 2) || (number % 3 == 0 && number != 3) )
return (false);
for( int k = 1; 36*k*k-12*k < number;++k)
if ( (number % (6*k+1) == 0) || (number % (6*k-1) == 0) )
return (false);
return true;
}
}
このブルートフォースピースの仕組み:すべての素数(2と3を除く)は、6k + 1または6k-1の形式で表現できます。ここで、kは正の整数です。このコードはこの事実を使用して、問題の数値の平方根よりも小さい6k + 1または6k-1の形式ですべての数値をテストします。この部分は、大きなIsPrime()関数(最初に示されている関数)に統合されています。
数値の下にあるすべての素数を見つける必要がある場合は、1000未満のすべての素数を見つけて、エラトステネスのふるいを調べてください。私のもう1つのお気に入り。
追加の注記として、誰もが楕円曲線法アルゴリズムを実装するのを見たいと思っています。しばらくの間C++で実装されたアルゴリズムを見たいと思っていたので、実装を失いました。理論的には、私が実装した確定的なRabin Millerアルゴリズムよりもさらに高速ですが、40億未満の数値に当てはまるかどうかはわかりません。
If(input%number!= 0)がfalseを返す場合、sqrtを取得してforeachを2からsqrt + 1に実行すると思います。 sqrt + 1に達したら、その素数を確認できます。
C++
bool isPrime(int number){
if (number != 2){
if (number < 2 || number % 2 == 0) {
return false;
}
for(int i=3; (i*i)<=number; i+=2){
if(number % i == 0 ){
return false;
}
}
}
return true;
}
Javascript
function isPrime(number)
{
if (number !== 2) {
if (number < 2 || number % 2 === 0) {
return false;
}
for (var i=3; (i*i)<=number; i+=2)
{
if (number % 2 === 0){
return false;
}
}
}
return true;
}
Python
def isPrime(number):
if (number != 2):
if (number < 2 or number % 2 == 0):
return False
i = 3
while (i*i) <= number:
if(number % i == 0 ):
return False;
i += 2
return True;
入力の範囲がわかっている場合(関数はint
を取るため、これを行います)、最大入力の平方根(2 ^ 31-1)以下の素数のテーブルを事前計算できます。この場合)、次に、与えられた数の平方根以下の表の各素数による分割可能性をテストします。
bool check_prime(int num) {
for (int i = num - 1; i > 1; i--) {
if ((num % i) == 0)
return false;
}
return true;
}
素数かどうかを調べます
同じアルゴリズムですが、ステップ2が奇数であるsqrt(n)にループする別の実装に従います。これは、2または2 * kで割り切れるかどうかを確認するためです。これが私のコードです
public class PrimeTest {
public static boolean isPrime(int i) {
if (i < 2) {
return false;
} else if (i % 2 == 0 && i != 2) {
return false;
} else {
for (int j = 3; j <= Math.sqrt(i); j = j + 2) {
if (i % j == 0) {
return false;
}
}
return true;
}
}
/**
* @param args
*/
public static void main(String[] args) {
for (int i = 1; i < 100; i++) {
if (isPrime(i)) {
System.out.println(i);
}
}
}
}
怠惰で大量のRAMがある場合は、 Eratosthenesのふるい を作成します。これは、素数ではないすべての数値をキックするための実質的に巨大な配列です。それ以降、すべての素数の「確率」テストは非常に速くなります。高速な結果を得るためのこのソリューションの上限は、RAMの量です。超低速の結果に対するこのソリューションの上限は、ハードディスクの容量です。
数学を使用して、最初に数値の平方根を見つけてから、平方根の後に得られる数値が終了するまでループを開始します。各値について、指定された数値が繰り返し値で割り切れるかどうかを確認します。指定された数値を除算する値がある場合、それは素数ではなく、素数です。これがコードです
bool is_Prime(int n)
{
int square_root = sqrt(n); // use math.h
int toggle = 1;
for(int i = 2; i <= square_root; i++)
{
if(n%i==0)
{
toggle = 0;
break;
}
}
if(toggle)
return true;
else
return false;
}
このコードは、数値が2で割り切れるかどうかをチェックするだけです。数が素数になるためには、それよりも小さいすべての整数で割り切れる必要があります。これは、ループ内でfloor(sqrt(n))
未満のすべての整数で割り切れるかどうかをチェックすることにより、簡単に実装できます。興味がある場合は、多数の はるかに高速なアルゴリズム が存在します。
上記の誰かが以下を持っています。
bool check_prime(int num) {
for (int i = num - 1; i > 1; i--) {
if ((num % i) == 0)
return false;
}
return true;
}
これはほとんど機能しました。私はVisual Studio 2017でそれをテストしました。2未満も素数でした(つまり、1、0、-1など)。
これを修正するためのわずかな変更を次に示します。
bool check_prime(int number)
{
if (number > 1)
{
for (int i = number - 1; i > 1; i--)
{
if ((number % i) == 0)
return false;
}
return true;
}
return false;
}
これはすばやく効率的なものです。
bool isPrimeNumber(int n) {
int divider = 2;
while (n % divider != 0) {
divider++;
}
if (n == divider) {
return true;
}
else {
return false;
}
}
2から始まるnの割り切れる数の検索を開始します。1が見つかるとすぐに、その数がnと等しい場合はそれは素数であり、そうでない場合はそうではありません。
番号が素数かそうでないかを見つけるためにこのアイデアを使用しました:
#include <conio.h>
#include <iostream>
using namespace std;
int main() {
int x, a;
cout << "Enter The No. :";
cin >> x;
int prime(unsigned int);
a = prime(x);
if (a == 1)
cout << "It Is A Prime No." << endl;
else
if (a == 0)
cout << "It Is Composite No." << endl;
getch();
}
int prime(unsigned int x) {
if (x == 1) {
cout << "It Is Neither Prime Nor Composite";
return 2;
}
if (x == 2 || x == 3 || x == 5 || x == 7)
return 1;
if (x % 2 != 0 && x % 3 != 0 && x % 5 != 0 && x % 7 != 0)
return 1;
else
return 0;
}
Nが2の場合、素数です。
Nが1の場合、素数ではありません。
Nが偶数の場合、素数ではありません。
Nが2より大きい奇数の場合、すべての奇数3..sqrt(n)+1をチェックする必要があります。この数値のいずれかがnを除算できる場合、nは素数でなければ、nは素数です。
より良いパフォーマンスのために私はエラトステネスのふるいをお勧めします。
次にコードサンプルを示します。
bool is_prime(int n) { if (n == 2) return true; if (n == 1 || n % 2 == 0) return false; for (int i = 3; i*i < n+1; i += 2) { if (n % i == 0) return false; } return true; }
私はこれを思いつきました:
int counter = 0;
bool checkPrime(int x) {
for (int y = x; y > 0; y--){
if (x%y == 0) {
counter++;
}
}
if (counter == 2) {
counter = 0; //resets counter for next input
return true; //if its only divisible by two numbers (itself and one) its a prime
}
else counter = 0;
return false;
}
//simple function to determine if a number is a prime number
//to state if it is a prime number
#include <iostream>
using namespace std;
int isPrime(int x); //functioned defined after int main()
int main()
{
int y;
cout<<"enter value"<<endl;
cin>>y;
isPrime(y);
return 0;
} //end of main function
//-------------function
int isPrime(int x)
{
int counter =0;
cout<<"factors of "<<x<<" are "<<"\n\n"; //print factors of the number
for (int i =0; i<=x; i++)
{
for (int j =0; j<=x; j++)
{
if (i * j == x) //check if the number has multiples;
{
cout<<i<<" , "; //output provided for the reader to see the
// muliples
++counter; //counts the number of factors
}
}
}
cout<<"\n\n";
if(counter>2)
{
cout<<"value is not a prime number"<<"\n\n";
}
if(counter<=2)
{
cout<<"value is a prime number"<<endl;
}
}
この問題にはいくつかの異なるアプローチがあります。
「単純」な方法:数(の根)までのすべての(奇数)数を試します。
「ナイーブ」メソッドの改善:6n±1ごとにのみ試行してください.
確率的テスト:Miller-Rabin、Solovay-Strasseなど.
どのアプローチがあなたに適しているか、そしてあなたが素数で何をしているのかによって異なります。
少なくとも Primality Testing を読んでください。
// PrimeDef.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<iostream>
#include<stdlib.h>
using namespace std;
const char PRIME = 176;
const char NO_PRIME = 178;
const int LAST_VALUE = 2000;
bool isPrimeNumber( int value )
{
if( !( value / 2 ) ) return false;
for( int i = 1; ++i <= value / 2; )
if( 0 == value % i ) return false;
return true;
}
int main( int argc, char *argv[ ] )
{
char mark;
for( int i = -1, count = 1; ++i < LAST_VALUE; count++ )
{
mark = NO_PRIME;
if( isPrimeNumber( i ) ) mark = PRIME;
cout << mark;
if(i > 0 && !( count % 50 ) ) cout << endl;
}
return 0;
}