web-dev-qa-db-ja.com

非常に簡単な素数テスト-forループを理解していないと思う

私は基本的なJava試験のために過去の試験論文を練習していますが、数値が素数であるかどうかをテストするためのforループを作成するのは難しいと感じています。少なくとも2桁の数字で機能するような、より大きな数字の効率測定を追加します。

現時点では、n IS素数。

私の問題は、forループ自体と「trueを返す」をどこに置くかで問題が発生していることだと思います。そして、「falseを返す;」...それは私が犯している本当に基本的な間違いだと確信しています...

public boolean isPrime(int n) {
    int i;
    for (i = 2; i <= n; i++) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

私が他の場所でstackoverflowの助けを見つけることができなかったのは、同様の質問がより複雑な実装を求めてより効率的な方法を求めていたためです。

13
BexLE

forループには少し問題があります。そのはず: -

for (i = 2; i < n; i++)  // replace `i <= n` with `i < n`

もちろん、nnで割った場合、余りをチェックしたくないでしょう。常に1を提供します。

実際、条件を次のように変更することで、繰り返しの回数を減らすことさえできます。-i <= n / 2nは、nを考慮する場合を除いて、n / 2より大きい数で除算できないため、まったく考慮する必要はありません。

したがって、forループを次のように変更できます。-

for (i = 2; i <= n / 2; i++)  
31
Rohit Jain

次のようにして、はるかに早く停止し、ループをより速くスキップできます。

public boolean isPrime(long n) {
    // fast even test.
    if(n > 2 && (n & 1) == 0)
       return false;
    // only odd factors need to be tested up to n^0.5
    for(int i = 3; i * i <= n; i += 2)
        if (n % i == 0) 
            return false;
    return true;
}
31
Peter Lawrey

最後の反復ステップでtrueが得られるため、i < nと記述する必要があります。

3
Zoltán Tamási

エラーはi <= n

for (i = 2; i<n; i++){
3
public class PrimeNumberCheck {
  private static int maxNumberToCheck = 100;

  public PrimeNumberCheck() {
  }

    public static void main(String[] args) {
      PrimeNumberCheck primeNumberCheck = new PrimeNumberCheck();

      for(int ii=0;ii < maxNumberToCheck; ii++) {
        boolean isPrimeNumber = primeNumberCheck.isPrime(ii);

      System.out.println(ii + " is " + (isPrimeNumber == true ? "prime." : "not prime."));
    }
  }

  private boolean isPrime(int numberToCheck) {    
    boolean isPrime = true;

    if(numberToCheck < 2) {
      isPrime = false;
    }

    for(int ii=2;ii<numberToCheck;ii++) {
      if(numberToCheck%ii == 0) {
        isPrime = false;
        break;
      }
    }

    return isPrime;
  }
}
2
user2033388

3で割り切れるこのコード番号では、forループコードの初期化がスキップされます。
Forループの反復も3の倍数をスキップします。

private static boolean isPrime(int n) {

    if ((n > 2 && (n & 1) == 0) // check is it even
       || n <= 1  //check for -ve
       || (n > 3 && (n % 3 ==  0))) {  //check for 3 divisiable
            return false;
    }

    int maxLookup = (int) Math.sqrt(n);
    for (int i = 3; (i+2) <= maxLookup; i = i + 6) {
        if (n % (i+2) == 0 || n % (i+4) == 0) {
            return false;
        }
    }
    return true;
}
1

最速の方法の1つは、nの平方根までループすることです。

  private static boolean isPrime(int n){
        int square = (int)Math.ceil((Math.sqrt(n)));//find the square root
        HashSet<Integer> nos = new HashSet<>(); 
        for(int i=1;i<=square;i++){
            if(n%i==0){
                if(n/i==i){
                    nos.add(i);
                }else{
                    nos.add(i);
                    int rem = n/i;
                    nos.add(rem);
                }
            }
        }
        return nos.size()==2;//if contains 1 and n then prime
    }
1
Ram Kumar

Forループでこれにいくつかの簡単なMathプロパティを使用することもできます。

数字「n」は、それ自体または1で割り切れる場合にのみ素数になります。数字が素数でない場合、2つの要素があります。

n = a * b

forループを使用して、「n」に到達する代わりに、番号「n」のsqrtまでチェックできます。 「a」と「b」の両方が数値「n」のsqrtよりも大きい場合、a * bは「n」よりも大きくなります。したがって、少なくとも1つの係数は平方根以下でなければなりません。

ループは次のようになります。

for(int i=2; i<=Math.sqrt(n); i++)

これを行うことにより、コードの実行時の複雑さを大幅に減らすことができます。 O(n/2)になると思います。

1
Nitesh Joshi

それをJava 8の方法で行うと、よりきれいになります

    private static boolean isPrimeA(final int number) {
        return IntStream
               .rangeClosed(2, number/2)
               .noneMatch(i -> number%i == 0);
    }
0
Sal

_i<=n_をチェックしているので、_i==n_の場合、0のみを取得し、常にfalseを返します。i<=(n/2)を試してください。_i<n_までチェックする必要はありません。

0
Renjith

さて、forループには問題があります。コードは次のとおりです。

public static boolean checkPrimeNUmber(int number) 
{ 
   if(number <= 1) 
   { 
      return false; 
   } 
   for(int a = 2; a < Math.sqrt(number); a++) 
   { 
      if(number % a == 0) 
      { 
         return false; 
      } 
   } 
   return true;
}
0
Shiva

上記のアルゴリズムは1を素数として扱いますが、そうではありません。したがって、ここに解決策があります。

static boolean isPrime(int n) {
  int perfect_modulo = 0;
  boolean prime = false;

  for ( int i = 1; i <=  n; i++ ) {
    if ( n % i == 0 ) {
      perfect_modulo += 1;
    }
  }
  if ( perfect_modulo == 2 ) {
    prime = true;
  }

  return prime;
}
0
kxhitiz