Python全栈(8)—— 高效判断素数、求素数的方法

1、素数简介

质数又称素数。指整数在一个大于1的自然数中,除了1和此整数自身外,没法被其他自然数整除的数。

2、判断素数函数

2.1 简单粗暴的方法

按照固有思维,大家都会想到,对于所给数n,那么从2开始,一直到n-1,看一下有没有能够整除的,如果有就不是素数,下面就是最简单粗暴的方法:

N = input('>>')
N = int(N)
flag = True

if N > 1:
    for i in range(2,N):
        if N%i == 0:
            print('False')
            break
    else:
        print('True')
else:
    print('False')

这么写当然没错了,但是效率比较低,属于数n,时间复杂度为O(n)

2.2 高效算法

def isPrime(n): 
  if n <= 1: 
    return False 
  i = 2 
  while i*i <= n: 
    if n % i == 0: 
      return False 
    i += 1 
  return True 

N = input('>>')
N = int(N)
print(isPrime(N))

对于数据n,如果n不是素数,那么它一定可以被根号n以内的某个数字整除,利用这条性质,就可以大大降低时间复杂度,提高代码效率。

3、生成素数

3.1方法1

太简单粗暴的方法就不介绍了,如果某个数字不是素数,那么它一定可以被比它小的某个素数整除,利用这条性质,可以设计如下程序:

import time
n=int(input('请输入要求多少以内的素数(包括n):'))
start_time=time.time()
prime=[2]
for i in range(2,n+1):
    for x in prime:
        if i%x ==0:
            break
    else:
        prime.append(i)
end_time=time.time()
#print(prime)
print(end_time-start_time)

3.2 方法2

利用2.2节中的性质,可以设计如下程序:

def primes(start, stop):
    if start < 2:
        start = 2
    for i in range(start, stop+1):
        for j in range(2, i):
            if i % j == 0:
                break
        else:
            yield i

# 0到200之间的素数
for x in primes(0, 200):
    print(x)

3.3 方法3

埃氏筛法
(1)先把1删除(现今数学界1既不是质数也不是合数)
(2)读取队列中当前最小的数2,然后把2的倍数删去
(3)读取队列中当前最小的数3,然后把3的倍数删去
(4)读取队列中当前最小的数5,然后把5的倍数删去
(5)如上所述直到需求的范围内所有的数均删除或读取

# 生成一个奇数生成器。
def odd_iter():
    n = 1
    while True:
        n = n + 2
        yield n

# 过滤掉n的倍数的数。
def not_divisible(n):
    return lambda x: x % n > 0

# 获取当前序列的第一个元素,然后删除后面序列该元素倍数的数,然后构造新序列。
def primes():
    yield 2
    it = odd_iter()
    while True:
        n = next(it)
        yield n
        it = filter(not_divisible(n), it)

# 获取 start 到 stop 之间的素数。
start, stop = 10, 2000
for n in primes():
    if n > start and n < stop:
        print(n, end=',')
    elif n > stop:
        break

这种方法的效率是很高的,要远高于前两种方法。

yield

带有 yield 的函数在 Python 中被称之为 generator(生成器),其本身作用和return类似。

为什么用这个生成器,是因为如果用List的话,会占用更大的空间,比如说取0,1,2,3,4,5,6…1000

这个时候range(1000)就默认生成一个含有1000个数的list了,所以很占内存。

这个时候你可以用刚才的yield组合成生成器进行实现,也可以用xrange(1000)这个生成器实现

yield组合:

def foo(num):
    print("starting...")
    while num<10:
        num=num+1
        yield num
for n in foo(0):
    print(n)

结果:

starting...
1
2
3
4
5
6
7
8
9
10

yield详细介绍:
https://blog.csdn.net/mieleizhi0522/article/details/82142856/

filter() 函数

用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。

该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判断,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。

def is_odd(n):
    return n % 2 == 1
 
newlist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(newlist)

结果:

[1, 3, 5, 7, 9]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力改掉拖延症的小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值