Python基础--编译器、解释器、素数优化

本文介绍了高级语言与低级语言的区别,详细讲解了编译器和解释器的工作原理,并探讨了素数的判断与优化方法。在优化求100万以内的素数过程中,通过合理减少计算次数和利用素数规律来提高效率。
摘要由CSDN通过智能技术生成

高级语言和低级语言之间需要一个转换的工具:编译器解释器

低级语言

  • 面向机器的语言,包括机器语言、汇编语言
  • 不同的机器不能通用,不同的机器需要不同的机器指令或者汇编程序

高级语言

  • 接近自然语言和数学语言的计算机语言
  • 高级语言首先要书写源程序,通过编译程序把源程序转换成机器指令的程序
  • 1954年正式发布的Fortran语言是最早的高级语言,本意是公式翻译

编译器

  编译器是把源代码整个编译成目标代码,执行时不在需要编译器,直接在支持目标代码的平台上运行,这样执行效率比解释执行快很多。比如C和C++等语言的代码被编译成二进制代码(exe程序),在windows平台上执行。


解释器

  解释器是一条一条的解释执行源语言。比如Python、JAVA、javascript、PHP就是典型的解释性语言。它们的代码需要被解释器编程中间代码(Bytecode),在虚拟机上运行。


  • 编译语言,把源代码转换成目标机器的CPU指令
  • 解释语言,解释后转换成字节码,运行在虚拟机上,解释器执行中间代码
  • 编译器的优点:执行效率远远高于解释运行的程序
  • 解释器的优点:比较容易让用户实现自己跨平台的代码
    这里写图片描述

这里写图片描述

这里写图片描述


素数

质数(prime number)又称素数,有无限个。
质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。


判断一个数是否是素数

num = int(input('请输入一个数>>>'))
if num % 2 == 0:
    print('该数是质数')
    quit()
    for i in range(3,int((num**0.5)+1),2):
        if num % i == 0:
            print('该数不是质数')
            break
    else:
        print('该数是质数')

素数的定义是从2开始到自身的-1的数中找不到一个能整除的,即为素数。

优化点一:可以简化到从2开始到自身开平方的数中找到一个能整除的,即为素数。
优化点二:同时素数也不会被一个偶数整除,所以在range函数中设置步长为2,跳过所有偶数。

求100万以内的素数

start = datetime.datetime.now()
print(2,end=' ')

for i in range(3,1000000,2):
    for j in range(3,int((i**0.5))+1,2):
        if i % j == 0:
            break
    else:
        print(i,end=' ')

end = datetime.datetime.now()
print(end-start,'s')
测试用时 3.83s  3.56s  3.76s 4.01s 3.84s
start = datetime.datetime.now()

prime = []
flag = True
for i in range(3,1000000,2):
    for j in prime:
        if j >= (i**0.5)+1:
            flag = True
            break
        if i % j == 0:
            flag = False
            break 
    if flag:
        prime.append(i)

print([2]+prime)

end = datetime.datetime.now()
print(end-start,'s')
测试用时 5.11s 4.92s 4.93s 5.23s 5.06s
  1. 因为一个合数一定可以分解成几个素数的乘积,也就是说,一个数如果能被一个素数整除就是合数。所以设置一个列表prime接收依次验证所得的素数加快后续的检验。
  2. 因为我们在提供测试数据的时候已经淘汰了偶数,所以把2暂时移出素数集,减少计算次数。
  3. 同时在素数的验证中加入“从2开始到自身开平方的数中找到一个能整除的,即为素数”的概念,减少取列表中的素数验算自身的次数。
  4. 素数出现的规律是结尾为1、3、7、9的数,设想过提前与5进行计算排除结尾为5的数。
    但是假设1000以内,可以被3整除的数大约为333个,而被5整除的是200个。
    并且因为我们已经淘汰了偶数,所有被5整除的数只剩下100个,因此我们没有必要提前用5进行计算处理掉以5结尾的数。
start = datetime.datetime.now()

prime = []
flag = True
for i in range(3,1000000,2):
   # k = i ** 0.5 + 1
    k = math.sqrt(i) + 1
    for j in prime:
        if j >= k:
            flag = True
            break
        if i % j == 0:
            flag = False
            break
    if flag:
        prime.append(i)

print([2]+prime)

time = (datetime.datetime.now()-start).total_seconds()
print(time)
测试用时 2.24s 2.13s 2.3s 2.05s 2.11s
  1. 因为如果写成j >= (i**0.5)+1 在每一次循环都要进行重复运算,所以提前在循环外计算,即k = i ** 0.5 + 1,以加快速度。
  2. 同时测试发现使用函数计算k,也就是k=math.sqrt(i)+1。在计算100W数据时只有0.0x秒的优势,差别极小。在计算1000W数据时,大约有0.5s的优势。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值