• 締切済み

素数について

1000000以下の素数を求め画面に表示するプログラムを作りなさい。 結果をファイルに出力し(sosuu.dat)、 レポートはソースプログラムとsosuu.datの両方を添付してください。 という課題が出ました。 情けないのですが、素数の求める式が分かりません。もし分かる方がいらっしゃいましたら教えていただけますでしょか。お願いします。 以下のプログラムは今回の関連授業で作ったものです。以下のプログラムで使った文字だけで、今回のプログラムを作れますでしょうか。お願いします。 友愛数を求めるプログラムその2 #include "stdio.h" void main () { unsigned long int a, b, c, i; FILE *fp; fp = fopen ("yuuai.dat", "w"); for (i = 2; i < 3000000L; i++) { a = 1; b = 2; while (b <= i / b) { if (i % b == 0) { if (b != i / b) { a += b + i / b; } else { a += b; } } b++; } if (a > i) { b = 2; c = 1; while (b <= a / b) { if (a % b == 0) { if (b != a / b) { c += b + a / b; } else { c += b; } } b++; } if (c == i) { printf ("%d %dYn", i, a); fprintf (fp, "%d %dYn", i, a); } } } fclose (fp); }

みんなの回答

  • fatbowler
  • ベストアンサー率48% (26/54)
回答No.7

ANo.5の補足に対して。 「とても時間がかかり100までの素数を出すのも難しいです。」 とは、計算に時間がかかるのではなくて、割り切れるものがあるかどうか試すのに、 片っ端からif文を書いていくのに時間がかかる、という意味ですよね? 割られる数も取り違えているようです。 d=sqrt(i); はあくまで終了条件で、 iが3で割り切れない iが5で割り切れない iが7で割り切れない   ・   ・   ・ iがdで割り切れない が全て成り立てば、iは素数である が私のアドバイスの内容です。(奇数が偶数で割り切れるはずがないので偶数は省略) そのままコーディングしたのが下記になります。 全角スペースは半角スペースに置き換えて下さい。 (全角スペースでインデントするのが見やすそうですね。) -------- #include "stdio.h" #include "math.h" void main () {     int i,j,d,sflg;     printf("2\n");     for (i = 3; i <= 1000000; i+=2)     {         d = (int)sqrt(i);         sflg = 1;         for(j = 3; j <= d; j++)         {             if(i%j == 0)             {                 sflg = 0;                 break;             }         }         if(sflg)         {             printf("%d\n",i);         }     } } -------- なお、質問者のコードを重視して     d = (int)sqrt(i);     for(j = 3; j <= d; j++) と、sqrt()をそのまま使いましたが()、この計算には時間が掛かりますのでANo.6のように、     for(j = 3; (j*J) <= i; j++) とした方がベターです。 もっとも、今回は私の環境では体感的に差は出ませんでしたが。 あと、sosuu.dat の方は大丈夫ですか? Windowsならコマンドプロンプトで画面への出力をファイルに落ちるようにリダイレクトするだけですが。 ファイルをfopenして、printfをfprintfに置き換えてもOKです。(この方がベター)

gether
質問者

お礼

本当にありがとうございました。 fatbowlerさんのプログラムを殆ど使わせていただきました。 sosuu.datも上手くできました。 忙しい中、たくさんの力を貸してくださり本当にありがとうございました。

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.6

★アドバイス ・ちょこっとネット検索したら参考になりそうなページを Wikipedia で見つけました。  http://ja.wikipedia.org/wiki/%E7%B4%A0%E6%95%B0%E5%88%A4%E5%AE%9A→『素数判定 - Wikipedia』  これを参考に素数一覧のソースを作って見ました。 サンプル: // 素数判定 int IsPrime( int n ) {  int i;    if ( n < 2 ) return 0;  if ( n == 2 ) return 1;  if ( !(n % 2) ) return 0;    for ( i = 3 ; (i * i) <= n ; i += 2 ){   if ( !(n % i) ){    return 0;   }  }  return 1; } // 素数一覧 int main( void ) {  int i;    printf( "<< 素数一覧 >>\n" );  for ( i = 1 ; i <= 1000000 ; i++ ){   if ( IsPrime(i) ){    printf( "%d ", i );   }  }  printf( "\n" );  return 0; } その他: ・私の環境ではリダイレクションしてファイルに保存すると 1~2 秒で終了しました。  あと『友愛数』を求められるのなら素数も出来そうな気はしますが…。 ・以上。

参考URL:
http://ja.wikipedia.org/wiki/%E7%B4%A0%E6%95%B0%E5%88%A4%E5%AE%9A
gether
質問者

お礼

プログラムまで作ってくださり、ありがとうございました。 友愛数は授業でヒントをたくさん得ながらだったので作れたのですが、自力では素数にも手も足も出せない状態でした。 本当にありがとうございました。

  • fatbowler
  • ベストアンサー率48% (26/54)
回答No.5

素数を求めるのは決して難しくないので、ご自分でプログラムを作成されるようお勧めします。 方法は単純で、 ・素数かどうか、片っ端からチェックしていく ・チェックの方法は、対象の整数が1以外の数字で割り切れないか、片っ端から試してみる という力技です。 ヒントとしては、 ・偶数は2で割り切れるので、最初から除外してよい ・整数nは、√n以下の整数に約数がなければ素数と判断してよい くらいでしょうか。 頑張って下さい。

gether
質問者

補足

今ヒントを元に作ってみたのですが、とても時間がかかり100までの素数を出すのも難しいです。どうすればよいでしょうか? #include "stdio.h" #include "math.h" void main () { int i,d; printf("2\n"); printf("3\n"); printf("5\n"); printf("7\n"); for (i = 8; i <= 100; i++) { d=sqrt(i); while (d % 2 != 0) { if(d%3!=0) { if(d%5!=0) { if(d%7!=0) printf("%d\n",i); } } } } }

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.4

> 情けないのですが、素数の求める式が分かりません。もし分かる方がいらっしゃいましたら教えていただけますでしょか。 必ず結果が素数となる公式を見つけることは多くの数学者の夢です。 > 以下のプログラムは今回の関連授業で作ったものです。以下のプログラムで使った文字だけで、今回のプログラムを作れますでしょうか。 作れます。 /や%のような演算子になる文字も含まれていますし、必要なキーワードや関数を構成する文字も含まれているようです。

  • kaaaiii
  • ベストアンサー率21% (31/143)
回答No.3

概略だけ言いますと、素数iは i>=n*n (n>=2)までの間に、nで割れない数、です。 例えば19は、19>=4*4までに、2,3,4で割れません。 5*5だと19を超えちゃいますよね。だから素数です。 つまりこのプログラムの作り方は、 for (i = 2; i <= 1000000; i++) { n=2; while (i >= n*n) { if (i % n == 0) ~ みたいな感じでやっていけばいいんじゃないでしょうか。 細かいやり方はご自分で考える事をすすめます。

gether
質問者

お礼

分かりやすい説明ありがとうございます。 自分なりに改良してみたのですが、なかなか上手くいきません^^; ありがとうございました。

  • Werner
  • ベストアンサー率53% (395/735)
回答No.2
gether
質問者

お礼

参考にさせていただきました!! ありがとうございました。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.1

手始めに、素数の定義を日本語の文章で書いてみてください。

関連するQ&A

  • 最大公約数を出すには?

    こんにちは。 過去ログを見てみましたが、まだ知らない言葉が出てきていて理解できませんんでした。なるべくなら、簡単な方法で出すやり方を教えてください。 ちなみに公約数の表示は以下のようにしてできました。if、while、forぐらいなら使えます。 明日までの課題なので、できるだけ今日中に答えてくださったら、とても助かります。 よろしくお願いします。 #include <stdio.h> main() { int a,b,i; i=1; printf("a="); scanf("%d",&a); printf("b="); scanf("%d",&b); while((i<=a)&&(i<=b)){ if((a%i==0)&&(b%i==0)) {printf("Answer=%d\n",i);i=i+1;} else{i=i+1;} } }

  • fscanf ファイルから数を読み込む。

    ファイルから数を読み込むと 4201696 4201696 4201696 と、sample.txtにない数が表示されます。 sample.txtの中身は、2から6の数です。 sample.txtの中身は画像に添付しました。 以下は実行したプログラムです。 #include<stdio.h> #include <assert.h> int main(void){ FILE *fp; int a,b,i; if((fp=fopen("sample.txt","a"))==NULL){ printf("fileopen error\n"); } printf("整数を入力してください。"); scanf("%d",&a); fprintf(fp,"%3d\n",a); printf("整数を入力してください。"); scanf("%d",&a); fprintf(fp,"%3d\n",a); i=0; while(i<3){ fscanf(fp, "%d",&b); assert(b>2); printf("%3d\n",b); i++; } return(0);} 2から6の間の数が表示されるよう、指摘をおねがいします。

  • 素数判定の繰返し

    繰返し素数判定を行ない、CtrlーDで終了するプログラムをつくっています。 まず繰返しなしの素数判定プログラムを作り #include<stdio.h> int main(void) { int a,i; printf("自然数を入力:"); scanf("%d",&a); if(a<=0) printf("入力エラーです。\n"); else if(a==1) printf("1は素数ではない。\n"); else{ for(i=2; i*i<=a; i++){ if(a%i==0) break; } if(i*i>a) printf("%dは素数です。\n",a); else printf("%dは素数ではない。\n",a); } return(0); } これはちゃんとできたのですがそれを繰り返すことができません。 #include<stdio.h> int main(void) { int a,i; printf("自然数を入力:"); scanf("%d",&a); while((a=getchar())!=EOF){ if(a<=0) printf("入力エラーです。\n"); else if(a==1) printf("1は素数ではない。\n"); else{ for(i=2; i*i<=a; i++){ if(a%i==0) break; } if(i*i>a) printf("%dは素数です。\n",a); else printf("%dは素数ではない。\n",a); } printf("自然数を入力:"); scanf("%d",&a); } printf("プログラムを終了します。\n"); return(0); } これは訳わからないことになっちゃいます。。。 どうしたらいいんでしょうか??

  • 2進数の足し算(C言語)

    C言語初学者です。 タイトル通り、2進数の足し算をするプログラムを作っていますが、行き詰ってしまいました。 特に、桁上げをどうするか悩んでいます。 今の自分の考えでは、入力された数値を10で割り、その余りを足していけばできると思っていたのですが、やはり桁上げや繰り上がりに悩んでいます。 全然できてませんが以下ソースです。 #include <stdio.h> int main(void) { int a, b, i; do { printf("8桁以下の非負の2進数を入力してください(1つ目): "); scanf("%d" ,&a); if (a < 0) puts("負の数を入力しないでください。"); } while (a < 0); do { printf("8桁以下の非負の2進数を入力してください(2つ目): "); scanf("%d" ,&b); if (b < 0) puts("負の数を入力しないでください。"); } while (b < 0); a = a % 10; b = b % 10; よろしくお願いします。

  • VB2005で、Structureの配列を返すプログラムを以下のように書きたい

    VB2005で、Structureの配列を返すプログラムを以下のように書きたいのですが、そもそもVB6しか使ったことが無いもので、以下のような素数の結果を返すこのプログラムの書き方はVB2005らしいでしょうか? Module Module1 Public Structure SosuuStatus Public num As Integer Public status As String End Structure Class Sosuu Function SosuuCheck(ByVal st As Integer, ByVal ed As Integer) As SosuuStatus() Dim i As Integer, j As Integer Dim sosuu(0 To ed - st) As SosuuStatus Dim cnt As Integer = 0 For i = st To ed sosuu(cnt).num = i sosuu(cnt).status = "" '初期化 If 1 = i Then sosuu(cnt).status = "素数ではない" ElseIf 0 = (i Mod 2) Then sosuu(cnt).status = "素数ではない" Else For j = 3 To Math.Sqrt(ed) If 0 = (i / j) Then sosuu(cnt).status = "素数ではない" End If Next j End If If sosuu(cnt).status = "" Then sosuu(cnt).status = "素数である" End If cnt = cnt + 1 Next i SosuuCheck = sosuu End Function End Class End Module

  • explodeと条件分岐

    次のようなプログラムを描きました。 /////////////////////////////////////////////////////////////// $A1 = $_POST['A1']; $B1 = $_POST['B1']; $fp = fopen("data.dat", "a+"); flock($fp, LOCK_EX); while($line = fgets($fp)){  list($A2,$B2) = explode("^", $line);  if($A1 == $A2 && $B1 == $B2) echo "成功";  else echo "ログイン失敗"; } //////////////////////////////////////////////////////////////// ここでdata.datの内容は…  AAA^AAA  BBB^BBB  CCC^CCC とします。 フォームから、A1=AAA,B1=BBBを与えたとき、 「成功」が出ると思っていたのですが、「失敗」と出てしまいます。 いろいろ考えてみたのですが、解決に至らず質問することにしました。 ご指摘、お願いします。 尚、フォームから正確に入力されていることと、 分岐のところを「if($A1 == $A2)」とすると、 正常に動くことは確認できました。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • 2つの自然数を入力しその間にある素数を表示する

    2つの自然数を入力して、その間にある素数を表示するプログラムです。 #include <stdio.h> main( ) { int a,b,c,i,j; printf("Input number 1:"); scanf("\n%d",&a); printf("Input number 2:"); scanf("\n%d",&b); if(a>b){ c=a; a=b; b=c; } for(i=a;a<b+1;i++){ for(j=2;j<i-1;j++){ if(i%j!=0){j++;} else{ if(i=j){ printf("\n%d",i); } } } } } i=aからbまで j=2からi-1まで iはjで 割り切れるか NO→(jを1つ増やす) YES→iはjと等しいか YES→iの値を表示 NO→(iを1つ増やす) END この部分がよくわかりませんfor文を使うんですか? ご指導お願いします。

  • java 素数判定

    入力した数字が整数か否かを判定するjavaプログラムを作っています。 以下の通りコンパイルして実行しました。これだと実行したときに どんな数字を数字を入力しても「31は素数です。 」となります。 入力した数字を判定させるにはどのようにしたらいいのでしょうか? class Sosuu { public static void main (String[] args) { int n = 31; boolean isPrime = true; for (int i = 2; i <= n - 1; i++) if (n % i == 0) { isPrime = false; break; } if (isPrime) System.out.println(n + " は素数です。"); else System.out.println(n + " は素数ではありません。"); } }

    • ベストアンサー
    • Java
  • 素数プログラムの解読、

    C言語のプログラムで素数を求めるプログラムで、 //入力された数字が素数がどうかを求めるプログラムです。 #include<stdio.h> main() { int a,c; //aはそれが素数かどうか調べたい数字です。 printf("aに何か好きな整数をいれてください。\n"); printf("a="); scanf("%d",&a); c = 2; while ( a%c ){ c += c%2+1; printf("途中計算 %d\n",c); } if ( a > 1 && c == a ){ printf("素数です。\n"); }else{ printf("素数ちゃうよ。\n"); } } というのを作りました。このプログラムは 教えてgooの回答欄にあったものを自分で いじったものですが、 c = 2; while ( a%c ){ c += c%2+1; printf("途中計算 %d\n",c); } の部分が何をしているのかが、わかりません。 printf("途中計算 %d\n",c); は 何をしているかが解るかもしれないと思い 自分で付足しましたが、やっぱりわかりません。 だれか解る方お願いします。

  • if文の論理積について

    if文の論理積についての質問があります. 以下の関数は(int)num番目の素数を戻り値とする関数です. long sosuu(int num) { long a,b; int count = 0; for(a = 2; ; a++){ for(b = 2; b < a; b++){ if(a % b ==0) break; } if( (a == b) && (count++ == num)) break; /*ここが問題*/ } return a; } 今のところ,この関数で問題はおきていませんが, if((a==b)&&(count++ == num)); についての質問です. この場合,C言語の内部処理では,(a!=b)の場合,countはインクリメントされないのでしょうか? 論理積で左辺が0の場合は右辺の処理も行われないのでしょうか? 僕が使っている開発環境(BorlandC++,VC++)では両方とも問題は無かったのですが,C言語業界全体としてはどうなのでしょう? 僕としてはソースが見やすくなって都合が良いのですが,他の開発環境担になったとき,バグを出すことになりそうで少し不安です. 他の開発環境を持っている方,教えてください. この関数を使うメイン関数も置いておくので,良かったら,チェック用として使ってください. /*プログラムエントリポイント*/ int main(int num,char *main_hikisu[]) { long input,i,count,sosu; for(i = 1; i < num ; i++) { /*文字列から数字を取得*/ input = atoi(main_hikisu[i]); /*素因数分解できない形の取得*/ if(input <= 1){ printf("%sは素因数分解できません\n",main_hikisu[i]); continue; } /*素因数分解開始*/ printf("%d = ",input); count = 0; do{ sosu = sosuu(count); if(input % sosu == 0){ input /= sosu; printf("%d",sosu); if(input != 1) printf("*"); }else count++; }while( input != 1); printf("\n"); } if(num == 1){ printf("このプログラムはコマンドライン引数に数字を入れることにより,素因数分解を実行します"); }else{ printf("プログラム終了\a"); } return 0; } 以上です.よろしくお願いします.

専門家に質問してみよう