2017-03-20 12 views
1

素因数分解 - ユーザに数字を入力させ、すべての素因数(存在する場合)を見つけて表示させます。プログラムの素因数分解Javaのプログラム

私は、数字が素数であるかどうかを検証するための方法と、ユーザーからの入力番号が素数を分けることができるかどうかを確認する方法を作成しました。

私はなぜプログラムが動作していないのか、forループ(機能的操作を使うことができる)の問題を理解できません。私を助けてください!
初心者ですが、このコードを改善するためのアドバイスをいただければ幸いです。

import java.util.ArrayList; 
import java.util.Scanner; 


public class PrimeFactors { 
    int count, input, num; 
    Scanner sc = new Scanner(System.in); 
    ArrayList<Integer> factors = new ArrayList(); 

    public static void main(String[] args) { 
     PrimeFactors pfo = new PrimeFactors(); 
     pfo.primeFactor(); 


    } 

    public void primeFactor(){ 
     input = sc.nextInt(); 
     for(num = input; num <= 1; num--){ 
      System.out.println(input); 
      if(isPrime(num)){ 
       if (divide(num)) { 
        System.out.println("Adding a new int..."); 
        factors.add(num); 
        num = input; 
       } 
      } 
     } 
     for(int element : factors){ 
      System.out.println(factors.get(element)); 
     } 
    } 

    public boolean isPrime(int number){ 
     for(int i = 2; i < number; i++){ 
      if(number % i == 0){ 
       count++; 
      } 
     } 
     return (count == 0); 
    } 

    public boolean divide(int number){ 
     return (input % number == 0); 
    } 

} 
+3

'(NUM =入力; NUM <= 1; NUM - ){' 'あなたはもしかして> ='ここに? –

+0

エラーが表示されますか?あなたの 'divide'関数は' input%num'を呼び出しますが、その時点で入力がセットされていますか?また、多くのコードをすばやく最適化できます。例えば、あなたの 'isPrime'関数では、まず分数を2でチェックし、次にi = 3からループし、毎回2をインクリメントするのはどうですか? (つまり、チェックオッズのみ)。そして、要因を見つけると即座に「中断する」。 –

答えて

1

インスタンス変数を使用する必要がある場合は、グローバル変数を使用していました。ジョニーが指摘したようないくつかのタイプミス。私が変更した大きな事は、私がこのプログラムを再帰的にしたことでした。できるだけグローバル変数から遠ざかるようにしてください。それは事をより混乱させます(primeFactorメソッドはグローバル変数を使用するよりも、変数を取るべきです)。

public class PrimeFactors { 
    int count; 
    static int input; 
    int num; 
    static Scanner sc = new Scanner(System.in); 
    static ArrayList<Integer> factors = new ArrayList(); 

    public static void main(String[] args) { 
     PrimeFactors pfo = new PrimeFactors(); 
     input = sc.nextInt(); 
     pfo.primeFactor(); 
     for(int element : factors){ 
      System.out.println(element); 
     } 
    } 

    public void primeFactor(){ 
     if (input > 1) { 

      for(int i = input; i >= 1; i--){ 
       if(isPrime(i)){ 
        if (divide(i)) { 
         System.out.println("Adding a new int..."); 

         factors.add(i); 
         input = input/i; 
         primeFactor(); 
        } 
       } 
      } 

     } 
    } 

    public boolean isPrime(int number){ 
     int count = 0; 
     for(int i = 2; i < number; i++){ 
      if(number % i == 0){ 
       count++; 
      } 
     } 
     return (count == 0); 
    } 

    public boolean divide(int number){ 
     return (input % number == 0); 
    } 
} 

これは私のprimeFactorsの解決方法です。私は素数リストの部分を計算しなかった。ストリームはかなり素晴らしいです、私はプロジェクトオイラーの問題を解決する際にストリームを使用しようとしていました。

private static ArrayList<Integer> primeFactors(int number) { 
     return primeFactors(new ArrayList<Integer>(), number); 
    } 

    private static ArrayList<Integer> primeFactors(ArrayList<Integer> primeFactors, int number) { 
     if (number == 1) { 
      return primeFactors; 
     } 

     int newPrime=primeDividor(number); 
     primeFactors.add(newPrime); 
     return primeFactors(primeFactors, number/newPrime); 
    } 

    private static int primeDividor(int input) { 
     return primes.stream() 
        .filter(e -> input % e == 0) 
        .findFirst() 
        .orElse(input); 
    } 
1

コードには複数の問題があります。まず、primeFactorのループは、1より大きい数値に対しては決して実行されません。それを修正するには、forループをfor(num = 1; num <= input; num++)に変更して、1から入力するすべての値をテストします。しかし、後でnumを入力で上書きするので、ループから自動的に切り離されます。

第2に、isPrime関数の先頭にcountをゼロに設定せず、isPrime関数に対してローカルにすることはありません(別の場所では使用されません)。

第3に、ファクターをコールする必要はありません。イテレーターでforループを使用する場合は、宣言した変数に値が含まれています。したがって、factors.get(element)への呼び出しを削除し、elementを使用するだけです。

これらの変更により、コードに適切な動作が得られます。最適化できる他の方法もあります。

  • 機能の名前を正しく指定してください。 divideはisDivisibleと呼び、2つの引数、つまり数値と除数を受け入れる必要があります。
  • メンバ変数を関数に対してローカルにすることはできません。これは副作用を取り除く。現在のクラスの変数はすべてローカルでなければなりません。
  • 篩の数字で割り切れるかどうかを確認する前に、篩のエラトステネスを構築してください。それは、それ自身より小さなあらゆる数で割るよりはるかに速くなります。あなたは、私はそれを改善することができますどのように私にいくつかのより多くのアドバイスを与える場合

    import java.util.ArrayList; 
    import java.util.Scanner; 
    
    
    public class PrimeFactors { 
        int count, input, num; 
    Scanner sc = new Scanner(System.in); 
    ArrayList<Integer> factors = new ArrayList(); 
    
    public static void main(String[] args) { 
        PrimeFactors pfo = new PrimeFactors(); 
        pfo.primeFactor(); 
    } 
    
    public void primeFactor(){ 
        input = sc.nextInt(); 
        for(num = 1; num <= input; num++){ 
         if(isPrime(num)){ 
          if (divide(num)) { 
           System.out.println("Adding a new int..."); 
           factors.add(num); 
          } 
         } 
        } 
        for(int element : factors){ 
         System.out.println(element); 
        } 
    } 
    
    public boolean isPrime(int number){ 
        int count = 0; 
    
        for(int i = 2; i < number; i++){ 
         if(number % i == 0){ 
          count++; 
         } 
        } 
        return (count == 0); 
    } 
    
    public boolean divide(int number){ 
        return (input % number == 0); 
    } 
    } 
    
+0

25は機能しません。5と1を与えます。 –

+0

あなたは正しいです。ループは2で始まります(1は素数ではないため)。素数として5を得るだけです。 – Lunar

0

私はすべてのあなたのアドバイスに耳を傾け、私はエラトステネスのふるいを使用して私のプログラムを改善し、また、私は非常に感謝されます。

ため
public class PrimeFactors { 
    static int input; 
    static Scanner sc = new Scanner(System.in); 
    static ArrayList<Integer> factors = new ArrayList(); 

    public static void main(String[] args) { 
     PrimeFactors pfo = new PrimeFactors(); 
     SieveOfEratosthenes sieveObj = new SieveOfEratosthenes(); 

     input = sc.nextInt(); 

     sieveObj.findAllPrimeFactors(input); 
     pfo.divisiblePrimeFactors(sieveObj.allPrimeFactors); 

     for(int element : factors){ 
      System.out.println(element); 
     } 
    } 

    public void divisiblePrimeFactors(ArrayList<Integer> allPrimeFactors){  
     if(input > 1){ 

      for(int element : allPrimeFactors){ 
       if(isDivisible(element, input)){ 
        factors.add(element); 
        input = input/element; 
        divisiblePrimeFactors(allPrimeFactors); 
       }  
      } 
     }  
    } 

    public boolean isDivisible(int number, int divisor){ 
     return (divisor % number == 0); 
    } 
} 

public class SieveOfEratosthenes { 

    ArrayList<Integer> allPrimeFactors= new ArrayList(); 

    public void findAllPrimeFactors(int limit){ 
     boolean[] isPrime = new boolean[limit]; 
     isPrime[0] = false; 
     isPrime[1] = false; 

     for(int i = 1; i < limit; i++){ 
      isPrime[i] = true; 
     } 

     for(int i = 2; i < limit; i++){ 
      if(isPrime[i]){ 
       allPrimeFactors.add(i); 
      } 
      for(int j = i*i; j < limit; j+=i){ 
       isPrime[j] = false; 
      } 
     } 
    } 
} 
+0

これは答えや質問のようには見えません。作業コードのコードレビューが必要な場合は、別のサイトがあります。あなたの特定の質問については、回答があったと思いますので、既存の回答の1つを受け入れることができます。 – eis

+0

まだ入力を汎用変数として使用していますが、これは起こりません。あなたの関数は引数として入力を取ります。私は、私が意味することを示す素数を考慮する関数を投稿します。 –

0
public class Prime 
{ 
    int i; 

    public Prime() 
    { 
     i = 2; 
    } 

    public boolean isPrime(int test) 
    { 
     int k; 

     if(test < 2) 
     return false; 
    else if(test == 2) 
     return true; 
    else if((test > 2) && (test % 2 == 0)) 
     return false; 
    else 
    { 
     for(k = 3; k < (test/2); k += 2) 
     { 
      if(test % k == 0) 
       return false; 
     } 

    } 

     return true; 

    } 

    public void primeFactors(int factorize) 
    { 
     if(isPrime(factorize)) 
     { 
     System.out.println(factorize); 
     i = 2; 
     } 
     else 
     { 
     if(isPrime(i) && (factorize % i == 0)) 
     { 
      System.out.print(i+", "); 
      primeFactors(factorize/i); 
     } 
     else 
     { 
      i++; 
      primeFactors(factorize); 
     } 
    } 

    } 

    public static void main(String[] args) 
    { 
     Prime p = new Prime(); 

     p.primeFactors(1001); 
     p.primeFactors(649); 
     p.primeFactors(144); 

    } 

}//end Prime.java 
+0

素因数分解は、バイナリの電気状態1と0がブール代数に対して行うように、再帰的なコードの実装に自然に役立ちます!それは完璧にフィットするので、私はそれを他の方法で書くことは考えられませんでしたが、間違いなくそうする他の方法があります。再帰を使用する場合の簡単なタスク。 – user2710322

関連する問題