求某整数前的所有质数(素数)和的算法及优化(2)

求某整数前的所有质数(素数)和的算法及优化(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+"毫秒");
	}
}

结束语

为什么要这么纠结算法了,个人的理解是在开始学习时要多思考,用不同的算法解决问题,最后找到最有解,这样在做项目的时候遇到问题才会更快的想出解决方案

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值