算法:数论(质数与质因子)

1、试除法求质数

import math
def div(x):
    q=int(math.sqrt(x))
    for i in range(2,q+1):
        if x%i==0:
            return False
    return True

2、分解质因数(试除法)

import math
def div(x):
    q=int(math.sqrt(x))
    left=2
    while left<=x/left
        if x%left==0:
            s=0#记录该质因子出现的次数
            while x%left==0:
                x/=left
                s+=1
            print(left,s)#质因子及其出现次数
        left+=1
    if x>1:print(x,1)#最大质因子
    

3、筛选质数

例子:求1~n之间所有的质数个数?

暴力解法:时间复杂度为O(n*sqrt(n))即循环所有数字,试除法判断质数。[容易爆]

埃氏筛法:按照某数的倍数筛除,即假如a是质数,我们筛除所有满足条件(j<n)的所有a*j,删除过程有重复。如果a是合数,合数一定可以做质数分解,即分解质因数,即为某个比其小的质数的倍数,这样必然被前面的质数的倍数的方法给筛除掉,所以如果a是合数,则不需要考虑。

时间复杂度为O(n*logn)

st=[True]*N#  N为数据范围,st数组表示某个数字是否是质数
def div_num(x):
    res=0#记录结果
    for i in range(2,x+1):#遍历所有的数字
        if st[i]:res+=1#是质数
        else:#不是质数,就不需要执行下面的筛除操作
            continue
        j=i+i
        while j<=x:
            st[j]=False#不是质数
            j+=i#以i的整数倍增加
    return res
         

线性筛法:上述方法会重复的删除某些数字,例如6会同时被2和3两个质数筛除。

时间复杂度为O(n)

方法:每个数字只用其最小质因数筛除,每个数字只有一个最小质因数,所以每个数字如果会被筛除,则一定只筛除一次。

st=[True]*N  # N为数据范围
prim=[]#存质数
def div_num(x):
    res=0
    for i in range(2,x+1):
        if st[i]:
            res+=1
            prim.append(i)
        j=0
        while prim[j]<=x/i:
            st[prim[j]*i]=False#筛除
            if i%prim[j]==0:break
            j+=1
    return res 

#记prim[j]为pj
#当i%pj==0的时候,在break之前,pj*i已经被筛除了,此时pj是pj*i的最小质因数
#当i%pj!=0的时候,不会break,pj则小于i的所有质因数,pj是质数pj*i的最小质因数
#所以综上,我们是依据最小质因数去筛除的,而每一个合数只有一个最小质因数,所以每个合数肯定
#是被筛除了一次。            

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值