Java - основные проблемы с вводом-выводом - PullRequest
2 голосов
/ 05 июля 2011

Я пытаюсь закодировать сито с эратосфенами, которое я намерен использовать, чтобы найти наибольший простой фактор 13195. Если это сработает, я собираюсь использовать его по номеру: 600851475143.

С момента созданиясписок чисел в диапазоне 2-600851475143 будет почти невозможен из-за проблем с памятью, я решил вместо этого хранить числа в текстовом файле.

Проблема, с которой я сталкиваюсь, заключается в том, что вместо получениятекстовый файл, заполненный числами, код создает файл только с одним номером (это мой первый раз, когда я работаю с IO в Java):

        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 ]

1 голос
/ 05 июля 2011

Не используйте 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, а не всю карту - сложность та же.

1 голос
/ 05 июля 2011

Ваш код продолжает открываться, писать и закрывать один и тот же файл.Вы должны сделать что-то вроде этого:

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();
}
0 голосов
/ 05 июля 2011

Сохранение непосредственно на диск выполняется медленнее, рассматривали ли вы сделать это по частям, а затем сохранить на диск?Это также может дать преимущество меньшего размера файла, поскольку вы можете записать только найденные простые числа вместо каждого составного числа.

0 голосов
/ 05 июля 2011

Вы перезаписываете свой файл при каждом прохождении цикла. Вам нужно открыть файл вне основного цикла.

    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();
0 голосов
/ 05 июля 2011

Вам нужно вывести файл из цикла.

0 голосов
/ 05 июля 2011

Вы воссоздаете свой файлописатель на каждой итерации цикла 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...