このc ++コードは、次の素数を出力します。5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 61 71 71 79 79 83 89 97。
しかし、私はそれが私の本が書かれることを望んでいるとは思わない。数値の平方根について言及しています。そこで、2番目のループをfor (int j=2; j<sqrt(i); j++)
に変更してみましたが、必要な結果が得られませんでした。
このコードを私の本が望むように変更するにはどうすればよいですか?
int main ()
{
for (int i=2; i<100; i++)
for (int j=2; j<i; j++)
{
if (i % j == 0)
break;
else if (i == j+1)
cout << i << " ";
}
return 0;
}
素整数とは、正確に2つの異なる除数、つまり1と数値自体を持つものです。 100未満のすべての素数を見つけて出力するC++プログラムを作成、実行、およびテストします。(ヒント:1は素数です。2〜100の各数について、Remainder = Number%nを見つけます。nは2からの範囲です。 to sqrt(number)。nがsqrt(number)よりも大きい場合、その数はnで割り切れない。なぜ?剰余が0に等しい場合、その数は素数ではない。)
3つの方法:
1。
int main ()
{
for (int i=2; i<100; i++)
for (int j=2; j*j<=i; j++)
{
if (i % j == 0)
break;
else if (j+1 > sqrt(i)) {
cout << i << " ";
}
}
return 0;
}
2。
int main ()
{
for (int i=2; i<100; i++)
{
bool prime=true;
for (int j=2; j*j<=i; j++)
{
if (i % j == 0)
{
prime=false;
break;
}
}
if(prime) cout << i << " ";
}
return 0;
}
3。
#include <vector>
int main()
{
std::vector<int> primes;
primes.Push_back(2);
for(int i=3; i < 100; i++)
{
bool prime=true;
for(int j=0;j<primes.size() && primes[j]*primes[j] <= i;j++)
{
if(i % primes[j] == 0)
{
prime=false;
break;
}
}
if(prime)
{
primes.Push_back(i);
cout << i << " ";
}
}
return 0;
}
編集:3番目の例では、以前に計算されたすべての素数を追跡します。数が非素数で割り切れる場合、それもまた割り切れる素数<=その除数があります。これにより、primes_in_range/total_rangeの係数で計算が削減されます。
j
がequalとsqrt(i)
の場合、smallerである場合だけでなく、有効な要因である可能性もあります。
内部ループでsqrt(i)
まで繰り返し処理するには、次のように記述できます。
_for (int j=2; j*j<=i; j++)
_
(sqrt(i)
を使用する場合と比較すると、これには浮動小数点数への変換が不要という利点があります。)
数値に除数がある場合、そのうちの少なくとも1つは数値の平方根以下でなければなりません。除数をチェックするときは、テストする数までではなく、平方根までチェックするだけで済みます。
これは、2〜100の素数をリストするための私の非常に単純なc ++プログラムです。
for(int j=2;j<=100;++j)
{
int i=2;
for(;i<=j-1;i++)
{
if(j%i == 0)
break;
}
if(i==j && i != 2)
cout<<j<<endl;
}
実際、より良い解決策は、「素数を見つけるためのアルゴリズムの高速タイプである」「素数ふるいまたは素数ふるい」を使用することです。
単純な(ただし高速ではない)アルゴリズムは「serof eratosthenes」と呼ばれ、次の手順で実行できます(Wikipediaから):
- 2からnまでの連続した整数のリストを作成します:(2、3、4、...、n)。
- 最初に、pを2(最初の素数)に等しくします。
- Pから始めて、pの増分でカウントアップし、これらの各数値をリスト内のp自体より大きくマークします。これらの番号は2p、3p、4pなどです。それらのいくつかは既にマークされている可能性があることに注意してください。
- リスト内でマークされていないpより大きい最初の番号を見つけます。そのような番号がなかった場合、停止します。そうでない場合は、pをこの数(次の素数)に等しくし、手順3から繰り返します。
Ser of Eratosthenes logicを使用すると、はるかに高速な速度で同じ結果を達成できます。
count
を比較すると、私のコードはジョブを完了するまでの反復回数が大幅に少なくなります。最後に、さまざまなN
値の結果をチェックアウトします。
このコードがすでに受け入れられているものよりも優れている理由:
-プロセス全体で偶数は一度もチェックされません。
-内側と外側の両方のループは、可能な制限内でのみチェックしています。余分なチェックはありません。
コード:
int N = 1000; //Print primes number from 1 to N
vector<bool> primes(N, true);
for(int i = 3; i*i < N; i += 2){ //Jump of 2
for(int j = 3; j*i < N; j+=2){ //Again, jump of 2
primes[j*i] = false;
}
}
if(N >= 2) cout << "2 ";
for(int i = 3; i < N; i+=2){ //Again, jump of 2
if(primes[i] == true) cout << i << " ";
}
ために N = 1000
、私のコードには1166回の反復が、受け入れられた答えには5287の時間がかかります(4.5倍遅い)
ために N = 10000
、私のコードは14637回の反復を要し、受け入れられた回答は117526を要します(8倍遅い)
ために N = 100000
、私のコードは175491回の反復を要し、受け入れられた回答は2745693(15.6倍遅い)を要します
100までの素数を見つけることは特に素晴らしく簡単です:
printf("2 3 "); // first two primes are 2 and 3
int m5 = 25, m7 = 49, i = 5, d = 4;
for( ; i < 25; i += (d=6-d) )
{
printf("%d ", i); // all 6-coprimes below 5*5 are prime
}
for( ; i < 49; i += (d=6-d) )
{
if( i != m5) printf("%d ", i);
if( m5 <= i ) m5 += 10; // no multiples of 5 below 7*7 allowed!
}
for( ; i < 100; i += (d=6-d) ) // from 49 to 100,
{
if( i != m5 && i != m7) printf("%d ", i);
if( m5 <= i ) m5 += 10; // sieve by multiples of 5,
if( m7 <= i ) m7 += 14; // and 7, too
}
100の平方根は10なので、このレンディションは- エラトステネスのふるい と 2-3ホイール は上記の素数の倍数を使用します310より大きくない-viz。 5および7のみ! -6-coprimes100を段階的にふるいにかける。
Forループをfor (int j=2; j<=sqrt(i); j++)
に変更するのは問題ありませんが、それから何か他のものを変更する必要もあります。印刷条件を具体的に見ると、
_else if (i == j+1) {
cout << i << " ";
}
_
sqrt(i)
まで反復するだけで、なぜトリガーされないのですか?これを変更するためにcout
をどこに移動できますか? (ヒント:印刷をループ外に移動してから、何らかのタイプのフラグ変数を使用することもできます)
次のコードで数値が素数であるかどうかを確認します(もちろんsqrtを使用):
bool IsPrime(const unsigned int x)
{
const unsigned int TOP
= static_cast<int>(
std::sqrt( static_cast<double>( x ) )
) + 1;
for ( int i=2; i != TOP; ++i )
{
if (x % i == 0) return false;
}
return true;
}
このメソッドを使用して素数を決定します。
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
#include <cmath>
void initialize( unsigned int *, const unsigned int );
void show_list( const unsigned int *, const unsigned int );
void criba( unsigned int *, const unsigned int );
void setItem ( unsigned int *, const unsigned int, const unsigned int );
bool IsPrime(const unsigned int x)
{
const unsigned int TOP
= static_cast<int>(
std::sqrt( static_cast<double>( x ) )
) + 1;
for ( int i=2; i != TOP; ++i )
{
if (x % i == 0) return false;
}
return true;
}
int main()
{
unsigned int *l;
unsigned int n;
cout << "Ingrese tope de criba" << endl;
cin >> n;
l = new unsigned int[n];
initialize( l, n );
cout << "Esta es la lista" << endl;
show_list( l, n );
criba( l, n );
cout << "Estos son los primos" << endl;
show_list( l, n );
}
void initialize( unsigned int *l, const unsigned int n)
{
for( int i = 0; i < n - 1; i++ )
*( l + i ) = i + 2;
}
void show_list( const unsigned int *l, const unsigned int n)
{
for( int i = 0; i < n - 1; i++ )
{
if( *( l + i ) != 0)
cout << l[i] << " - ";
}
cout << endl;
}
void setItem( unsigned int *l, const unsigned int n, const unsigned int p)
{
unsigned int i = 2;
while( p * i <= n)
{
*( l + (i * p - 2) ) = 0;
i++;
}
}
void criba( unsigned int *l, const unsigned int n)
{
for( int i = 0; i * i <= n ; i++ )
if( IsPrime ( *( l + i) ) )
setItem( l, n, *(l + i) );
}
これは、指定された数nまでのすべての素数を印刷するための簡単なコードです。
#include<iostream.h>
#include<conio.h>
void main()
{
clrscr();
int n,i,j,k;
cout<<"Enter n\n";
cin>>n;
for(i=1;i<=n;i++)
{ k=0;
for(j=1;j<=i;j++)
{
if((i%j)==0)
k++;
}
if(k==2)
cout<<i<<endl;
}
getch();
}
私は常にこれを使用します(簡単で高速です):
#include <iostream>
using namespace std;
int i,j;
bool b[101];
int main( )
{
for(i=2;i<101;i++){
b[i]=true;
}
for(i=1;i<101;i++){
if(b[i]){
cout<<i<<" ";
for(j=i*2;j<101;j+=i) b[j]=false;
}
}
}
このコードの出力は次のとおりです。2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
この本は、Gary Bronsonが書いた「エンジニアと科学者向けのC++」(グーグルで検索)のようです。
これは可能な答えですか?私見それは驚くべきことです。
質問を(本から)数回読む必要がありました。私の解釈:
Foreachnumber N:2 <= N <100素数かどうかを確認します。
どうやって? Foreach除数D:2 <= D <sqrt(N)、
DがNを除算する場合、Nは素数ではありません。D> sqrt(N)の場合、Nは素数です。
試してみてください:
N = 2, sqrt(2) ≈ 1.41, D = 2, 2 < 1.41 ? no 2 > 1.41 ? yes 2 is prime.
N = 3, sqrt(3) ≈ 1.73, D = 2, 2 < 1.73 ? no 2 > 1.73 ? yes 3 is prime.
N = 4, sqrt(4) = 2.00, D = 2, 2 < 2.00 ? no 2 > 2.00 ? no 4 is not prime.
N = 5, sqrt(5) ≈ 2.24, D = 2, 2 < 2.24 ? yes 5 % 2 > 0? yes
D = 3, 3 < 2.24 ? no 3 > 2.24 ? yes 5 is prime.
N = 6, sqrt(6) ≈ 2.45, D = 2, 2 < 2.45 ? yes 6 % 2 = 0 2 > 2.45 ? no 6 is not prime.
私が見る限り、それは素数を見つける方法です、
ふるいを使わずに(ずっと、ずっと速く)、
ただし:答えは質問にあります!驚くべき?
速度? Primes <400,000:10秒未満(私の時計、ロレックスで、私は市場でそれを買いました、売り手はそれが本物で、2本のバゲットの価格で本物のもので、12本の本物のダイヤモンドもありました)。
素数を数えてみましょう(コードは表示しません;):664579素数<10,000,000:5秒。
#include "stdafx.h"
#include <math.h>
#include <iostream>
using namespace std;
int main()
{
double rt;
for (int d = 2, n = 2; n < 100; d = 2, n++)
{
for (rt = sqrt(n); d < rt; d++)
if (n % d == 0) break;
if (d > rt) cout << n << " ";
}
getchar(); // 25 primes :-)
}
(他の回答と同様に)プライムシーブのある以前の回答を削除しました。
次の「ネクロマンサー」バッジがもうすぐ届きますように。
著者に次のように尋ねました。あなたの本では、「C++ for E&S」は素数に関する演習です。[xrcs] ... [/ xrcs]。 7年前、SO/q/5200879で質問されました。
数日前に答えました:SO/a/49199435
それは合理的な解決策、またはおそらく解決策だと思いますか。
彼は答えました:ピーター、私が演習を構成しているとき、私は本当に具体的な解決策を心に抱いていません。
したがって、正確な解決策を考えていたとは言えません。 C++の喜びは、本当に創造的なソリューションと優れたコードを思いつくことができるということです。
送信していただきありがとうございます!
博士。ブロンソン
https://youtu.be/1175axY2Vvw に行きました
PS。ふるい: https://Pastebin.com/JMdTxbeJ
いいえかどうかを確認します。素数かC++でないか:
#include<iostream>
#include<cmath>
using namespace std;
int main(){
int n, counter=0;
cout <<"Enter a number to check whether it is prime or not \n";
cin>>n;
for(int i=2; i<=n-1;i++) {
if (n%i==0) {
cout<<n<<" is NOT a prime number \n";
break;
}
counter++;
}
//cout<<"Value n is "<<n<<endl;
//cout << "number of times counter run is "<<counter << endl;
if (counter == n-2)
cout << n<< " is prime \n";
return 0;
}
「N」個の素数を出力する簡単なプログラム。 N値を100として使用できます。
#include <iostream >
using namespace std;
int main()
{
int N;
cin >> N;
for (int i = 2; N > 0; ++i)
{
bool isPrime = true ;
for (int j = 2; j < i; ++j)
{
if (i % j == 0)
{
isPrime = false ;
break ;
}
}
if (isPrime)
{
--N;
cout << i << "\n";
}
}
return 0;
}
#include<iostream>
using namespace std;
void main()
{
int num,i,j,prime;
cout<<"Enter the upper limit :";
cin>>num;
cout<<"Prime numbers till "<<num<<" are :2, ";
for(i=3;i<=num;i++)
{
prime=1;
for(j=2;j<i;j++)
{
if(i%j==0)
{
prime=0;
break;
}
}
if(prime==1)
cout<<i<<", ";
}
}
これは簡単なブログからの私のアプローチです:
//Prime Numbers generation in C++
//Using for loops and conditional structures
#include <iostream>
using namespace std;
int main()
{
int a = 2; //start from 2
long long int b = 1000; //ends at 1000
for (int i = a; i <= b; i++)
{
for (int j = 2; j <= i; j++)
{
if (!(i%j)&&(i!=j)) //Condition for not prime
{
break;
}
if (j==i) //condition for Prime Numbers
{
cout << i << endl;
}
}
}
}
-詳細は次を参照してください: http://www.programmingtunes.com/generation-of-prime-numbers-c/#sthash.YoWHqYcm.dpuf
#include "stdafx.h"
#include<iostream>
using namespace std;
void main()
{ int f =0;
for(int i=2;i<=100;i++)
{
f=0;
for(int j=2;j<=i/2;j++)
{
if(i%j==0)
{ f=1;
break;
}
}
if (f==0)
cout<<i<<" ";
}
system("pause");
}
エラトステネスのふるいの実装は次のとおりです(2とnの間の素数用)
#include <iostream>
int main (){
int n=0;
std::cout << "n = ";
std::cin >> n;
std::cout << std::endl;
if (n==0 || n==1){
std::cout << "No primes in this range" << std::endl;
return 0;
}
const int array_len = n-2+1;
int the_int_array[array_len];
for (int counter=2; counter <=n; counter++)
the_int_array[counter-2]=counter;
int runner = 0;
int new_runner = 0;
while (runner < array_len ){
if (the_int_array[runner]!=0){
new_runner = runner;
new_runner = new_runner + the_int_array[runner];
while (new_runner < array_len){
the_int_array[new_runner] = 0;
new_runner = (new_runner + the_int_array[runner]);
}
}
runner++;
}
runner = 0;
while (runner < array_len ){
if (the_int_array[runner]!=0)
std::cout << the_int_array[runner] << " ";
runner++;
}
std::cout << std::endl;
return 0;
}
分割可能性の素数のルールを使用すると、O(n)で見つけることができ、それは本当に効率的です Rules of Divisibility
解決策は、数字の個々の数字に基づいています...
ProdigySimの2番目の方法による最も人気のある回答に基づいて、Perlでそれを行いました。素数を2回出力するのを避けるために、print $i . " \n";
の直後にPerlでbreak
に相当するlast
を追加する必要がありました。
#!/bin/Perl
use strict;
for(my $i=2; $i < 100; $i++){
my $prime = 1;
for (my $j=2; $j*$j<=$i; $j++){
if ($i % $j == 0){
$prime = 0;
last;
}
if($prime) {
print $i . " \n";
last;
}
}
}