▼解答編6
「息抜き:簡単な数値解析 〜エラトステネスのふるい〜」
← 前
:
次 →
問1の解答.
「1か,その数でしか割り切れない」が素数なので,その指定数までを
1つずつ割り切れるかどうか判定していく手法を取ってみました.
ただし多少は効率良くなるように,指定数の半分までを分母の対象にしています.
例えば指定数が「13」だった場合:
2 〜 6 までを対象にして,この中で割り切れる数があれば素数ではない.
問2の解答.
1つのプログラムで まとめてみました.
「PrimeNumber.java」
public class PrimeNumber {
/**
* @param args コマンド・ライン引数
*
* メイン・メソッド.
*/
public static void main(String[] args) {
PrimeNumber pn;
int userNum;
boolean[] isPrimeNumber;
// 引数のエラー判定1(あるかないか)
if(args.length!=1) {
System.out.println("引数ないよ");
System.exit(1);
}
// 引数のエラー判定2(自然数かどうか)
try {
userNum=Integer.parseInt(args[0]);
} catch(NumberFormatException nfe) {
userNum=-1;
}
if(userNum<0) {
System.out.println("正の整数じゃないよ");
System.exit(1);
}
// 自身のインスタンス生成
pn=new PrimeNumber();
// 結果保持用配列の確保
isPrimeNumber=new boolean[userNum+1];
// 指定数値分だけ繰り返し
for(int i=0;i<isPrimeNumber.length;i++) {
// 素数判定(独自仕様)
isPrimeNumber[i]=pn.judgePrime(i);
}
// 結果の出力
pn.outputResult(isPrimeNumber);
System.out.println("");
// エラトステネスのふるい
isPrimeNumber=pn.hurui(userNum+1);
// 結果の出力
pn.outputResult(isPrimeNumber);
}
/**
* @param dstNum 判定する数値
* @return 素数であれば true
*
* 対象数値が素数かどうか判定するメソッド.
*/
public boolean judgePrime(int dstNum) {
int maxDstNum;
// 0,1 は素数ではない
if(dstNum<2) {
return false;
}
// 判定する数値の半分までが計算対象
maxDstNum=dstNum/2;
for(int i=2;i<=maxDstNum;i++) {
// 割り切れたら素数ではない
if((dstNum%i)==0) {
return false;
}
}
return true;
}
/**
* @param dstNum 判定する最大値
* @return 素数であれば true を保持した配列
*
* 対象数値以下全ての数値が素数かどうか判定するメソッド.
*/
public boolean[] hurui(int dstNum) {
boolean[] isPrime;
// 結果保持用配列の確保
isPrime=new boolean[dstNum];
// 初期化
for(int i=2;i<isPrime.length;i++) {
isPrime[i]=true;
}
// 0,1 は素数ではない
isPrime[0]=isPrime[1]=false;
// ふるい
for(int i=0;i<isPrime.length;i++) {
if(isPrime[i]) {
// 求める素数より小さい全ての素数の倍数を除去
for(int j=2*i;j<isPrime.length;j+=i) {
isPrime[j]=false;
}
}
}
return isPrime;
}
/**
* @param isPrime 素数かどうかを保持した配列
*
* 結果表示用メソッド.
*/
private void outputResult(boolean[] isPrime) {
for(int i=0;i<isPrime.length;i++) {
if(isPrime[i]) {
System.out.print(i+",");
}
}
}
}
|
補足:
もっと効率を高めるに「以下の条件にせよ」と,大悶より お叱りを受けました.
×: 指定数の x/2 までを〜
○: 指定数の √x までを〜