我正在尝试编写一个eratosthenes的筛子,我打算用它来找到13195的最大素数因子。如果这样可行,我打算在数字上使用它:600851475143。
由于内存问题,创建一个范围为2-600851475143的数字列表几乎是不可能的,因此我决定将数字存储在文本文件中。
我遇到的问题是,代码只是生成一个带有数字的文本文件,而代码只生成一个带有一个数字的文件(这是我第一次使用Java中的IO相关内容):
long number = 13195;
long limit = (long) Math.sqrt(number);
for (long i = 2; i < limit + 1; i++)
{
try
{
Writer output = null;
File file = new File("Primes.txt");
output = new BufferedWriter(new FileWriter(file));
output.write(Long.toString(i) + "\n");
output.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
这是包含文本文件的输出: 114
我做错了什么?
答案 0 :(得分:1)
您的代码会不断重新打开,写入和关闭同一个文件。你应该这样做:
long number = 13195;
long limit = (long) Math.sqrt(number);
try
{
File file = new File("Primes.txt");
Writer output = new BufferedWriter(new FileWriter(file));
for (long i = 2; i < limit + 1; i++)
{
output.write(Long.toString(i) + "\n");
}
output.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
答案 1 :(得分:1)
不要使用Erathostenes - 除非你需要范围内的所有素数,否则它太慢了。
这是分解给定数字的更好方法。该函数返回一个映射,其中键是n的主要因子,值是它们的幂。例如。对于13195,它将是{5:1,7:1,13:1,29:1}
它的复杂性是O(sqrt(n)):
public static Map<Integer, Integer> Factorize(int n){
HashMap<Integer, Integer> ret = new HashMap<Integer, Integer>();
int origN = n;
for(int p = 2; p*p <= origN && n > 1; p += (p == 2 ? 1: 2)){
int power = 0;
while (n % p == 0){
++power;
n /= p;
}
if(power > 0)
ret.put(p, power);
}
return ret;
}
当然,如果你只需要最大的素数因子,你可以返回最后一个p而不是整个地图 - 复杂性是相同的。
答案 2 :(得分:0)
您正在for循环的每次迭代中重新创建文件编写器,而不是指定它追加,因此您将在每次迭代中覆盖您的文件。
尝试更改它以在for循环之前创建文件编写器并在循环之后关闭它。像这样:
long number = 13195;
long limit = (long) Math.sqrt(number);
Writer output = null;
try
{
File file = new File("/var/tmp/Primes.txt");
output = new BufferedWriter(new FileWriter(file));
for (long i = 2; i < limit + 1; i++) {
output.write(Long.toString(i) + "\n");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
output.close();
}
答案 3 :(得分:0)
您需要将文件实例化移出循环。
答案 4 :(得分:0)
您在循环中的每次传递都会覆盖您的文件。 您需要在主循环之外打开文件。
long number = 13195;
long limit = (long) Math.sqrt(number);
try
{
Writer output = null;
File file = new File("Primes.txt");
output = new BufferedWriter(new FileWriter(file));
catch (IOException e)
{
// Cannot open file
e.printStackTrace();
}
for (long i = 2; i < limit + 1; i++)
{
try
{
output.write(Long.toString(i) + "\n");
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
output.close();
答案 5 :(得分:0)
直接保存到磁盘的速度较慢,您是否考虑过这样做,然后保存到磁盘?它还可以具有较小文件大小的好处,因为您只能编写找到的素数,而不是每个复合数字。