求某整数前的所有质数(素数)和的算法及优化(2)
计算的优化过程
这是优化的第二篇,如需了解优化过程请参照
《求某整数前的所有质数(素数)和的算法及优化(1)》
进一步优化
这数组的算法上在进一步优化,优化原理是寻找因数是,只需计算到该数的开方即可,如:
36的因数只要计算
36=1x36
36=2x18
36=3x12
36=4x9
36=6x6
到6之后的结果只是把两个数字颠倒过来,就没有计算的必要了。质数的算法也是如此,所以可在判断i是否是质数的代码中加入当j大于i的开方即可大大的提高计算速度。代码如下
1万前的质数求和只需要0.045秒(用pychar运行,IDLE运行计算速度回更慢具体时间因电脑和运行环境有关).
import time
x = input("请输入一个大于2整数:")
num=int(x)
z=0
total=0
pr=[]
ti_1=time.time()
print(ti_1) #计算起始时间
print(num)
print("前的所有质数为:")
for i in range(2,num+1): #从2开始判断是否是质数,直至到x
z=0 #判断是否是质数的变量
for j in pr: #判断i是否是质数
if (i%j)==0:
z+=1
if z==1 or j>pow(i,0.5): #z=1时,表面i能被质数集合中一个数整除,i非质数,无需判断大于i开方的数
break
if z==0:
total+=i
pr.append(i)
print(i,end=' ')
if (i%10)>6:
print(" ")
ti_2=time.time()
print()
print(num,end=':')
print("前的所有质数和为",end=':')
print(total)
print("计算所用时间为",end=':')
print(ti_2-ti_1,end='')
print("秒")
Java代码及与Python的比较
Java的代码明显比Python的代码复杂,但是计算速度要快的多,计算10万内的质数和是Java只需要339毫秒,Python却要610毫秒,但Python的计算精度更高(不知道计算速度是不是编译器的问题)。
在编写Java程序是还遇到了一个即非逻辑错误也非编译语法错误的问题,到现在还没弄清楚怎么回去,明天再研究一下。
package primenumbertotal;
import java.util.Arrays;
import java.util.Scanner;
public class PrimeNumvberTotalList {
public static void main(String[] args) {
System.out.println("求输入数字前的所有质数并求和,请输入一个整数:");
int x = new Scanner(System.in).nextInt();
int z=0,n=0,y;
long total = 0L;
int[] a = {};
long t,t1,t2;
t1=System.currentTimeMillis();
System.out.println(x+"前的质数为:");
for(int i=2;i<=x;i++) {
z=0;
for(int j=0;j<a.length;j++) {
if (i%a[j]==0) {
z+=1;
}
if(z==1|| a[j]>Math.sqrt(i)) {
break; //break只是跳出for-j循环 这里不可以进入下一轮for-i循环
}
}
if (z==0) {
total+=i;
System.out.print(i+" ");
a = Arrays.copyOf(a, a.length+1);
a[a.length-1]=i;
if(i%10>6) { //没有该行则显示不出每一位质数,但求和速度回更快
System.out.println();
}
}
}
t2=System.currentTimeMillis();
t=t2-t1;
System.out.println();
System.out.println(x+"前所有质数的和为:"+total);
System.out.println("所有时间为:"+t+"毫秒");
}
}
结束语
为什么要这么纠结算法了,个人的理解是在开始学习时要多思考,用不同的算法解决问题,最后找到最有解,这样在做项目的时候遇到问题才会更快的想出解决方案