Java-基本IO问题

时间:2011-07-05 06:55:37

标签: java io

我正在尝试编写一个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

我做错了什么?

6 个答案:

答案 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)

直接保存到磁盘的速度较慢,您是否考虑过这样做,然后保存到磁盘?它还可以具有较小文件大小的好处,因为您只能编写找到的素数,而不是每个复合数字。