【问题标题】:How can I determine extremely large prime factors?如何确定极大的素因数?
【发布时间】:2014-02-26 23:40:28
【问题描述】:

所以我试图找到关于欧拉项目的问题 3 的答案。我需要确定给定数字的最大素数。

引用 Project Euler : “13195 的质因数是 5、7、13 和 29。 数字 600851475143 的最大质因数是多少?"

我已经构建了我的代码,它可以完美地适用于任何 int 大小的东西。 但由于他们给出的数量巨大,我的代码存在转换问题。

最初我尝试切换到长变量和长数组,但出现错误: '从 long 到 int 的可能有损转换'

那么我怎样才能让我的代码接受极长的数字呢?

public class Test {

long[] delers;

public static void main(String[] args) {
    Test test = new Test();
    test.determineDividers(600851475143,determineNumberOfDividers(600851475143));
    long a = test.determineHighestPrime(test.delers);
    System.out.println(a);
}

public void determineDividers(long getal,long aantalDelers) {
    delers= new long[aantalDelers];
    long k = 0;
    for (long i = 1; i < getal; i++) {
        if (getal % i == 0) {
            delers[k]=i;
            k++;                
        }
    }
}

public long determineNumberOfDividers(long getal) {
    int k = 0;
    for (long i = 1; i < getal; i++) {
        if (getal % i == 0) {
            k++;               
        }
    }
    return k;
}

public boolean determinePrime(long getal) {
    for (long i = 2; i < getal; i++) {
        if (getal % i == 0) {
            return false;
        }
    }
    return true;
}

public long determineHighestPrime(long[] deler) {
    for (long i = deler.length - 1; i > 0; i--) {
        if (determinePrime(deler[i]) == true) {
            return deler[i]);
        }
    }
    return 0;
}

}

感谢您的宝贵时间

编辑 1:从 PE 添加示例。

编辑 2:添加解决方案

public class Test {

long[] delers;

public static void main(String[] args) {
    Test test = new Test();
    test.determineDividers(600851475143L,test.determineNumberOfDividers(600851475143L));
    long a = test.determineHighestPrime(test.delers);
    System.out.println(a);
}

public void determineDividers(long getal,int aantalDelers) {
    delers= new long[aantalDelers];
    int k = 0;
    for (long i = 1; i < getal; i++) {
        if (getal % i == 0) {
            System.out.println(i);
            delers[k]=i;
            k++;                
        }
    }
}

public int determineNumberOfDividers(long getal) {
    int k = 0;
    for (long i = 1; i < getal; i++) {
        if (getal % i == 0) {
            k++;               
        }
    }
    return k;
}

public boolean determinePrime(long getal) {
    for (long i = 2; i < getal; i++) {
        if (getal % i == 0) {
            return false;
        }
    }
    return true;
}

public long determineHighestPrime(long[] deler) {
    for (int i = deler.length - 1; i > 0; i--) {
        if (determinePrime(deler[i]) == true) {
            return deler[i];
        }
    }
    return 0;
}

}

【问题讨论】:

  • 在那些巨大的常量后面加上一个L,即600851475143L,告诉Java它们必须是long
  • 您也可以考虑转到BigDecimalBigInteger 课程。它们专为处理任何大小的数字而设计。
  • 您必须将L 添加到两个常量。
  • “确定给定数的最大素因数”你不必存储它的所有素因数,更不用说它的所有除数,所以不必知道他们有多少。 -- 只需使用long。 -- 如果n=a*ba 是素数,那么n 的素数分解是a 加上b = n / a 的素数分解,对吧? ... 如果 n=2*bb 不能被 2,3,4,5,6 整除,但 7 将其整除,则 b=7*cc 可以不能被2,3,4,5,6 - 因为否则 b 会。对吗?
  • @ajb 对。再一次,如果n=a*b where a&lt;=b 然后是a*a &lt;= a*b = n,所以当我们通过i=7,8,9,... 测试c 时,当我们到达i 这样i*i &gt; n,我们真的需要测试c (i+1) 或者我们现在是否已经知道 c 素数?

标签: java primes long-integer


【解决方案1】:

设置数组时,数组的大小必须为int。因此,这个:

delers= new long[aantalDelers];

不会编译,因为您将参数aantalDelers 声明为long。但是,当您调用determineDividers 时,您为aantalDelers 传递的值是determineNumberOfDividers 的结果,您将其声明为返回long,但该函数显示return k,而k 是一个@ 987654331@.

所以我认为您可以更改determineNumberOfDividers 使其返回int 而不是long,并将aantalDelers 参数更改为int 而不是long。这样您就可以避免任何long-to-int 转换。此外,在您使用ki 作为数组索引的地方,并且您将它们声明为long,这些也应更改为int

在我的脑海中,我认为这会起作用,因为我认为最多 263 的数字不能有超过 231 个除数。但是如果我的数学是错误的并且它可以,那么除了数组之外你还需要一些其他的机制。 (事实上​​,无论如何你可能需要想出另一种算法;我感觉这个算法需要很长时间才能运行。)

【讨论】:

  • 重新更新了 OP。我仍然在“test.determineDividers(600851475143L,test.determineNumberOfDividers(600851475143));”处收到错误说明:整数太大 600851475143
【解决方案2】:

将所有“巨大”的变量更改为 BigInteger。您需要更新您的 Math 以使用函数调用而不是 java 操作数,但它们都在 BigInteger 中可用。

【讨论】:

  • 这不是必需的。 600851475143 与long 的最大值 18446744073709551616 相差甚远。
  • 是的。最后一个问题是“那么我怎样才能让我的代码接受极长的数字?”。我想我会直接回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-31
  • 2015-03-07
  • 2013-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多