質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

947閲覧

C言語の高速化処理について

shun011

総合スコア11

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2019/06/12 06:56

編集2019/06/12 07:00

前提・実現したいこと

C言語を用いて、1〜10万までの数字の中から素数を見つけ出し、表示するプログラムを作りたくてググったところ、2つのソースコードが見つかりました。

発生している問題・エラーメッセージ

実行速度が全然違ったので、どうしてこんなに変わるのか教えてください!
初心者なので、出来るだけわかりやすく教えていただけると幸いです。

該当のソースコード

C

1#include <stdio.h> 2 3int main(void) 4{ 5 int i,j,k; 6 int c=0; 7 8 for(i=1;i<=100000;i++) { 9 k=0; 10 for(j=1;j<=i;j++) 11 { 12 if(i%j==0) k++; 13 } 14 15 if(k==2) { 16 printf("%d ",i); 17 ++c; 18 } 19} 20 21 printf("\n"); 22 23 printf("個数: %d\n",c); 24 25 return 0; 26} 27

C

1#include <stdio.h> 2 3int dispPrimarity(int n1, int n2) 4{ 5 6 int i = 0; 7 int j = 0; 8 9 // 素数判定 10 for( i=n1;i<=n2;++i ) { 11 int flag = 0; 12 for( j=2;j<i;++j) { 13 if( i%j == 0) { 14 flag = 1; 15 break; 16 } 17 } 18 // 素数なら出力 19 if( flag == 0 ) 20 printf("%d ", i); 21 } 22 return 0; 23} 24 25int main(void) 26{ 27 // 1~100000までの素数を表示 28 dispPrimarity(1, 100000); 29 30 return 0; 31} 32

補足情報(FW/ツールのバージョンなど)

最初の方の実行速度が
real 0m18.922s
user 0m18.303s
sys 0m0.104s

2つ目の実行速度が
real 0m1.855s
user 0m1.670s
sys 0m0.016s
でした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

最初のほうは、合成数である場合も約数の個数を算出するために内側のループの最後まで実行しますが、2つ目は合成数と判明した時点で残りの処理を飛ばしているからです。偶数の処理がほぼ丸ごとカットされる、と言えば分かりやすいでしょうか。

投稿2019/06/12 07:02

majiponi

総合スコア1720

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

i = 99999あたりで

c

1k = 0; 2for(j=1;j<=i;j++) 3 { 4 if(i%j==0) k++; 5 }

c

1int flag = 0; 2for( j=2;j<i;++j) { 3 if( i%j == 0) { 4 flag = 1; 5 break; 6 } 7}

それぞれのループは何回i%jを行うのかを考えるとよいでしょう。

ついでに継続条件をもう少し詰める事ができます。

c

1int flag = 0; 2for( j=2;j*j<=i;++j) { 3 if( i%j == 0) { 4 flag = 1; 5 break; 6 } 7}

ま、エラトステネスの篩を実装した方が速いと思いますが

投稿2019/06/12 07:18

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

1番目の方は、外側のループ(i)で指定されている数の「約数の数」を算出して、その値が2であるかどうか(素数は1と自分自身の二つしか約数を持たない)で判断しています。

2番目の方は外側のループは同じですが、「2以上で、その数を割りきることができたら合成数と判断して処理を打ち切る」のです。

例えば i が 10000 のときを考えると、内側のループが 10000 回と1回(2で割り切れるのでそこで打ち切り)というくらい違ってきます。

投稿2019/06/12 09:02

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shun011

2019/06/12 12:46

1番わかりやすかったです!!細かくありがとうございます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問