华为编程面试题目 求2到2000的质数 源程序筛法求质数

2024-04-12 17:08

本文主要是介绍华为编程面试题目 求2到2000的质数 源程序筛法求质数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

内存足够大,写程序输出2到2000的质数。

'''华为面试题目 求2到2000的质数'''
N = 2000
number = list( range(2, N+1) )
times = 0
checknum = list(range(2,int((N+1)/2)+1))
for i in checknum:for index in number:times += 1if index != i:if index/i == int(index/i):number.remove(index)if index in checknum:checknum.remove(index)print(number)
print("尝试%d次"%times)

以上比较朴素、比较笨、比较快速的实现了一个程序。如果作为本科生,写出这样的程序或可以接受。

设计思想:

验证一个大于2的数是不是质数,当然只要从2循环到int(N/2),去除这个数,如果能够整除,被除数不等于除数,则这就是一个合数。如果都不能整除,则这是一个质数。

但是如果从2一直到N,都这样求一遍,时间复杂度太高了。比如,计算49是不是质数,前面会使用4和6去除,问题是4和6本身就是合数,其实应该使用质数去除49验证,也就是用2 3 5 7,但是,怎么直接拿这种质数去除呢?那么以上程序的朴素思想1就来了:维护两个表,一个表number是从2到N,一个表checknum是从2到N/2,checknum专门存储除数。每一次取除数都从checknum取,一旦checknum能够整除number,判断出这个number是一个合数,就把它从两个表里面删去。由于我们使用的是python的for in 形式的循环,动态修改循环列表,可以保证目前用于检查的数是个质数,不会从未来的表里删掉。比如我们验证4/2,则4应该从checknum表里面删掉;而不会因为验证一个m,导致了小于m的数从number被删掉,这样的话,不会需要回溯数组。于是就有了以上程序。

当然这个程序并不是某一种最优解,需要考虑优化解法。

 

有一种获取一个范围内的质数的方案叫“筛法”,就是把这个范围内的数都写出来,用最小的质数2来除,除尽就划掉。再用下一个质数3来除,除尽就划掉。那么利用这种思想,我们可以有第2种程序:

从list里面取除数,从2开始,一个个循环去除list包含的元素,查找list中的合数,找到合数就从list删掉(当然你要考虑到,list的查找+删除remove函数由于做了大量的数据位移,实际是很耗时的),然后,list的下一个数:3。当3筛过之后,由于4已经在除以2的一轮中删掉了,所以下一个除数是5。这就避免了使用合数来除list中的数。

另外,用2到N/2中所有的质数来除吗?也不是。显然,实际应该从2到int(sqrt(N))来除。比如,N=100,由于除以7的时候,7*14=98已经被删除,在这之前的7*11=77也被删除了,已经不需要使用int(sqrt(100))+1=11除了,11*8 11*9 都在更早被删除,所以只要小于等于10,就可以了。为什么要等于?比如N=121,int(sqrt(N))=11,需要除到11时才能把121去掉。

那么我们就有了下面的解法:

'''华为面试题目 求2到2000的质数'''
import math
N = 2000
number = list( range(2, N+1) )
times = 0
index = 0 #index表示现在的除数是list里的第几个数
#flag定为N的算术平方根
flag = int(math.sqrt(N))
for i in number:x = number[index]#x 从number中取数,如果大于flag本轮循环结束if x > flag:break#从index+1开始向后遍历,如果能够整除则从number删除for bei in number[index+1:]:times += 1if bei/x == int(bei/x):number.remove(bei)index += 1
#最终剩下的就是质数
print(number)
print("尝试%d次"%times)

这个解法还有没有改进空间呢?还是有的。在for bei in  number[index+1:]这里,这是做了一个列表的切片。每做一个切片就是复制数组的一段,还是有比较大的开销。那么,我们如果把这个循环换成:自index+1到len(number)循环,取number变量的事情放在里面,则会省去一些数组复制的空间开销。

但是,一旦这样处理,删除、取变量都是同一个数组操作,要注意控制里面的循环变量。

这篇关于华为编程面试题目 求2到2000的质数 源程序筛法求质数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/897730

相关文章

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

数据库面试必备之MySQL中的乐观锁与悲观锁

《数据库面试必备之MySQL中的乐观锁与悲观锁》:本文主要介绍数据库面试必备之MySQL中乐观锁与悲观锁的相关资料,乐观锁适用于读多写少的场景,通过版本号检查避免冲突,而悲观锁适用于写多读少且对数... 目录一、引言二、乐观锁(一)原理(二)应用场景(三)示例代码三、悲观锁(一)原理(二)应用场景(三)示例

售价599元起! 华为路由器X1/Pro发布 配置与区别一览

《售价599元起!华为路由器X1/Pro发布配置与区别一览》华为路由器X1/Pro发布,有朋友留言问华为路由X1和X1Pro怎么选择,关于这个问题,本期图文将对这二款路由器做了期参数对比,大家看... 华为路由 X1 系列已经正式发布并开启预售,将在 4 月 25 日 10:08 正式开售,两款产品分别为华

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制

定价129元!支持双频 Wi-Fi 5的华为AX1路由器发布

《定价129元!支持双频Wi-Fi5的华为AX1路由器发布》华为上周推出了其最新的入门级Wi-Fi5路由器——华为路由AX1,建议零售价129元,这款路由器配置如何?详细请看下文介... 华为 Wi-Fi 5 路由 AX1 已正式开售,新品支持双频 1200 兆、配有四个千兆网口、提供可视化智能诊断功能,建

C#多线程编程中导致死锁的常见陷阱和避免方法

《C#多线程编程中导致死锁的常见陷阱和避免方法》在C#多线程编程中,死锁(Deadlock)是一种常见的、令人头疼的错误,死锁通常发生在多个线程试图获取多个资源的锁时,导致相互等待对方释放资源,最终形... 目录引言1. 什么是死锁?死锁的典型条件:2. 导致死锁的常见原因2.1 锁的顺序问题错误示例:不同

PyCharm接入DeepSeek实现AI编程的操作流程

《PyCharm接入DeepSeek实现AI编程的操作流程》DeepSeek是一家专注于人工智能技术研发的公司,致力于开发高性能、低成本的AI模型,接下来,我们把DeepSeek接入到PyCharm中... 目录引言效果演示创建API key在PyCharm中下载Continue插件配置Continue引言