Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!
查看: 2464|回复: 13

[VBA] 用VBA解欧拉计划题目(3)

[复制链接]
发表于 2017-10-31 15:27 | 显示全部楼层 |阅读模式
第3题 :最大质因数
13195的所有质因数为5、7、13和29。
600851475143最大的质因数是多少?
  1. Sub problem3()   '求600851475143的最大质因数(结果是6857)
  2.     Dim n
  3.     tm = Timer
  4.     n = 600851475143#
  5.     arr = GetPrimeArray(Int(Sqr(n)))   '生成质数数组
  6.     For k = UBound(arr) To 2 Step -1  '从大往下循环,找到第一个
  7.         If n / arr(k) = Int(n / arr(k)) Then Exit For
  8.     Next
  9.     res = arr(k)
  10.     Debug.Print res, Timer - tm
  11. End Sub

  12. Function GetPrimeArray(n)     '得到小于n的质数数组  欧几里德筛选法  by GTR
  13.     Dim p&
  14.     ReDim a(1 To n) As Byte
  15.     i = 2
  16.     Do While i <= Sqr(n)   ' / 2
  17. '        a(i) = 1
  18. '        p = p + 1
  19.         j = 2 * i
  20.         Do While j <= n
  21.             a(j) = 1      'a(j) + 1
  22.             j = j + i
  23.         Loop
  24.         i = i + 1
  25.         Do While a(i) = 1 And i < n
  26.             i = i + 1
  27.         Loop
  28.     Loop

  29.     ReDim b(1 To n) As Long
  30.     For i = 2 To n
  31.         If a(i) = 0 Then
  32.             m = m + 1
  33.             b(m) = i
  34.         End If
  35.     Next
  36.     ReDim Preserve b(1 To m) As Long
  37.     GetPrimeArray = b
  38. End Function
复制代码


excel精英培训的微信平台,每天都会发送excel学习教程和资料。扫一扫明天就可以收到新教程
发表于 2017-10-31 17:16 | 显示全部楼层
你这程序结果错误。

600851475143/6857=876259 余数 6780

我觉得应该是分解为:1814713*43*11*7

回复

使用道具 举报

 楼主| 发表于 2017-10-31 19:21 | 显示全部楼层
香川群子 发表于 2017-10-31 17:16
你这程序结果错误。

600851475143/6857=876259 余数 6780

立即窗口输入:
?600851475143/6857
87625999

我的结果是不会错的,因为我是注册做题的,每次提交正确后我才确认完成。

回复

使用道具 举报

 楼主| 发表于 2017-10-31 19:25 | 显示全部楼层
?600851475143/1814713
331100.000464536
回复

使用道具 举报

发表于 2017-11-1 09:53 | 显示全部楼层
本帖最后由 香川群子 于 2017-11-1 10:00 编辑
grf1973 发表于 2017-10-31 19:21
立即窗口输入:
?600851475143/6857
87625999

哦。我错了,把原始数字输入=6008514743……少了2个数字。600851475143

应该是:
600,851,475,143= 6857*1471*839*71
回复

使用道具 举报

发表于 2017-11-1 10:56 | 显示全部楼层
grf1973 发表于 2017-10-31 19:25
?600851475143/1814713
331100.000464536

我的代码比你的快5倍。

素数筛选算法,我自己优化过了,是目前VBA中速度最快的算法。

  1. Sub test2()
  2.     Dim ar, i&, n, s$
  3.     n = 600851475143#
  4.     ar = GetPrimeArr(Int(Sqr(n)))
  5.     For i = UBound(ar) To 2 Step -1
  6.         If n / ar(i) = Int(n / ar(i)) Then s = s & "*" & ar(i)
  7.     Next
  8.     Debug.Print n & " = " & Mid(s, 2)
  9. End Sub
  10. Function GetPrimeArr(n&) 'by kagawa
  11.     Dim i&, j&, k&, m&
  12.     m = Int((n - 1) / 2): ReDim a(1 To m) As Byte
  13.     For i = 1 To Sqr(n) \ 2
  14.         If a(i) = 0 Then
  15.             For j = i * 3 + 1 To m Step i * 2 + 1
  16.                 a(j) = 1
  17.             Next
  18.         End If
  19.     Next
  20.    
  21.     ReDim b&(1 To m): b(1) = 1: b(2) = 2: k = 2
  22.     For i = 1 To m
  23.         If a(i) = 0 Then k = k + 1: b(k) = i * 2 + 1
  24.     Next
  25.     ReDim Preserve b&(1 To k)
  26.     GetPrimeArr = b
  27. End Function
复制代码


回复

使用道具 举报

发表于 2017-11-1 10:57 | 显示全部楼层
计算结果:
600851475143 = 6857*1471*839*71
回复

使用道具 举报

 楼主| 发表于 2017-11-1 11:17 | 显示全部楼层
嗯。终于找到一个快一点的筛选法了。原来那个是我儿子提供给我的。。。。。
不过你的21句要小改一下,毕竟1不是质数。
  1. Function GetPrimeArr(n&) 'by kagawa
  2.     Dim i&, j&, k&, m&
  3.     m = Int((n - 1) / 2): ReDim a(1 To m) As Byte
  4.     For i = 1 To Sqr(n) \ 2
  5.         If a(i) = 0 Then
  6.             For j = i * 3 + 1 To m Step i * 2 + 1
  7.                 a(j) = 1
  8.             Next
  9.         End If
  10.     Next
  11.    
  12.     ReDim b&(1 To m): b(1) = 2:  k = 1
  13.     For i = 1 To m
  14.         If a(i) = 0 Then k = k + 1: b(k) = i * 2 + 1
  15.     Next
  16.     ReDim Preserve b&(1 To k)
  17.     GetPrimeArr = b
  18. End Function
复制代码
回复

使用道具 举报

发表于 2017-11-1 11:20 | 显示全部楼层
本帖最后由 上清宫主 于 2017-11-1 11:43 编辑

不就是找最大质因数吗?没搞懂为什么要那么麻烦
以下代码也不比你们的慢:
Sub test()
n = 600851475143#
i = 2#
s = 0#
t = Timer
Do While i < n
   s = n / i
   If InStr(s, ".") < 1 Then
      n = n / i
      i = i - 1
    End If
   i=i+1
Loop
Debug.Print i, Timer - t
End Sub
另:好象你们提供的,对于本身就是素数的数就不大对了
回复

使用道具 举报

 楼主| 发表于 2017-11-1 11:32 | 显示全部楼层
上清宫主 发表于 2017-11-1 11:20
不就是找最大质因数吗?没搞懂为什么要那么麻烦
以下代码也不比你们的慢:
Sub test()

是的,前期的题目的确不用考虑时间度,算法。但后面会慢慢出现超大数量级的类型,算法就尤为重要了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-5-8 04:40 , Processed in 0.373640 second(s), 5 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表