Java 找到一个非常大的数字
所以,我试图找到最大的素因子600851475143。我有一个简单的方法,可以找到目前最大的一个:Java 找到一个非常大的数字,java,Java,所以,我试图找到最大的素因子600851475143。我有一个简单的方法,可以找到目前最大的一个: private static void findPrimeFactors(long num) { ArrayList<Long> list = new ArrayList<Long>(); for (long i = 1; i <= num; i++) { int lol = 0; for
private static void findPrimeFactors(long num) {
ArrayList<Long> list = new ArrayList<Long>();
for (long i = 1; i <= num; i++) {
int lol = 0;
for (int a = 1; a < i; a++) {
if (i % a == 0) {
lol++;
}
}
if (lol < 2) {
if (!list.isEmpty())
list.remove(list.size() - 1);
list.add(i);
}
}
System.out.println(list.get(list.size() - 1));
}
和20000:
19997
Done in 1774.0 milliseconds (1.774 seconds) (177.3702774 nano seconds)
正如你所看到的,在一个更大的数字中找到它需要相当长的时间。现在我应该在600851475143中找到我要找的号码,所以我可以说这需要一段时间。我想知道他们是否有更快的计算方法?这是我的全部代码:
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
try {
long num = 600851475143L;
long time = System.currentTimeMillis();
long timeNano = System.nanoTime();
findPrimeFactors(20000);
double finishTime = System.currentTimeMillis() - time;
double finishTimeNano = System.nanoTime() - timeNano;
System.out.println("Done in " + finishTime + " milliseconds (" + ((finishTime) / 1000) + " seconds)" + " (" + finishTimeNano / 10000000 + " nano seconds)");
} catch (Exception e) {
e.printStackTrace();
}
}
private static void findPrimeFactors(long num) {
ArrayList<Long> list = new ArrayList<Long>();
for (long i = 1; i <= num; i++) {
int lol = 0;
for (int a = 1; a < i; a++) {
if (i % a == 0) {
lol++;
}
}
if (lol < 2) {
if (!list.isEmpty())
list.remove(list.size() - 1);
list.add(i);
}
}
System.out.println(list.get(list.size() - 1));
}
}
import java.util.ArrayList;
公共班机{
公共静态void main(字符串[]args){
试一试{
长数=600851475143L;
长时间=System.currentTimeMillis();
long-timeNano=System.nanoTime();
findPrimeFactors(20000);
double finishTime=System.currentTimeMillis()-时间;
double finishTimeNano=System.nanoTime()-timeNano;
System.out.println(“完成时间为”+finishTime+“毫秒”(+((finishTime)/1000)+“秒)”+“(+finishTimeNano/10000000+“纳秒”);
}捕获(例外e){
e、 printStackTrace();
}
}
私有静态void findPrimeFactors(long num){
ArrayList=新建ArrayList();
对于(long i=1;i如果您正在寻找最大的因素,可以从最大的数字开始。类似这样的内容(未测试的代码):
私有静态void findPrimeFactors(long num){
龙我;
布尔候选;
对于(i=num;i>1;i--){
//我被选为首要因素
候选者=真;
对于(int a=2;候选者和&a提示,请加快:
- 您正在尝试边修改ArrayList,每次修改ArrayList都需要O(n)个时间。如果确实需要修改列表,请查看使用链接列表
- 你不需要测试所有的数字,只需要测试素数
首先你必须了解的是,你的任务本质上是“找到一个大数的素数因子”。如果你知道怎么做,你可以将你的大数除以找到的因子,然后进行一次循环
…但我很遗憾地告诉你,没有已知的算法可以在多项式时间内找到Laaaarge数的素因子。实际上,这是许多密码系统(例如著名的RSA)的基础
然而,现在600851475143这样的数字可以很快被分解。有很多算法可以做到这一点,但你必须学习一些数学才能理解它们
对于这个数字,我可以告诉您600851475143=71*839*1471*6857。您需要一个更好的算法。下面是一个简单的试用除法实现:
function factors(n)
f, fs := 2, []
while f * f <= n
while n % f == 0
append f to fs
n := n / f
f := f + 1
if n > 1 append n to fs
return fs
功能因子(n)
f、 fs:=2,[]
而f*f 1将n附加到fs
返回fs
我将让您使用适当的数据类型将伪代码转换为您最喜欢的编程语言。请注意,600851475143太大,无法存储在32位整数中,这是问题的一部分乐趣
如果你对解决涉及质数的Euler项目问题感兴趣,我谦虚地在我的博客上推荐这篇文章。这些质数<20000除以你的大数吗?这会很好地分解它。我想你可以看看这个。希望这能帮上忙。我现在正在测试它,真的需要一段时间……猜猜真的需要质数列表才能更快地工作…即使只使用质数因子,这也需要很长时间。顺便说一句,答案是600851475067。这是第23038900221个质数。在这里找到它:您可以在num
的swuare根启动candidate
循环,从而节省大量时间。此外,您还可以使用计算素数直到600851475143的平方根以节省更多的时间并将它们存储在集合中而不是列表中+1来解决密码系统就是基于这个问题,我也试过了!它工作得快多了,但仍然需要一段时间才能达到我想要的。答案应该是立即的。如果不是的话,您的实现有问题。
private static void findPrimeFactors(long num) {
long i;
boolean candidate;
for (i=num; i>1; i--){
// i is candidate to be prime factor
candidate=true;
for (int a=2; candidate && a<i; a++){
if (i % a == 0) candidate=false; // i is not prime.
}
if (candidate) break;
}
System.out.println(i);
}
import java.util.*;
public class PrimeFinder {
private static List<Long> finder (Long max){
List<Long> list=new ArrayList<Long>();
Long maxPrime=2L;
Long i;
boolean candidate=true;
for (i=2L;i<max;i++){
candidate=true;
for (Long prime:list){
if (i % prime==0) {candidate=false;break;}
}
if (candidate){
list.add(i);
System.out.println(i+" "+list.size());
maxPrime=i;
}
}
System.out.println(maxPrime);
return list;
}
public static void main(String[] argv){
finder(600851475143L);
}
}
function factors(n)
f, fs := 2, []
while f * f <= n
while n % f == 0
append f to fs
n := n / f
f := f + 1
if n > 1 append n to fs
return fs