• ベストアンサー

【Java】ある数列から、素数を探すプログラムについて

Java初心者です。独学なので質問できる環境が無く、 こちらで質問致します。回答をお願い致します。 以下のプログラムについて質問です。 class Prime { public static void main(String[] args) { int max = 100; // 素数を探す数の最大値 boolean[] a = new boolean[max]; // 素数かどうか判定する配列 // 配列の初期化 for(int i = 0; i < max; i++) a[i] = true; // 素数かどうか判定 for(int i = 2; i < max; i++) { if(a[i-1]) { for(int j = 2; i*j <= max; j++) a[i * j - 1] = false; } else continue; } // 結果を表示 for(int i = 1; i < max; i++) { if(a[i]) System.out.print((i + 1) + " "); } System.out.println(); } } 上記の「配列の初期化」の個所、 for(int i = 0; i < max; i++) a[i] = true; ここでなぜ、a[i] = true;となるかわかりません。 0と1はどちらも素数ではないと思うので、 私はtrueではないと思うのですが・・・。 ぜひとも教えて頂きたいと思います。

  • Java
  • 回答数3
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

まず結論から言うとこのプログラムにおいては「そこは使わないのでどちらでも構わない」ということになります. ただし, このプログラムは腐っています. 動作は正しいですがこのように書いてはいけません. もっと素直に, 例えば class Prime { public static void main(String[] args) { int max = 100; // 素数を探す数の最大値 boolean[] a = new boolean[max+1]; // 素数かどうか判定する配列 // 配列の初期化 for(int i = 2; i <= max; i++) a[i] = true; // 素数かどうか判定 for(int i = 2; i <= max; i++) { if(a[i]) { for(int j = 2; i*j <= max; j++) a[i * j] = false; } } // 結果を表示 for(int i = 2; i <= max; i++) { if(a[i]) System.out.print(i + " "); } System.out.println(); } } とでも書くべきです.

dondondoo
質問者

お礼

回答ありがとうございました! しかも、新しいプログラムまで書いて下さり、大変うれしいです! たしかに、 System.out.print(i + " "); のほうがスッキリしていますね! 本当にありがとうございました!!

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

一応念の為: もとのプログラムでもっとも「腐っている」のは, a[i] が「i+1 が素数かどうか」を表しているという点にあります. なぜそこでひねらなければならないのか. a[i] が「i が素数かどうかを表す」とすれば, #2 で挙げたように素直なプログラムとして書くことができます. デメリットは「配列要素が 1個無駄になる」ですが, たかが 1個のためにこのようにひねる必要はありません. 本当に配列要素を節約したいのなら, もっと違う方法をとるべきです.

dondondoo
質問者

お礼

再度コメントありがとうございました! 見やすい・分かりやすいプログラム作りを心がけたいと思います! 本当にありがとうございました!

noname#94983
noname#94983
回答No.1

ここでの処理の考え方は、配列全部にとりあえずtrueを入れておき、その後で繰り返しを使って、ある値の倍数の要素にfalseを入れる、ということをひたすら繰り返している。これで、配列aの中で、何かの数字の倍数(つまりその数字で割り切れる)の要素にはすべてfalseが設定されていく。結果として、trueのまま残っているのは何の数の倍数でもない値(つまり素数)になる、という考え方をしている。 だから、最初の繰り返しでa[i] = true;するのは、「とりあえず全部にtrueを入れておく」ということであって、0や1が素数だろうがそうでなかろうが関係ない。初期化というのはそういうことなのだから。とりあえず全部入れておき、それからその後で1つ1つについて調べていく、ということなんだから。

dondondoo
質問者

お礼

とても早い回答、ありがとうございます!! >配列全部にとりあえずtrueを入れておき、その後で繰り返しを使って、ある値の倍数の要素にfalseを入れる なるほど、そのような意味だったのですね。もう一度「初期化」の確認を致します。 改めてありがとうございました!

関連するQ&A

  • javaで素数を探すプログラム。

    javaで素数を探すプログラム。 初歩的なことかと思いますが、助言をお願いします。 if(a[i-1]) ←この部分がわかりません。これはどのような条件がなのでしょうか? class Prime { public static void main(String[] args) { int max = 100; // 素数を探す数の最大値 boolean[] a = new boolean[max]; // 素数かどうか判定する配列 // 配列の初期化 for(int i = 0; i < max; i++) a[i] = true; // 素数かどうか判定 for(int i = 2; i < max; i++) { if(a[i-1]) { for(int j = 2; i*j <= max; j++) a[i * j - 1] = false; } else continue; } // 結果を表示 for(int i = 1; i < max; i++) { if(a[i]) System.out.print((i + 1) + " "); } System.out.println(); } } このプログラム

    • ベストアンサー
    • Java
  • プログラムのスレッド化について。

    以下の処理をスレッド化しようとしています。 public class FCP{ int N=10 long LOOP_MAX=100 double x[][] = new double[N][4] int g[][] = new int[N][4] boolean y[][] = new boolean[N][4]//出力 boolean A[][] = new boolean[N][10] double T=0.5 Set_Adjacent_Matrix() //A配列にtrueとfalseを代入 Set_initial_value() //y配列に初期値を代入(Math.random()>0.5) g1(int i, int j) //k<4 sum=1 if( y[i][k] == true ) --sum return(double)sum g2(int i, int j) //k<N sum=0 if( y[i][j] == true ) if( y[k][j] == true && A[i][k] == true ) --sum return(double)sum Display_output() //結果表示 if( y[i][j] ) System.out.print("0") else System.out.print(".") public static void main(String args[]) { long loop; int i, j, k; Set_Adjacent_Matrix(); Set_initial_value(); for( loop=0; loop<LOOP_MAX; loop++ ){ for( i=0; i<N; i++ ){ for( j=0; j<4; j++ ){ x[i][j] = g1( i, j ) + g2( i, j ); if( y[i][j] ){ x[i][j] += T; }else{ x[i][j] -= T; } if( x[i][j] > 0.0){ y[i][j] = true; }else{ y[i][j] = false; } } } Display_output(); } } 今回Threadクラスの継承を使ってスレッド化しようと考えました。runメソッドには上のプログラムのmain部分の処理をさせようと思っています。そしてstartメソッドで必要な数(Nの値=10コ)のスレッドを生成しrunメソッドを実行する。 と、ここまではわかったのですが、「生成された各スレッドの番号を保持し、そのスレッドに担当させる処理を決める」という部分をどうすればいいのかわかりません。 「i(1~10)番目のスレッドはN(1~10)列目の処理を担当している」という風にするにはどうしたらいいのでしょうか? よろしくお願いします。

    • ベストアンサー
    • Java
  • 【Java】プログラムの読み方

    Javaの学習を始めて数週間の初心者です。 皆さんのお知恵を貸してください。 条件分岐、ループ、配列、メソッドを使用したプログラムを作成する、 という課題です。習っただけでなく自分でちゃんと使えるか、という意図だと思います。 素数を判定するプログラムにしようと考えました(もっと単純なもので構わないのですが、思いつかなかった…)。 ネットを検索して考え方を参考にしながら、書いてみました(コピペではないです)。 不細工で読みにくいかもしれませんがよろしくお願いします。 概要(問題のソースは最下部) ・キーボードで3つの数字を入力し、それらを配列numに代入する(readLine使用)。[メソッド][配列] ・(ここからペーストしたソース)配列をfor文で足し込み合計値をsumに代入。[ループ] ・2以上とそれ以外に分ける(素数は2~)。[条件分岐] ・2以上、sum未満の数で順番に割っていく。 ・1回でも割り切れたらboolean型sosuにfalseを代入、処理を終了させる。 (ここには載っていませんが、sosuはtrueで初期化済み) ・sosuがtrueかfalseかで表示を変える。 とりあえずソースを書いてコンパイルも通り、実行した結果も一応私の意図通りに動きます。。 が、これを講師の方に動きを説明しないといけません。一つ一つの動きは理解できるのですが、 ifの入れ子のブロックで処理がどう移っていくのかが不明瞭です。 お訊きしたいのは以下のケースで処理がどう動くのか、です。理由もお願いします。 (1)2つ目のfor文、1回目でfalseの場合(例えばsumが2の時) …2の場合、「素数です」と表示されますが、改めて読むと「elseに飛んでsosu = falseになるのでは?」 という疑問があります。具体的な内容を伏せて講師の方に訊いてみると「上のif文でtrueになっても その下のfor文でfalseならばelseに飛ぶはず」と言われました。 (2)2つ目のif文、falseになった場合 …この場合、falseなら素数と判定された、と思っていて実行結果もそのようになるのですが、 「elseに飛ぶ、が正しいならおかしくないかな?」と感じます。 (3)breakの後 …大体上と同じ疑問です。 (4)要は入れ子になっている場合、どこに処理が移るかがちゃんと解っていないのだと思います。 このような場合の読み方のアドバイスをお願いします。 情報に不足があればご指摘ください。 ↓ここからソース↓ (略) System.out.println("※合計値はint型の範囲内になるよう注意してください。"); (略) int sum = 0; for (int i = 0; i < num.length; i++) { sum += num[i]; } if (sum >= 2) { for (int i = 2; i < sum; i++) { if (sum % i == 0) { sosu = false; break; } } } else { sosu = false; } if (sosu == true) { System.out.println("\n合計値" + sum + "は素数です。"); } else { System.out.println("\n合計値" + sum + "は素数ではありません。"); } (以下略)

    • ベストアンサー
    • Java
  • 初心者ですが教えて下さい

    javaの勉強を始めたばかりの者です。 参考書に掲載されていた素数検索のソースなのですが、一部どうしても理解できない部分があります。 以下のソースの if(a[i-1]) の部分なのですが、ここで何という条件を定義しているのでしょうか。 初歩的な質問で申し訳ないのですが、教えて下さい。お願いします。 (各コマンドの具体的な説明もしていただけると大変助かります) 以下、掲載されていたソースです。 class a { public static void main(String[] args) { int max = 100; boolean[] a = new boolean[max]; for(int i = 0; i < max; i++) a[i] = true; for(int i = 2; i < max; i++) { if(a[i-1]) { for(int j = 2; i*j <= max; j++) a[i * j - 1] = false; } else continue; } for(int i = 1; i < max; i++) { if(a[i]) System.out.print((i + 1) + " "); } } }

    • ベストアンサー
    • Java
  • java初心者です。基本的ですがよろしくおねがいします◎

    下記の内容でコンパイル時にエラーが出てしまいます。 ■問題■要素数10の配列を任意のデータで初期化し、最大値と最小値を求めよ。 import java.io.*; class Ensyu4 {    public static void main(String args[])     {    int i=0,max=0,min=0;//カウンタ、最大値変数、最小値変数         int[10] intArray = {5, 6, 7, 8, 9, 10, 1, 2, 3, 4}; //配列任意初期化         max = intArray[0];         min = intArray[0];         for(i=0;i<10;i++)//最大・最小判定         {             if(max<intArray[i])                 max = intArray[i];             if(min>intArray[i])                 min = intArray[i];         }     System.out.println(max + "が最大値です");     System.out.println(min + "が最小値です");     } } エラーの内容・・・ Ensyu4.java:9: ']' がありません。 int[10] intArray = {5, 6, 7, 8, 9, 10, 1, 2, 3, 4}; //配列任意初 期化 ^ Ensyu4.java:9: 文ではありません。 int[10] intArray = {5, 6, 7, 8, 9, 10, 1, 2, 3, 4}; //配列任意初 期化 ・・・どうやら配列の初期化の仕方が間違っているようなのですが、何が間違っているかわかりません。きっと基本的な間違いなのでしょうが・・・^^; 下記のサイトを参考にさせていただいています◎ http://www.javaroad.jp/java_array1.htm なにとぞご協力お願いいたします^^;

    • ベストアンサー
    • Java
  • 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
  • 前回の質問のプログラムの応用 Java言語

    MAX_QUESTION の部分を指定できるようにしたいのです! たとえば、20と入力したら、20問、問題が生成されるようなプログラムです。 教えてください。よろしくお願いします。 import java.io.*; public class Java05 { /** 表示する問題の個数 */ public static final int MAX_QUESTION=10; /** * 足し算の問題をMAX_QUESTION回繰り返して出題する。 * 最後に正答率を表示する。 */ public static void main(String[] args){ int goodAnswer=0; //正答の個数 System.out.println("これから足し算の問題を"+MAX_QUESTION+"問出します。"); /* * 以下、問題を繰り返し表示し、ユーザからの解答を判断する。 * その後、正答の数を数える。 */ for(int i=0;i<MAX_QUESTION;i++){ boolean ok=showQuestion(i+1); if(ok){ goodAnswer++; } } double rate=goodAnswer*100.0/MAX_QUESTION; System.out.println(""); System.out.println("問題は"+MAX_QUESTION+"問"); System.out.println("正答数は"+goodAnswer+"問"); System.out.println("不正解数"+(MAX_QUESTION-goodAnswer)+"問"); System.out.println("正答率は"+rate+"%"); } /** * showQuestionは足し算の問題を1問出し、答えを待つ。 * 正答、誤答の別を表示する。 * 正答の場合は ture を返す。 */ public static boolean showQuestion(int questno){ double dblA=Math.random()*1000; double dblB=Math.random()*1000; int intA=(int)dblA; int intB=(int)dblB; BufferedReader reader=new BufferedReader(new InputStreamReader(System.in)); try{ System.out.println("[第"+questno+"問] "+intA+"+"+intB+"="); String line=reader.readLine(); int result=Integer.parseInt(line); if(intA+intB==result){ System.out.println("正解!"); return true; }else{ System.out.println("不正解!"); return false; } }catch(IOException e){ System.out.println(e); }catch(NumberFormatException e){ System.out.println("入力が正しくありません。"); } return false; } }

  • 変数booleanの扱い方

    下記のコードでコンパイルしたところ、出現 int 互換性のない型 要求:boolean boolean bl = 0 ; とエラーが出ました。コード上でまず、bl = 0 と0が入るのがまず分からないのと、trueとfalseを入れ換えているのがわかりません。すみませんが、かなりわかってないので、出来るだけ詳しく説明お願いします。 boolean bl = 0; for(int i=0; i<5; i++) for(int j=0; j<5; j++) if(bl == false){ System.out.print('*'); bl = true; } else{ System.out.print('-'); bl = false; } } お決まりのクラス宣言などのコードは省きました。

    • ベストアンサー
    • Java
  • booleanの戻り値について

    配列の等価判定をしたいのですが思うように動かないです。 助けてください import java.io.*; class Kadai4 { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int[] TBL1; int[] TBL2; TBL1 = new int[5]; TBL2 = new int[5]; boolean flg=true; System.out.println("配列1を入力"); for (int i = 0; i <= 4; i++) { String s1 = br.readLine(); int t1 = Integer.parseInt(s1); TBL1[i] = t1; } System.out.println("配列2を入力"); for (int i = 0; i <= 4; i++) { String s1 = br.readLine(); int t1 = Integer.parseInt(s1); TBL2[i] = t1; } // 配列表示 System.out.println("配列表示"); for (int i = 0; i < TBL1.length; i++) { System.out.print(" TBL1[" + i + "]=" + TBL1[i]); } System.out.println(""); for (int i = 0; i < TBL2.length; i++) { System.out.print(" TBL2[" + i + "]=" + TBL2[i]); } toka(TBL1, TBL2); System.out.println(""); if (flg == true) { System.out.println("配列は等価"); } else { System.out.println("配列は非等価"); } } private static boolean toka(int[] ss1, int[] ss2) { boolean flg = true; for (int i = 0; i < ss1.length; i++) { if (ss1[i] != ss2[i] || ss1.length != ss2.length) { flg=false } } return flg; } }

  • 要素数が10の配列で、乱数0~9の値が重複しないようにする方法がわからなくて困っています。

    JAVAの練習問題でわからなくて困っています 以下は線形探索のプログラムで、このプログラムを改良して、 要素数が10の配列で、乱数0~9の値が重複しないようにする方法がわからなくて困っています。 以下のような簡単なプログラムでできる方法で行いたいです。 どなたか答えまたはヒントを下さい、お願いします。 ------------------------------------------------------------ import java.util.Random; import java.util.Scanner; public static void main (String[] args) { Random rand = new Random(); Scanner stdIn = new Scanner(System.in); final int n = 10; //要素数 int[] a = new int[n]; //配列を宣言 for (int j = 0; j < n;) a[j] = rand.nextInt(10); System.out.print("配列aの全要素の値\n{ "); for (int j = 0; j < n; j++) System.out.print(a[j] + " "); System.out.println("}"); System.out.print("探す数値 : "); int key = stdIn.nextInt(); int i; for (i = 0; i < n; i++) if (a[i] == key) break; if (i < n) //探索成功 System.out.println("それはa[" + i + "]にあります。"); else //探索失敗 System.out.println("それはありません。"); } }

専門家に質問してみよう