Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中获取一个数字的因子数量的最快方法是什么_Java_Algorithm_Math - Fatal编程技术网

Java中获取一个数字的因子数量的最快方法是什么

Java中获取一个数字的因子数量的最快方法是什么,java,algorithm,math,Java,Algorithm,Math,我正在尝试用Java编写一个函数,它将返回一个特定数字的因子数 应考虑以下限制 它应该用biginger完成 不允许存储以前生成的数字,因此处理更多,内存更少。(您不能像中那样使用“Atkin筛选”) 负数可以忽略 这是我到目前为止所做的,但是速度非常慢 public static int getNumberOfFactors(BigInteger number) { // If the number is 1 int numberOfFactors = 1; if (

我正在尝试用Java编写一个函数,它将返回一个特定数字的因子数

应考虑以下限制

  • 它应该用biginger完成
  • 不允许存储以前生成的数字,因此处理更多,内存更少。(您不能像中那样使用“Atkin筛选”)
  • 负数可以忽略
  • 这是我到目前为止所做的,但是速度非常慢

    public static int getNumberOfFactors(BigInteger number) {
        // If the number is 1
        int numberOfFactors = 1;
    
        if (number.compareTo(BigInteger.ONE) <= 0)  {
            return numberOfFactors;
        }
    
        BigInteger boundry = number.divide(new BigInteger("2"));
        BigInteger counter = new BigInteger("2");
    
        while (counter.compareTo(boundry) <= 0) {
            if (number.mod(counter).compareTo(BigInteger.ZERO) == 0) {
                numberOfFactors++;
            }
    
            counter = counter.add(BigInteger.ONE);
        }
    
        // For the number it self
        numberOfFactors++;
    
        return numberOfFactors;
    }
    
    public static int getNumberOfFactors(BigInteger数字){
    //如果数字是1
    int numberOfFactors=1;
    
    如果(number.compareTo(biginger.ONE)我可以提出更快的解决方案,尽管我感觉它还不够快。您的解决方案在
    O(n)
    中运行,而我的解决方案将在
    O(sqrt(n))中运行。

    我将使用这样一个事实,如果n=xi1p1*xi2p2*xi3p3*…xikpk是
    n
    (即xij都是不同的素数)的素因子分解,那么n总共有(p1+1)*(p2+1)*…*(pk+1)因子

    现在,解决方案是:

    BigInteger x = new BigInteger("2");
    long totalFactors = 1;
    while (x.multiply(x).compareTo(number) <= 0) {
        int power = 0;
        while (number.mod(x).equals(BigInteger.ZERO)) {
            power++;
            number = number.divide(x);
        }
        totalFactors *= (power + 1);
        x = x.add(BigInteger.ONE);
    }
    if (!number.equals(BigInteger.ONE)) {
        totalFactors *= 2;
    }
    System.out.println("The total number of factors is: " + totalFactors);
    
    BigInteger x=新的BigInteger(“2”);
    长期总因子=1;
    而(x.multiply(x).compareTo(number)则有一些改进:

  • 您只需要检查sqrt(n),而不是n/2。这使得您的算法是O(sqrt(n))而不是O(n)
  • 您只需在检查2后检查奇数,这将使速度加倍
  • 虽然您不能使用前面的数字,但您可以使用已知的素数和少量存储构建一个筛子:2,3是素数,因此只需检查(例如)11,13,17,19,23,而不是12,14,15,16,18。因此,您可以存储3:[+2,+4]的增量模式,每6次重复一次:
  • var delta=[2,4];
    var周期=6;
    var=3;
    var i=0;
    
    而Boris Strandjev提出的(val最快的解决方案在Java中生成大量输出时存在一些问题。 这是Java中查找大整数除数的最快算法

    以下是我将成功运行的代码:

    import java.math.BigInteger;
    import java.util.Scanner;
    
    class ProductDivisors {
    
        public static BigInteger modulo=new BigInteger("1000000007");
        public static BigInteger solve=new BigInteger("1");
        public static BigInteger two=new BigInteger("2");
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Scanner sc=new Scanner(System.in);
            int N=sc.nextInt();
            BigInteger prod=new BigInteger("1");
            while(N-->0){
                prod=sc.nextBigInteger();
                solve=solve.multiply(prod);
            }
            BigInteger x = new BigInteger("2");
            BigInteger total = new BigInteger("0");
            BigInteger totalFactors =new BigInteger("1");
            while (x.multiply(x).compareTo(solve) <= 0) {
                int power = 0;
                while (solve.mod(x).equals(BigInteger.ZERO)) {
                    power++;
                    solve = solve.divide(x);
                }
                total = new BigInteger(""+(power + 1));
                totalFactors=totalFactors.multiply(total);
                x = x.add(BigInteger.ONE);
            }
            if (!(solve.equals(BigInteger.ONE))) {
                totalFactors =totalFactors.multiply(two);
            }
            totalFactors=totalFactors.mod(modulo);
            System.out.println(totalFactors);
        }
    
    }
    
    import java.math.biginger;
    导入java.util.Scanner;
    类乘积因子{
    公共静态BigInteger模=新的BigInteger(“100000007”);
    公共静态BigInteger solve=新的BigInteger(“1”);
    公共静态BigInteger 2=新的BigInteger(“2”);
    公共静态void main(字符串[]args){
    //TODO自动生成的方法存根
    扫描仪sc=新的扫描仪(System.in);
    int N=sc.nextInt();
    BigInteger产品=新的BigInteger(“1”);
    而(N-->0){
    prod=sc.nextbiginger();
    求解=求解。乘法(prod);
    }
    BigInteger x=新的BigInteger(“2”);
    BigInteger总计=新的BigInteger(“0”);
    BigInteger totalFactors=新的BigInteger(“1”);
    
    while(x.multiply(x).compareTo(solve)如果存在重复的因子,例如2*2*2将返回2(1代表2,1代表4),则此操作也会失败@PeterLawrey不是真的-他迭代所有因子,从不进行除法运算。因子分解可能非常慢,以至于在某些密码算法中使用。它被称为,9000是对的,这不是一个容易的问题。@PeterLawrey问题从来没有说它应该只返回素数因子的数目。从问题的措辞来看,我假设8的因子数应该返回4(1,2,4,8)相当快?该代码在您的计算机上运行多长时间
    10000007^2
    我把它减少到22。也许你是对的,在极端情况下,它没有我声称的那么快,但我想不出更好的解决方案。@Betlista btw用long替换所有大整数将时间减少到3秒。遗憾的是,
    biginger
    在这里有很大的限制。要稍微加快速度,请添加一个fi第一次,然后再加上两个。例如2,3,5,7…。这将使运行时间减半。看起来这将返回4对9…你不是把平方根作为一个因子计算两次吗?我认为你的代码至少在n=9或n=49时工作不好。关于周期的想法可能是“跳过以0,2,4,5,6,8中的一个结尾的数字”,所以delta是4,2,2,2,从3开始-检查10个数字中的4…9可以被3整除,所以检查3应该在循环之外进行。49可以被7整除,7在第一次迭代中被选为3的+4 delta。49在第八次迭代中也会被+4 delta击中。delta[0]是2,所以您正在检查5,9,11,15。。。(跳过素数7和13)如果存在
    val
    条件,如何命中49?缺少计数的初始化,但我猜是2@Betlista:谢谢您的检查,我没有在列表末尾添加正确的内容。我应该添加6-4(最终的增量),而不是添加6。这样您可以得到5,7,11,13,17,19
    import java.math.BigInteger;
    import java.util.Scanner;
    
    class ProductDivisors {
    
        public static BigInteger modulo=new BigInteger("1000000007");
        public static BigInteger solve=new BigInteger("1");
        public static BigInteger two=new BigInteger("2");
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Scanner sc=new Scanner(System.in);
            int N=sc.nextInt();
            BigInteger prod=new BigInteger("1");
            while(N-->0){
                prod=sc.nextBigInteger();
                solve=solve.multiply(prod);
            }
            BigInteger x = new BigInteger("2");
            BigInteger total = new BigInteger("0");
            BigInteger totalFactors =new BigInteger("1");
            while (x.multiply(x).compareTo(solve) <= 0) {
                int power = 0;
                while (solve.mod(x).equals(BigInteger.ZERO)) {
                    power++;
                    solve = solve.divide(x);
                }
                total = new BigInteger(""+(power + 1));
                totalFactors=totalFactors.multiply(total);
                x = x.add(BigInteger.ONE);
            }
            if (!(solve.equals(BigInteger.ONE))) {
                totalFactors =totalFactors.multiply(two);
            }
            totalFactors=totalFactors.mod(modulo);
            System.out.println(totalFactors);
        }
    
    }