我在Java中接受了一项家庭作业,创建了可以找到Prime数字等的类(你会在代码中更好地看到)。
我的代码:
class Primes {
public static boolean IsPrime(long num) {
if (num%2==0){
return false;
}
for (int i=3; i*i<=num;i+=2) {
if (num%i==0) {
return false;
}
}
return true;
} // End boolen IsPrime
public static int[] primes(int min, int max){
int counter=0;
int arcount=0;
for (int i=min;i<max;i++){
if (IsPrime(i)){
counter++;
}
}
int [] arr= new int[counter];
for (int i=min;i<max;i++){
if (IsPrime(i)){
arr[arcount]=i;
arcount++;
}
}
return arr;
} // End Primes
public static String tostring (int [] arr){
String ans="";
for (int i=0; i<arr.length;i++){
ans= ans+arr[i]+ " ";
}
return ans;
}
public static int closestPrime(long num){
long e = 0 , d = 0 , f = num;
for (int i = 2; i <= num + 1 ; i++){
if ((num + 1) % i == 0){
if ((num + 1) % i == 0 && (num + 1) == i){
d = num + 1;
break;
}
num++;
i = 1;
}
}
num = f;
for (int i = 2; i < num; i++){
if ((num - 1) % i == 0){
if ((num - 1) % i == 0 && (num - 1) == i){
e = num - 1;
break;
}
num--;
i = 1;
}
}
num = f;
if (d - num < num - e) System.out.println("Closest Prime: "+d);
else System.out.println("Closest Prime: "+e);
return (int) num;
} // End closestPrime
}//end class
我的代码的目标是更快(和更正确)。我在实现这个目标时遇到了困难。建议?
**新代码:
class Primes {
public static boolean IsPrime(int num) {
if (num==1){
return false;
}
for (int i=2; i<Math.sqrt(num);i++) {
if (num%i==0) {
return false;
}
}
return true;
}
// End boolen IsPrime
public static int[] primes(int min, int max){
int size=0;
int [] arrtemp= new int[max-min];
for (int i=min;i<max;i++){
if (IsPrime(i)){
arrtemp[size]=i;
size++;
}
}
int [] arr= new int[size];
for (int i=0;i<size;i++){
arr[i]=arrtemp[i];
}
return arr;
}
public static String tostring (int [] arr){
String ans="";
for (int i=0; i<arr.length;i++){
ans= ans+arr[i]+ " ";
}
return ans;
}
public static int closestPrime(int num) {
int count=1;
for (int i=num;;i++){
int plus=num+count, minus=num-count;
if (IsPrime(minus)){
return minus;
}
if (IsPrime(plus)) {
return plus;
}
count=count+1;
}
} // End closestPrime
}//end class
我确实试着让它好一些。你怎么看,它可以改进得更多? (速度测试仍然很高......)
答案 0 :(得分:1)
在您的primes
功能中:
问题出在最后一步。通过仔细检查每个数字是否为素数,您将复制最昂贵的操作。
您可以使用动态数据结构,并在找到时为其添加素数。这样你只需要检查一次。
或者,您可以创建一个布尔数组,该数组是您输入范围的大小。然后,当您找到素数时,将相应的数组值设置为true。
<强>更新强>
您仍然可以进行一些改进,但有些工作需要比其他工作更多的工作。查看测试的具体情况,看看哪些适合您的需求。
低调的果实:
ArrayList
收集素数,因为您在primes
中找到素数,而不是将值循环两次。 closestPrime
中,您正在检查num
两侧的每一个值:其中一半是偶数,因此不是素数。您可以调整代码以仅检查奇数的素数。实施的诡计:
IsPrime
尝试更高级的算法:查看Sieve of Eratosthenes 最重要的是,您应该花些时间确定代码中瓶颈的确切位置。通常,性能问题是由我们认为非常好的代码引起的。您可以考虑查看开发环境中可用的代码分析选项。
答案 1 :(得分:0)
你对isPrime()进行了不少调用,每个调用都非常昂贵。你的第一步应该是尽量减少你这样做的次数,因为对于任何给定的数字,结果都不会改变,没有必要多次调用。您可以通过在计算值后存储值来使用memoization执行此操作:
ArrayList<Integer> memoList = new ArrayList<Integer>();
for(int i = 0; i < max; i++) {
if(isPrime(i)) {
memoList.add(i);
}
}
现在memoList包含你需要的所有素数,最多可以max
,你可以快速遍历它们,而不需要每次都重新计算它们。
其次,您可以改进isPrime()
方法。你的解决方案循环遍历从3到sqrt(n)的每个奇数,但为什么不绕过素数,现在我们知道它们?
public static boolean IsPrime(long num) {
for(int p : memoList) {
if(num % p == 0) {
return false;
}
}
return true;
}
这些更改应该可以显着提高代码的运行速度,但是已经有很多研究甚至更有效的计算素数的方法。 Prime Numbers上的维基百科页面提供了一些关于你可以试验的进一步战术(尤其是优质筛子)的非常好的信息。
请记住,因为这是家庭作业,所以当你打开它时你应该确定引用这个页面。欢迎你使用和扩展这个代码,但不引用这个问题,你使用的任何其他资源都是抄袭。< / p>
答案 2 :(得分:0)
我发现你的答案有几个问题。首先,2是素数。你在IsPrime的第一个条件打破了这一点。其次,在你的素数方法中,你骑自行车从最小到最大的所有数字。您可以放心地忽略所有负数和所有偶数(就像在IsPrime中一样)。将这两种方法结合起来并节省所有额外的周期更有意义。