Java-提高简单素数验证器的性能

时间:2018-07-26 20:43:54

标签: java math calculation

我正在学习Java课,刚完成一个作业,但脑子里有一个问题。我还没有时间问我的教授,无论如何我们都在做些题外话。

基本上,我们有一个程序可以验证用户输入的整数是否为质数。如果不是素数,它将计算小于输入的最接近素数。例如:

Enter an integer: 4
4 is not a prime number. The closest prime number is 3.

如果输入不是素数,则程序使用循环按预期方式工作。这是我的代码:

public static void main(String[] args) {

    Scanner input = new Scanner(System.in);
    int number;

    System.out.print("Please enter a positive, non-zero integer: ");
    number = input.nextInt();
    input.close();

    if (isValid(number) == true) {
        if(isPrime(number) == true) {
            System.out.printf("%d is a prime number.", number);
        } else {
            switch(number) {
                case 1: 
                    System.out.print("1 is not a prime number. \n");
                    System.out.print("We cannot find the nearest prime.");
                    break;
                default:
                    System.out.printf("%d is not a prime number.", number);
                    System.out.printf("\nThe nearest prime number is %d.", getNearestPrime(number));
                }
            }
        } else {
        System.out.print("Invalid input. Please run again.");
        System.exit(1);
    }   
}

public static boolean isValid(int number) {

    if (number > 0) {
        return true;
    } else {
        return false;
    }
}

public static boolean isPrime(int number) {

    int i;
    if(number == 1) {
        return false;
    } else {
        for(i = 2; i < number; i++) {
            if(number%i == 0) {
                return false;
            }
        }
        return true;
    }
}

public static int getNearestPrime(int number) {

    do {
        number--;
    } while (isPrime(number) == false);

    return number;
}

请务必注意,我们必须创建以下main中列出的三种方法。

我的问题是:在这种情况下计算较大的整数时,是否可以提高性能?

如果我要输入2,147,483,647,该程序将花费大约10秒钟来识别它是素数。如果输入2,147,483,646,则需要花费几乎相同的时间来找到最接近的素数。

我完全理解为什么会发生这种情况,但是似乎我使用的任何高级Java应用程序都可以比简单程序更快地处理更复杂的事情。

我真的很好奇经验丰富的程序员如何处理这样的事情。谢谢!

2 个答案:

答案 0 :(得分:3)

您可以更改的几件简单的事情:

1)质数永远不会是偶数,因此一旦检查数字是否可被二整除,就不需要检查它是否能被其他偶数整除。因此,您可以稍微简化循环。 (只需添加一个if语句以检查数字是否为2,然后从三点开始i

2)您只需要循环直到数字的平方根即可。

  int i;
  if(number == 1) {
      return false;
  }
  if(number == 2) {
     return true; //2 is a prime number
  } 
  if (number % 2 == 0) {
     return false;
  }
  for(i = 3; i* i <= number; i+=2) {
      if(number%i == 0) {
          return false;
      }
  }
  return true;

答案 1 :(得分:0)

要注意的一件事是,在算法方面,有更有效的算法可以使用。 See this answer for details

关于实现,例如,如果您想提高性能,则可以采用一些技巧,例如缓存最近的结果。 一种更有效的方法(但可能不在课程范围内)是使用预先计算的素数列表。 您可以在互联网上找到一个,也可以运行一次程序以对它们进行预先计算,直到达到指定点。

请注意,为了提高速度,此方法将权衡一些内存。