Java中的程序Prime分解

时间:2017-03-20 19:06:54

标签: java

Prime Factorization - 让用户输入一个数字并找到所有Prime因子(如果有的话)并显示它们。

我创建了一个用于验证数字是否为素数的方法,另一个用于检查来自用户的输入数字是否可以除去素数。

我无法理解为什么程序不起作用以及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);
    } 

}

4 个答案:

答案 0 :(得分: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的解决方案。我省略了计算主要清单部分。 Streams非常棒,我很乐意在解决项目Euler问题时尝试使用它们。

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 :(得分:1)

您的代码存在多个问题。首先,primeFactor中的循环永远不会运行大于1的数字。您可以通过将for循环更改为for(num = 1; num <= input; num++)来测试从1到输入的所有值。但是你稍后用输入覆盖num,所以它会自动中断循环。

其次,你永远不会将isPrime函数开头的计数设置为零,并将它设置为isPrime函数的本地(它不在其他地方使用)。

第三,当使用带迭代器的for循环时,你不需要调用factors.get,你声明的变量包含值。因此,您应该移除对factors.get(element)的来电,并使用element

这些更改为您的代码提供了正确的行为。还有其他方法可以优化它。

  • 正确命名您的功能。 divide应该被称为isDivisible并接受两个参数,即数字和除数。
  • 当您可以将成员变量置于函数本地时,请避免使用成员变量。这摆脱了副作用。当前类中的所有变量都应该是本地变量。
  • 您之前应该构建一个Eratosthenes筛,然后验证您的数字是否可以被筛子中的数字整除。它会比按每个小于自身的数字快得多。

    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);
    } 
    }
    

答案 2 :(得分:0)

我听了你的所有建议,并且我使用了Eratosthenes的Sieve改进了我的程序,如果你能给我一些更好的建议,我将非常感激。如何能让它变得更好。

    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;
            }
        }
    }
}

答案 3 :(得分: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