2016-08-16 6 views
1

私は、数値の素因数分解を行うメソッドを作ろうとしていましたが、おそらく最も効率的ではありませんが、なぜそれがうまくいかないのかわかりません。Javaのこの素因数分解コードで何が問題になっていますか?

それはあなたが(それぞれ、要因の ArrayListを返し、入力が素数である場合に応じて、 trueまたは falseのいずれかにそれらを期待する正確に何をすべきか factor()isPrime()という名前の、私が書いた他の二つの方法で、呼びかけ
public static ArrayList<Integer> primeFactorize(int num) { 
    ArrayList<Integer> primeFactors = new ArrayList<Integer>(); 

    for (int i = 2; i < Math.sqrt((double) num); i++) { 
     if (isPrime(i) && factor(num).contains(i)) { 
      primeFactors.add(i); 
      num /= i; 

      if (isPrime(num)) { 
       primeFactors.add(num); 
       break; 
      } 
      i = 2; 
     } 
    } 
    return primeFactors; 
} 

)。

私はnumが12であるとデバッガを経て、そしてそれはprimeFactorsに2を追加した最初のループのためにうまく働きました。それはnum 2である6とiされた状態で再び、アレイの上部に着いたときi < Math.sqrt((double) num)falseを返さかのようしかし、それはループを終了しました。

しかし6の平方根が少し私も(double) i < Math.sqrt((double) num)を試してみましたが、それだけでまったく同じことをした2以上であるので、それは、意味がありません。

誰もが私が欠けているものを見ることができますか?すべての返信いただきありがとうございます。


編集:ここで私のコードは、助けてくれてありがとう!私はそれがより効率的になることを確かに知っているので、後でそれをするかもしれませんが、今のところこれは完璧です。あなたのforループでは

public static ArrayList<Integer> primeFactorize(int num) { 
    ArrayList<Integer> primeFactors = new ArrayList<Integer>(); 

    int i = 2; 
    while (i < Math.sqrt((double) num)) { 
     if (isPrime(i) && num % i == 0) { 
      primeFactors.add(i); 
      num /= i; 

      if (isPrime(num)) { 
       primeFactors.add(num); 
       break; 
      } 
      i = 2; 
     } 
     else 
      i++; 
    } 
    return primeFactors; 
} 
+0

sqrt(num)ではなく、sqrt(i)。だからnum = 12で、6はsqrt(num)より大きい – FredK

答えて

4

i++セクションでは、すべてのループの最後に呼び出されます。だからあなたのコードでは、あなたは、ループが終了し、その後、2に等しいiを設定し、iに1を加算して、それが3も作るその後の比較が発生し、3はSQRT以上である(6)、ループを抜けるようにします。

あなたはiは、次の反復で2になりたい場合は、あなたが後にインクリメント操作は、それが前に2、ないになります実行さように値を設定する必要があります。この場合は、1に設定する必要があります。コード構造を変更して、必要ではないようにする方がよい場合があります。 As pointed out by biziclopwhileループを使用すると、増分するかどうかを決めることができ、この問題を回避できます。あなたはすでに答えを受け入れたので

+0

私はそれが私と何か関係があることを知っていた+ +、私はその笑、おかげで逃したと信じられない! – MegaAmoonguss

+1

一般的なアドバイス:ループ本体からループ変数を操作する場合は、 'for'ループを使用しないでください。 'while'を使うと、コードをもっとはっきりさせることができます。 2つのポイント間の単純なループのために 'for'を保つ。 – biziclop

+0

なぜ関数'factor() 'を使うのですか?現在の 'i'の値が' num'の要素であるかどうかを知りたいので、 '(num%i)== 0'で十分です。 – FredK

3

私はあなたの問題が解決されると仮定します。私が指摘したいことは、整数を倍精度にキャストすることは、別の方法があれば一般的には悪い考えです。したがって、浮動小数点演算を使用しない以下の実装をお見せしたいと思います。また、アルゴリズムが遅くなるので、numが素数であるかどうかをチェックすることは悪い考えです。 num % i == 0がtrueと評価された場合また、iは、このようにisPrime(i)チェックは不要であり、また、お使いのアルゴリズムが遅くなり、常に素数です。

List <Integer> primeFactors(int n) { 
    List<Integer> factors = new ArrayList<>(); 
    for (int i = 2; i <= n/i; ++i) { 
     while (n % i == 0) { 
      factors.add(i); 
      n /= i ; 
     } 
    } 
    if (n > 1) { 
     factors.add(n); 
    } 
    return factors ; 
} 
+0

本当に素敵なコード、ありがとう!私はコードをより効率的にする方法について聞くのは良いことです。高校生として、あなたは本当にあまり覚えていないことを考慮してください。 – MegaAmoonguss

+0

あなたは歓迎です、あなた(または私)がランタイム比較を行うべきです;)。 btw up-voteはいつも歓迎です:) – martijnn2008

+0

私は5つのもののようにupvoteしようとしましたが、私はまだ十分な評判を持っているとは思えません。 – MegaAmoonguss

関連する問題