Делаем мою программу проверки простых/идеальных/составных чисел более эффективной/чистой

Эта программа запрашивает у пользователя минимальное число больше 1 и максимальное число больше минимального. Затем он выводит число за числом, на что оно делится, является ли оно простым или составным, и если это совершенное число в следующем формате:

2 is divisible by 1
2 is prime.
2 is not perfect

3 is divisible by 1
3 is prime.
3 is not perfect

4 is divisible by 1 2 
4 is composite.
4 is not perfect.

5 is divisible by 1
5 is prime.
5 is not perfect

6 is divisible by 1 2 3 
6 is composite.
6 is perfect.

В конце отображается количество простых и совершенных чисел. Программа работает, но мне интересно, есть ли способы очистить код/сделать его более эффективным (или если я что-то делаю не так)

Код:

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Scanner input = new Scanner(System.in);

    int min;
    int max;

    //declaring min and max values

    System.out.println("Enter minimum value to check (an integer greater than 1:)");
    min=input.nextInt();

    while(!(min>1)) {
        System.out.println("The entry is valid. Please be sure to enter an integer greater than 1");
        System.out.println();
        System.out.println("Enter minimum value to check (an integer greater than 1:)");
        min=input.nextInt();
    }

    System.out.println("Enter maximum value to check (an integer greater than your min value:)");
    max=input.nextInt();

    while(!(max>min)) {
        System.out.println("The entry is valid. Please be sure to enter an integer greater than the min value");
        System.out.println();
        System.out.println("Enter maximum value to check (an integer greater than min:)");
        max=input.nextInt();
    }

    //declaring count and tracking variables

    int count;
    int numPrime=0;
    int numPerfect=0;
    int temp=1;
    String result=" ";
    boolean isPrime=true;
    boolean isPerfect=false;
    int i;
    //main loop

    for(count=min;count<=max;count++) {

        for(i=2;i<=count;i++) {
            if(count%i==0&&i!=count) {
                isPrime=false;
                result=result+i+" ";
                temp+=i;
            }
            else
                isPrime=true;
        }
        //Perfect counter
        if(temp==count) {
            isPerfect=true;
            numPerfect=numPerfect+1;
        }
        else
            isPerfect=false;
        //Composite print
        if(!(result.equals(" "))) {
            System.out.println(count+" is divisible by 1"+result);
            System.out.println(count+" is composite.");
            if(isPerfect==true)
                System.out.println(count+" is perfect.");
            else
                System.out.println(count+ " is not perfect.");
            System.out.println();
        }
        //Prime print
        else {
            numPrime=numPrime+1;
            System.out.println(count+" is divisible by 1");
            System.out.println(count+" is prime.");
            System.out.println(count+" is not perfect");
            System.out.println();
        }           
        //reset values
        result=" ";
        temp=1;
    }
    System.out.println("Primes found: "+numPrime);
    System.out.println("Perfect numbers found: "+numPerfect);


}

}


person rmcknst2    schedule 13.10.2017    source источник
comment
Если ваш код работает, я предлагаю опубликовать его на обзоре кода.   -  person Scary Wombat    schedule 13.10.2017
comment
Ок сделаю спасибо!   -  person rmcknst2    schedule 13.10.2017
comment
Поскольку это домашнее задание, я не хочу портить возможность обучения, но не могли бы вы уменьшить количество итераций цикла for? В частности, for(i=2;i‹=count;i++). Вам действительно нужно повторять от 2 до подсчета? Если count равен 144, значение i почти всегда не будет делителем 144. Зачем вам нужно выполнять итерацию, если i равно 133?   -  person JustinDanielson    schedule 13.10.2017
comment
@JustinDanielson о, хорошо, например, удалить делители, которые не будут работать, из пула проверяемых чисел?   -  person rmcknst2    schedule 13.10.2017
comment
да. 144/2 это 72, а на 144/72 надо проверять? В какой-то момент вы больше не найдете новых номеров. Простейшим порогом будет n/2, что сократит количество итераций вдвое. Но вы можете сделать лучше, чем это.   -  person JustinDanielson    schedule 14.10.2017


Ответы (1)


У меня есть хобби сделать мой идеальный числовой код Python максимально эффективным, поэтому я знаю несколько дополнительных вещей, повышающих эффективность, но, к сожалению, я не кодирую Java, поэтому это будут просто некоторые общие улучшения эффективности.

Во-первых, как было указано в комментариях, вам нужно только проверить квадратный корень числа, чтобы получить все делители, но вам нужно добавить число / ваши делители в список делителей, чтобы получить каждый делитель

e.g. Find the divisors of 20
The square root of 20 is 4.47 so we choose 4.
20 mod 1 == 0 so we add 1 and 20/1 a.k.a. 20 to our list of divisors
20 mod 2 == 0 so we add 2 and 20/2 a.k.a 10 to our list of divisors
20 mod 3 == 2 so we ignore this one.
20 mod 4 == 0 so we add 4 and 20/4 a.k.a. 5 to our list of divisors
Therefore the divisors are 1, 2, 4, 5, 10 and 20.

Еще одним хорошим улучшением эффективности является то, что все идеальные числа будут заканчиваться на 6 или 28, так что вы можете быстро это проверить.

Последнее улучшение эффективности, которое я знаю, — это большое изменение в бите простого вычисления.

If a number is smaller than or equal to 1 it is not prime.
Else if a number is smaller than or equal to 3 it is prime.
Else if a number mod 2 or a number mod 3 == 0 it is not prime.
Set i to 5
While i squared is smaller than or equal to a number:
    If a number mod i or a number mod (i + 2) == 0:
        It is not prime
    6 is added to i
If nothing has said otherwise then the number is prime.
person 13ros27    schedule 05.12.2017