这是一道作业题.
参考的是stackoverflow的第3个回答, 这个方法非常好, 据同学在群里说, 用那种遍历到sqrt(n)的办法, 需要将近一分钟. R速度是很慢的, 但是得到这个结果不到0.1s.
其实核心思路很简单: 从小到大的素数, 如果i是n的因子, 就一直除以i, 直到n不再包含因子i. 那么之后最小的因子都一定大于i.
这个回答加了一点优化: 素数一定是6n-1或者+1. 但这并不是关键. 优化意义不大, 大概减少了1/3的时间(6个数, 如果+=2, 是3次, 这里变成了2次).
time1=Sys.time()
num=600851475143
if(num%%3==0) {
max_f=3
while(num%%3==0) {
num=num/3L
}
}
six_m=6
sqrt_n=floor(sqrt(num))
while(six_m-1<=num) {
tmp=six_m-1
if(num%%tmp==0) {
max_f=tmp
while(num%%tmp==0) {
num=num/tmp
}
}
tmp=six_m+1
if(num%%tmp==0) {
max_f=tmp
while(num%%tmp==0) {
num=num/tmp
}
}
six_m=six_m+6
}
time2=Sys.time()
print(time2-time1)
print(max_f)
我开始犯了一个错误, 把上限写成了floor(sqrt(num)), 这显然不对, 比如14最大素因子是7. 我有这个潜意识, 大概是因为很早以前做因数分解留下的印象吧.
复杂度分析
简单分析一下, sqrt(num)那种方式, 复杂度是O(sqrt(N)), 这种方式复杂度是O(log(N)), 显然强得多.