置顶成品:在这里面,我一直是思考的,如果有特殊情况,会怎样,于是按着特殊情况去优化提升效率,结果却是整体效率下降,于是两个思路:
1、保证特殊情况的优化,去忍受整体效率
2、保证整体效率,忍受特殊情况
好累,上午就得出的这个结果,因为如果再去做特殊情况的优化的话,因为复杂度问题,可能会产生众多的bug,这是最头疼的一件事。
所以懒惰的我选择… 搞一搞其他问题吧!把质数库加入到目前最通用的算法中!说实话,不想放弃!虽然耗了好长时间在这个上面了,比上一次的浮点数优化层次太深了!

我刚才搜了下判断一个数是否是素数的算法,涉及到了太多高等数学的知识,我放弃思考了。就这样吧!

简单单次开方法:

def 约数(n):if n==1:return 1y=[1,n]if (m:=n**0.5)%1==0:m=int(m)y.append(m)else:m=int(m+1)for i in range(2,m):if n/i%1==0:y.append(i)y.append(int(n/i))y.sort()return y

单次开方增强:从小到的寻找质数,同时生成对应约数组,循环生成直至新的目标数不再包含该质数。寻找更大的质数。思路虽然简单,但是期间遇上更多的问题,各种debug和优化后,看代码没那么容易理解思路,而我刚才尝试841,居然没有之前的一个算法快,虽然841是一种特例吧!看来还是需要更加优化

def Factor(n):if n==1:return [1]y=[]s=2while 1:yf=[]for i in range(s,int(t:=n**0.5)):if n/i%1==0:z=ibreakelse:if t%1==0:z=int(t)elif n/(t//1)%1==0:z=int(t//1)for i in y:yf.append(i*z)y+=yf+[z]yf=[]z=int(n/(t//1))for i in y:yf.append(i*z)y+=yf+[z]y.sort()return yelse:z=int(n)yf.append(z)n=n/zfor i in y:yf.append(i*z)y+=yfwhile 1:if (t:=n/z)%1==0:n=tyt=[]for i in yf:yt.append(i*z)y+=ytyf=yt[:]elif n==1:y.append(1)y.sort()return yelse:breaks=z+1
%%timeit
def Factor(n):if n==1:return [1]y=[]t=nwhile 1:if (t:=t**0.5)%1!=0:tm=int(t)t=int(t**2+0.1)breaks=2while 1:yf=[]for i in range(s,int(tm:=t**0.5)):if n/i%1==0:z=ibreakelse:if t%1==0:z=int(t)elif n/(t//1)%1==0:z=int(t//1)for i in y:yf.append(i*z)y+=yf+[z]yf=[]z=int(n/(t//1))for i in y:yf.append(i*z)y+=yf+[z]y.sort()return yelse:z=int(n)yf.append(z)n=n/zfor i in y:yf.append(i*z)y+=yfwhile 1:if (t:=n/z)%1==0:n=tyt=[]for i in yf:yt.append(i*z)y+=ytyf=yt[:]elif n==1:y.append(1)y.sort()return yelse:breaks=z+1
for i in range(800,900):Factor(i)
if (o:=n%10)==1 or o==3 or o==7 or o==9:while 1:if (t:=t**0.5)%1!=0:tm=int(t)t=int(t**2+0.1)break

这个加进去之后,会涉及到更多的问题,一时很难解决,更适合最初的一个质数组合法。

for i in range(800,900):
简单版:505 µs ± 3.61 µs
加强版:552 µs ± 10.7 µs
循环加强版:535 µs ± 13.8 µs
之前的质数库版:737 µs ± 10.4 µs
之前的无质数库:762 µs ± 10.8 µs

10800,10900:
1.43 ms ± 12.4 µs
874 µs ± 34.5 µs
945 µs ± 16.1 µs
1.06 ms ± 15.8 µs
1.38 ms ± 32.7 µs
虽然看到小数量级时,仍未压过简单版,但是差距不大
但是大数量级时,是目前最快的了

    t=nwhile 1:if (t:=t**0.5)%1!=0:tm=int(t)t=int(t**2+0.1)breaks=2while 1:yf=[]for i in range(s,int(tm:=t**0.5)):

修改版我是把之前的多次开方搬到了这里,目的是更加的减少无端的消耗,主要是当目标数是个质数时!在小数量级时,这个功能负优化,但是在大的数量级时,能减少目标数是质数时,一个指数级的运算时长!明天继续改!将三个方法的步骤完全模块化列出,各个优点整合起来!

我卸载blink上了,结果PC端无法看,坑!
我尝试使用:

来判断目标数是否应该开方,结果很无语,先上结果!
for i in range(10600,10900):
Factor(i)
未添加:2.59 ms
添加if个位数判断:2.31 ms
完全不做开方:2.13 ms
也就是说完全不做总的来说效率更高!只能说纯质数与if之间的比例。
另外如果把if加入到每次循环结果的目标数上,耗时更长,虽然这个点子单纯的好,但是加进去就不好了。
带入997:很遗憾,第一次不做任何处理,效率最高,因为内部同时做了个处理。
但如果带入994009:未经预先开放处理的123 µs ,开放处理的6.05 µs,所以还是有必要预先处理的,顶多是个取舍的问题,至于内部的每次循环,例如2*61*61=7442,这个是需要内部多次开方提升效率的。
但经过几次范围测试,总之这些都是特例,特例到多做一次处理,整体耗时都会增加!
而这里面最核心最有用的就是一次开方
------------------------------历史------------------------------
这个历史比较坑,自以为是的用不断开放法找到无法再开方的目标,再找到质数因子,再组合成约数组,以及引进了质数库。质数库这个我将尝试加入到上面的方法中,求约数仍在继续!

如果使用一个质数库去优化当前算法,那么第一个问题,选择多大的质数库,假设选择1000以内的质数,那么他的适用范围就是1000**2,即1000000 100W。

测试:
1000000的元组,内存占用8000024字节,程序占用43516K,写入文件的话,7.52MB,记事本打开很耗时。那么生成库的大小将以记事本打开速度衡量。
当生成1W的元组,记事本大小在60KB,大概60K个字符时,是秒开的。
但我们其实也根本用不到这个大的元组也未曾可知。而1W时,内存占用是常规状态,并没有显示出多么的大。那么从元组的对比效率上看呢。例如10元素的元组和多少个元素的元组,效率是差不多的。

等等,我创建了各种组合

a=tuple(range(1000000))
b=tuple(range(1000))
c=(999,)
l=list(range(1000))
s=set(range(1000))999 in a

其中元组和列表都是线性搜索的,效率都一样,而且不高
13.7 µs ± 60 ns
但是集合结果就很快
61.1 ns ± 1.47 ns
但是如果要顺序运算的话,就又不能用到集合
也就是说集合仅仅是用来判断要运算的数是否在质数库内的方法
而且生成这些组合也是需要大量的耗时的
我直接赋值长度为1000的一个元组和一个集合,耗时21 µs
元组19.2 ns 集合21.5 µs 好吧,我错了!
这样的话,我只需要优化元组的搜索算法即可,集合计算包含是快,但是生成较慢
那么现在确定,仅使用元组来进行运算

s=set(a) #14.4 µs
a=tuple(s) #5.9 µs

比从源代码赋值要快些

但,其实数字状态下,for i in s的结果也是顺序的。

于是这里考虑的还是质数库需要多大的问题,而且如果使用集合搜索的话,集合由元组生成而非手动赋值。

道理是这个道理,还是试一下看看吧,例如1000内的质数就100多个,生成组合数据耗时,10000个的生成组合数据耗时。无库的算法在10W左右平均耗时是21µs,如果耗时过长,就划不来了,就是反优化!

z=[]
for i in range(2,1000):for j in range(2,i):if i/j%1==0:breakelse:z.append(i)
print(len(z),z)

168 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
1000以内的质数库
耗时9.72 ms ± 145 µs
手动赋值为元组:19.3 ns
手动赋值为集合:3.99 µs
元组转换为集合:3.34 µs
手动赋值为列表:926 ns
列表转换为集合:3.62 µs
果然集合还是过于耗时,先放弃。
997 in k:2.34 µs
k.__contains__(997):2.43 µs
997 in k[-10:-1]:284 ns
997==k[-1]:62.5 ns
997==997:35 ns
len[k]:67.6 ns
既然库是预置的,那么段我们也要预置下

ml={0:2,167:997}
def fm(k,s,e,c=0):m=s+int((e-s)/2)ml[m]=k[m]if c==2:returnc+=1fm(k,s,m,c)fm(k,m,e,c)
fm(k,0,167)
md={}
for i in sorted(ml):md[i]=ml[i]
print(md)

{0: 2, 20: 73, 41: 181, 62: 307, 83: 433, 104: 571, 125: 701, 146: 853, 167: 997}
分段后,更方便对比目标数是否在范围之内,即目标是否是范围之内的质数,其他情况就是目标在范围之外,目标是范围内的非质数
if a>=1:pass:35.2 ns
使用in判断,每个元素的对比耗时在28ns,分段还是有价值的

%%timeit
def kk(t):k=(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997)if t>=433:if t>=701:if t>=853:if t in k[146:]:return [1,t]else:if t in k[125:146]:return [1,t]else:if t>=571:if t in k[104:125]:return [1,t]else:if t in k[83:104]:return [1,t]else:if t>=181:if t>=307:if t in k[62:83]:return [1,t]else:if t in k[41:62]:return [1,t]else:if t>=73:if t in k[20:41]:return [1,t]else:if t in k[:20]:return [1,t]
for i in k:kk(i)

平均耗时0.56µs…

%%timeit
for i in k:i in k

200µs

997:
无库 5.52 µs 2:1.6 µs
有库分段 1.53 µs 2:1.14 µs 71:1.43 µs
有库in 2.81 µs 2:244 ns 71:528 ns
算法2 4.57 µs 2:883 ns
在分段上,这样不行,需要优先算前边的,这样分段才有意义

小数优先:71:516 ns 2:243 ns 997:2.55 µs
如果用算法代替预置段,这个之后再说,首先引入库的目的本不是预置段,而是更快的找到基数质数

%%timeit
k=[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
t=997
z=[]
for i in k:if t/i%1==0:z.append(i)break

24.7 µs ± 1.4 µs
写是写出来了,但是结果着实不正常,经过筛查,问题出在这了

%%timeit
k=[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
for i in k:""

3.28 µs
而相比
k为元组:1.99 µs ± 63.4 ns
k为集合:7.26 µs ± 75 ns

虽然允许是有差距,但关键不在运行,在我之前苦恼的一个问题,如何截断,例如:
841:292
质数库:3.73 µs
未优化:2.88 µs
因为未优化的,它采用的是29
0.5去求质数

那就用最简单的方法截断试试!
先算一下,for元组,一个循环10ns,if也是10ns,试试吧,看看是否有提升
不方便,如果使用if,break截断的话,就是双循环,外层循环无法使用简单的方法跳出,无奈写了个内置函数,使用return跳出
3.38 µs ± 110 ns
稍有提升,未到未优化的状态

def 约数1(n):k=(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997)if n==1:return 1t=nwhile 1:if (t:=t**0.5)%1!=0:tm=int(t)t=int(t**2+0.1)breakz=[]def 质数(t):while 1:if t==1:returnif (tm:=t**0.5//1)==1:z.append(t)returnfor i in k:if i<=tm:if t/i%1==0:z.append(i)breakelse:if tm>997:for i in (998,int(tm)+1):if t/i%1==0:z.append(i)breakelse:z.append(t)returnwhile 1:if (t:=t/i)%1!=0:t=int(t*i+0.1)break质数(t)y=[]for i in z:zy=[]t=nii=izy.append(i)t=t/iwhile 1:if (t:=t/i)%1==0:zy.append(ii:=ii*i)else:breakfor j in y:t=n/jii=1while 1:if (t:=t/i)%1==0:zy.append(j*(ii:=ii*i))else:breaky+=zyy.append(1)y.sort()return y

我尽力了

------------------------------------------------以下是无质数库------------------------------------------------

def 约数算法1(n):if n==1:return 1t=nwhile 1:if (t:=t**0.5)%1!=0:tm=int(t)t=int(t**2+0.1)breakz=[]while 1:if t==1:breakif tm==1:z.append(t)breakfor i in range(2,tm):if (t/i)%1==0:t=t/iz.append(i)breakelse:if (t/tm)%1==0:i=tmz.append(tm)else:z.append(t)breakwhile 1:if (t:=t/i)%1!=0:t=int(t*i+0.1)tm=int(t**0.5)breaky=[]for i in z:zy=[]t=nii=izy.append(i)t=t/iwhile 1:if (t:=t/i)%1==0:zy.append(ii:=ii*i)else:breakfor j in y:t=n/jii=1while 1:if (t:=t/i)%1==0:zy.append(j*(ii:=ii*i))else:breaky+=zyy.append(1)y.sort()return ydef 约数算法2(n):if n==1:return 1y=[1,n]if (m:=n**0.5)%1==0:m=int(m)y.append(m)else:m=int(m+1)for i in range(2,m):if n/i%1==0:y.append(i)y.append(int(n/i))y.sort()return y

算法2是很久前就想好了的,并一直在用,但是刚才批量过数据debug的时候,发现算法2有致命bug,现在两个算法结果一致了,大概都没问题了!

for i in range(100,200)
算法1:580 µs ± 19.2 µs
算法2:294 µs ± 6.5 µs

1000,1200
1.65 ms ± 16.5 µs
1.17 ms ± 15.5 µs

10000,10200
2.63 ms ± 77.1 µs
2.95 ms ± 79.8 µs
数值在10000级别时,才反超

100000,100200
4.34 ms ± 93.2 µs
8.4 ms ± 104 µs

196
5.99 µs
3.46 µs

1228
6.95 µs
5.68 µs

4096
6.33 µs
10.2 µs

其实我还有个思路来着,应该能更加优化下质数组合。明日继续优化

算法2是简单的一次开平方思路,算法1是在其基础上各种脑洞,最后总结算是质数法。

小数值下,算法2可能更快,毕竟结构复杂性在那,但是大数值下是算法1更快!

--------------------------------------------------------以下是历史记录--------------------------------------------------------

之所以要用质数法,就是为了弥补可以再次开平方的情况,那么就假设做到极致,用2的平方测试,再用7的平方测试。
4:
2.19 µs ± 63.4 ns
1.11 µs ± 9.49 ns

16:
3.37 µs ± 87.1 ns
1.7 µs ± 29.6 ns

256:
5.15 µs ± 113 ns
3.9 µs ± 51.9 ns

65536:
9.07 µs ± 118 ns
32.7 µs ± 1.09 µs

49:
2.94 µs ± 109 ns
1.75 µs ± 5.55 ns

2401:
4.06 µs ± 54 ns
6.94 µs ± 268 ns

至此,可以看到在大步进的质数下,两段开方,这个长代码的效率就赶上来了。

再举个极端的例子,例如两个大质数相乘!

989=23*43
10.4 µs ± 99.6 ns
4.62 µs ± 133 ns

我貌似想到一个更好的思路,聪明的人肯定一开始就能想到,撞墙。
如果我不采用质数拼,或者用更好的拼法呢倒三角形,或者过程合一

-----------------------------------------------以下是历史文档,可略--------------------------------------------

n=16
3.66 µs ± 51.5 ns
1.68 µs ± 12.3 ns

81:
4 µs ± 204 ns
2.26 µs ± 58.5 ns

61:
8.8 µs ± 186 ns
1.53 µs ± 10.1 ns

64:
5.21 µs ± 41.6 ns
2.54 µs ± 38.7 ns

256:
5.83 µs ± 46.9 ns
3.71 µs ± 116 ns
改:5.52 µs ± 239 ns

1225:
7.83 µs ± 64.3 ns
6.13 µs ± 134 ns
改:7.52 µs ± 188 ns
修改后有稍许提升,但是结构并没有大的优化

4096:
8.22 µs ± 102 ns
10.4 µs ± 193 ns
改:7.5 µs ± 97.9 ns

16384:
9.66 µs ± 124 ns
17.5 µs ± 195 ns

其实我对这个思路还是有自信的,看看哪里还能优化下


代码还没完成,就发现一个问题,记录下

# from random import randint
#生成一个数,求他的约数
# n=randint(1,1000)
n=2251875390625
#定义一个变量
def 求约数(n):t=nt=n#开平方缩减运算量while 1:if (t:=t**0.5)%1==0:nt=telse:break#定义质数集合#!!!这个def之后尝试写成while,试一下效率是否改变z=[]def 求质数(nt):for i in range(2,nt):if nt/i%1==0:z.append(i)breakelse:z.append(nt)returnt=nt=nt/iwhile 1:if (t:=t/i)%1!=0:breaknt=t求质数(int(nt))求质数(int(nt))
求约数(n)

目前以完成求质数步骤,但发现耗时已经超了

n=2251875390625
y=[1,n]
if (m:=n**0.5%1)==0:y.append(m)
for i in range(2,int(n**0.5)):if n/i%1==0:y.append(i)y.append(int(n/i))
y.sort()

之前运行的是n=996
12 µs ± 250 ns
6.1 µs ± 162 ns
耗时近翻倍
于是这次我找了个大数n=2251875390625
3.64 µs ± 64.6 ns
190 ms ± 3.22 ms

超逆袭,我没想到1225其实可以开平方成35的,但可以得出,当进入2步骤时,数量一样的话,加强优化的效率没小优化的效率高。主要在求质数部分,这里尽可能的再优化下,或者可以与之后的质数组合衔接以节省重复运算。

小优化如果做二段开平方的话,会发生问题的。所以才想到用质数拼约数,但这功能又会用到组合这个不大不小的话题!

%%timeit
n=989
def 约数(n):if n==1:return 1t=nt=nwhile 1:if (t:=t**0.5)%1==0:nt=telse:breaky=[]if nt==n:while 1:zy=[]for i in range(2,int(nt)):if nt/i%1==0:zy.append(i)breakelse:zy.append(int(nt))i=zy[-1]nt=nt/iit=iwhile 1:if (t:=nt/i)%1==0:nt=tzy.append(it:=it*i)else:breakfor j in y:it=1t=nt=t/jwhile 1:if (tt:=t/i)%1==0:t=ttzy.append(j*(it:=it*i))else:breaky+=zyif nt==1:breaky.append(1)y.sort()return y
y=约数(n)

这个程序做了一下改动,是针对第一次开方不是整数的情况,且将它称之为情况1,而本文最开始的文章是情况2。情况1是针对情况2的如上描述做的调整
989:
10.5 µs ± 184 ns
10.4 µs ± 99.6 ns

12288:
11.5 µs ± 387 ns
19 µs ± 494 ns

1228:
40.9 µs ± 1.02 µs
42.4 µs ± 492 ns
什么鬼,这个绝对不值
一次开方法:5.46 µs ± 120 ns
[1, 2, 4, 307, 614, 1228]
属于双质数,而且是很小的质数和很大的质数的搭配
还是说我的这个长代码有bug

长代码耗时

  • 开方:490 ns
  • 质数:38.6 µs
  • 结果:42.4 µs
    所以问题出在了取质数这上面

新思路,既然一次开方法更快,何不借鉴

%%timeit
n=1228
def 约数(n):if n==1:return 1t=nwhile 1:if (t:=t**0.5)%1!=0:tm=int(t)t=int(t**2+0.1)breakz=[]while 1:for i in range(2,tm):if (t/i)%1==0:t=t/iz.append(i)breakelse:z.append(t)breakwhile 1:if (t:=t/i)%1!=0:t=int(t*i+0.1)tm=int(t**0.5)breaky=[]for i in z:zy=[]t=nii=izy.append(i)t=t/iwhile 1:if (t:=t/i)%1==0:zy.append(ii:=ii*i)else:breakfor j in y:t=n/jii=1while 1:if (t:=t/i)%1==0:zy.append(j*(ii:=ii*i))else:breaky+=zyy.append(1)y.sort()return y
约数(n)

6.65 µs ± 103 ns
近乎完成品了

python - 求约数 质数法相关推荐

  1. python,求约数,开方法

    def 约数(n):if n<=3:return [1,n]m=int(n**0.5) #这里之前有个取整除的运算,后来发现int默认就是截断操作y=[]for i in range(1,m+1 ...

  2. python求素数算法_Python程序最多可计算n个质数(使用不同算法)

    python求素数算法 There are various methods through which we can calculate prime numbers upto n. 我们可以通过多种方 ...

  3. df满足条件的值修改_如何用python实现熵值法求指标权重(实例)

    权重是指某一因素或指标相对于某一事物的重要程度,其不同于一般的比重,体现的不仅仅是某一因素或指标所占的百分比,强调的是因素或指标的相对重要程度,倾向于贡献度或重要性.而在我们的数据分析过程中,倘若各个 ...

  4. python求极限中有算术平方根如何表达_Python求算数平方根和约数的方法汇总

    Python求算数平方根和约数的方法汇总 一.求算术平方根 a= x=int(raw_input('Enter a number:')) if x >= : while a*a < x: ...

  5. Python 求100以内的质数

    Python 求100以内的质数 list=[] for i in range(2,101): for j in range(2,i): if i%j ==0: break else: list.ap ...

  6. python求100以内质数以及合数

    质数有哪些?如何用python求质数?合数有哪些?这一次,我们做一个100以内质数生成器吧! z=[]#质数列表 h=[]#合数列表 for i in range(2,100+1):#循环2-100a ...

  7. python中是什么意思权重_如何用python实现熵值法求指标权重(实例)

    权重是指某一因素或指标相对于某一事物的重要程度,其不同于一般的比重,体现的不仅仅是某一因素或指标所占的百分比,强调的是因素或指标的相对重要程度,倾向于贡献度或重要性.而在我们的数据分析过程中,倘若各个 ...

  8. python求合数的所有因子,0是素数吗(python求一个数的因子)

    相信很多人对于0是素数吗(python求一个数的因子)并不是非常的了解,因此小编在这里为您详解的讲解一下相关信息! 0和1不是质数,因为质数的定义是:在大于1的自然数中,除了1和它本身以外不再有其他因 ...

  9. python判断素数的函数_如何用python求素数

    如何用python求100以内的素数? 质数(primenumber)又称素数,有无限个.质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数的数称为质数,如:2.3.5.7.11.13.1 ...

  10. 算法刷题-数论-试除法求约数、约数个数、约数之和、最大公约数(辗转相除法)

    文章目录 acwing869. 试除法求约数 acwing870. 约数个数 acwing871. 约数之和 acwing872. 最大公约数 acwing869. 试除法求约数 acwing869. ...

最新文章

  1. ORB-SLAM2从理论到代码实现(六):Tracking.cc程序详解(上)
  2. MySQL全面优化,速度飞起来
  3. UVa10340 - All in All(贪心算法)
  4. Frighting的日常:第5天
  5. java getresourceasstream null_java踩坑记-getResourceAsStream
  6. node nightmare 网页自动化测试 sample
  7. latex中怎么设置每一行文字都对齐_排版系列教程 | LaTeX,为学术论文排版而生【浮动体篇】...
  8. 【组件】大数据框架安装功能来划分
  9. Ubuntu 16.04粘贴板增强工具Diodon
  10. 蓝桥杯 ADV-91 算法提高 素数判断
  11. 数据库报错“system01.dbf需要更多的恢复来保持一致性,数据库无法打开”
  12. LeetCode: Implement strStr() [027]
  13. Redis protected-mode属性解读
  14. 制造业供应链平台解决方案,实现数字化、可视化、信息化
  15. code vs 集成tfs_Microsoft强大团队(源代码)管理工具--TFS2010 与vs结合
  16. SAP中利用标准成本报表计算成品人工成本及组成实例
  17. linux添加core文件位置,Linux生成core文件、core文件路径设置
  18. 零基础全天自学PHP,7个月后我找到了工作
  19. 2013年最后2个月的学习目标(成果)(上次更新2013年11月18日)
  20. re模块02-re模块

热门文章

  1. 免费的录屏软件,来试试这一款软件吧!
  2. python 笔记:h5py
  3. 使用JS读取本地文件
  4. 三维空间中无人机路径规划的改进型蝙蝠算法
  5. 日本著名数学游戏专家中村义作教授提出这样一个问题:将2520个桔子分给六个儿子
  6. 用C语言进行完数的判断(for循环和数组思想)
  7. JDK1.8下载 jdk1.8-64下载 国内源
  8. 能源路由器:基于固态变压器的能源路由器结构与能源流量模型
  9. 普林斯顿微积分读本篇十三:积分
  10. 微分方程数值解法结语