这是一个Java程序,它在给定范围内找到第n个素数。 可输入的最大范围是1-1500000。 代码输出对于所有可能的测试用例都是正确的,但必须针对运行时进行优化。 此代码中可以应用哪些优化技术?
import java.io.*;
class prime
{
public static void main(String[] args)throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String m1,m2,m;
int n1=0,n2=0,n=0;
try
{
//input as string instead of integer because errors must be displayed only after all the values have been input
m1=br.readLine(); //range minimum value
m2=br.readLine(); //range max value
m=br.readLine(); //nth value in range
n1=Integer.parseInt(m1);
n2=Integer.parseInt(m2);
n=Integer.parseInt(m);
if(n1<0||n2>1500000||n1>n2||n==0)
throw new Exception();
}
catch(Exception e)
{
System.out.println("Invalid Input");
System.exit(0);
}
int k=n1,count=0,count1=0;
while(k<=n2&&count1<=n)
{
count=0;
for(int i=1;i<=k;i++)
{
if(k%i==0)
count++;
}
if(count==2)
{
count1++;
}
k++;
}
if(count1==n)
{
System.out.println(k);
System.exit(0);
}
if(count1<n)
{
System.out.println("No prime number is present at this index");
System.exit(0);
}
}
}
答案 0 :(得分:0)
检查2和k的平方根之间的除数。如果你找不到,你就找到了一个黄金。
int k=n1,count1=0;
while(k<=n2&&count1<=n)
{
boolean isPrime = true;
for(int i=2;i <= Math.sqrt(k) ;i++)
{
if(k%i==0)
{
isPrime = false;
break;
}
}
if (isPrime)
count1++;
k++;
}
此外,您可以明确处理2并跳过其他偶数。
答案 1 :(得分:0)
不要测试&#34;正好有2个除数&#34;,test&#34;不能被1和1以外的数字整除&#34;。
不要将所有值&lt; = k作为除数进行测试,测试所有值&lt; = sqrt(k)。
(如果一个数字可以被大于sqrt(k)的数字整除,那么除法的结果也是一个除数,但是之前已经找到了)
也许重用已经计算过的素数;您只需要将素数作为可能的除数进行测试。但是你需要小心。如果你是在9999-9999范围内搜索,计算所有较小的素数是没有意义的,但是如果范围是1-9999,它会减少你必须进行的检查次数。您可以将两种方法和小于n1的测试数字结合起来&#34; normal&#34;使用你已经找到的素数来测试所有较大的除数。
您的循环可以像这样重写以应用1.和2。:
int k=Math.max(2, n1); // 0 and 1 are no prime
int count1 = 0;
while(k <= n2 && count1 <= n) {
final int sqrt = (int) Math.sqrt(k);
count1++; // asume it's a prime
for(int i = 2; i <= sqrt; i++) {
if(k % i == 0) {
// divisible by number other than 1 and itself -> not a prime
count1--;
break;
}
}
k++;
}
这会将运行时间从O((n2)² - (n1)²)
缩短为
答案 2 :(得分:0)
由于您的最大值是有限的,因此保留一个2到1229(1229²= 1510441)的素数表是有意义的,并依次尝试它们,直到数字小于素数的平方。 2可以不经分割地进行测试。您还可以存储正方形的表格。
2 3 5 7 11 13 17 19 23 29
31 37 41 43 47 53 59 61 67 71
73 79 83 89 97 101 103 107 109 113
127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199 211 223 227 229
233 239 241 251 257 263 269 271 277 281
283 293 307 311 313 317 331 337 347 349
353 359 367 373 379 383 389 397 401 409
419 421 431 433 439 443 449 457 461 463
467 479 487 491 499 503 509 521 523 541
547 557 563 569 571 577 587 593 599 601
607 613 617 619 631 641 643 647 653 659
661 673 677 683 691 701 709 719 727 733
739 743 751 757 761 769 773 787 797 809
811 821 823 827 829 839 853 857 859 863
877 881 883 887 907 911 919 929 937 941
947 953 967 971 977 983 991 997 1009 1013
1019 1021 1031 1033 1039 1049 1051 1061 1063 1069
1087 1091 1093 1097 1103 1109 1117 1123 1129 1151
1153 1163 1171 1181 1187 1193 1201 1213 1217 1223
1229