ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: 香川群子

[原创] 跟我学算法 【初级篇】:求某个整数范围内所有素数

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2015-1-30 22:50 | 显示全部楼层
香川群子 发表于 2015-1-30 21:44
【最后说一句,群子的代码中似乎使用了 Redim Preserve 这从效率讲是不可取的,因为数组的不变性,Redim  ...

再优化,再如何,vba 中redim 就是要开内存的。而redim preserve 最少有3 个操作,首先在heap 里开新数组的内存,然后从原数组逐一复制数据过去。第三释放原数组内存,如果没有第三步,速度会快点,结果更坏,产生了内存泄漏。
而你根据概算公式或者干脆估算一个较大的数组,则仅是数组定位的指针操作,速度和redim 还有redim preserve 完全不可同日而语。就是定位我取这个数组的前多少位有效,怎么是for 循环呢?你生成新数组之后回去该遍历还是要一样for 的啊。

TA的精华主题

TA的得分主题

发表于 2015-1-30 23:47 | 显示全部楼层
本帖最后由 高度保密 于 2015-1-31 14:04 编辑

关于质数的相关规律:
1、一个数只有1和它本身两个因数,这个数叫作质数。
2、1既不是质数,也不是合数。
3、2,3,5,7外所有2,3,5,7的倍数都不是质数。
4、2是偶数中唯一的质数,其他质数都是奇数。

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-1-31 00:32 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
高度保密 发表于 2015-1-30 22:32
59楼很快,但是部分数据无效,还需要改进 。比如32到122之间的的数会出错。

还有,1不是素数

【但是部分数据无效,还需要改进 。比如32到122之间的的数会出错。】

错误原因:
系数参数表输错1个。第3个系数应为0.5,不是0.25……定义数组太小,导致计算后溢出。

……原帖已更正。

TA的精华主题

TA的得分主题

发表于 2015-1-31 13:30 | 显示全部楼层
hehex 发表于 2015-1-30 12:15
其实求质数并不是很初级的算法,尤其到test5 已经很高深了,很不适合初学者了。
转发一篇一位大神(某大 ...

山外有山、天外有天

TA的精华主题

TA的得分主题

发表于 2015-1-31 21:47 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
香川群子 发表于 2015-1-30 17:18
本帖问题的算法总结:

① 仅需检查

小時候第一次寫質數表時,只使用了篩法
這個討論串的一系列優化方法,當初都是看一個優秀的程式碼之後
自行揣摩出來的…要是當時有這麼好的教學文件,相信能省下很多時間~
很喜歡這種風格的教學文件,相信對初學者應該很有幫助~

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2015-2-2 18:47 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2015-2-2 21:04 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2015-2-2 21:58 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2015-2-18 17:26 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 下标越界 于 2015-2-18 18:31 编辑
香川群子 发表于 2015-1-29 10:49
最基本、最简单的算法测试test1

要搁我这写,首先会是一个test0()
  1. Sub test0()
  2.     Dim i&, j&, k&, n&, a()
  3.    
  4.     n = [a1]
  5.    
  6.     ReDim a(1 To n)
  7.     k = 1
  8.     For i = 2 To n + 1
  9.        a(k) = i
  10.         For j = 2 To i - 1
  11.             If i Mod j = 0 Then k = k - 1: Exit For
  12.         Next j
  13.         k = k + 1
  14.     Next i

  15.    If a(k-1) > n Then a(k-1) = ""
  16.    
  17.     If k < 65536 Then [b:b] = "": [b1].Resize(k) = Application.Transpose(a)
  18.    
  19. End Sub

复制代码

补充内容 (2015-2-23 22:15):
怎么下面没人跟回复?那么我继续回复提问了:

TA的精华主题

TA的得分主题

发表于 2015-2-23 22:22 | 显示全部楼层
本帖最后由 下标越界 于 2015-2-23 22:42 编辑

按群子老师的test9对1千2百万范围内的整数筛选出788060个素数。
想象中按照分块显示输出到excel表格中,分块规则如下:
       每100个素数为一块,每块中按10X10排列;每25个“块”横向排成“一排”,每超过25个块就换“下一排”。于是很自然地有了如下代码:
  1. Sub test9()

  2.     Dim t1, t2, r11, c11, tab1

  3.     Dim i&, j&, k&, m&, n&, tim1, tim2
  4.     n = [a1]
  5.    
  6.       tim1 = Timer
  7.     m = (n - 1) \ 2: ReDim a(1 To m) As Boolean
  8.     For i = 1 To Sqr(n) \ 2
  9.         If a(i) = False Then
  10.             For j = i * 3 + 1 To m Step i * 2 + 1
  11.                 a(j) = True
  12.             Next
  13.         End If
  14.     Next
  15.    
  16.     nSize = Array(1, 1, 0.5, 0.17, 0.125, 0.1, 0.08, 0.067, 0.058, 0.055)
  17.     k = n * nSize(Log(n) / Log(10))
  18.     ReDim b&(1 To k): b(1) = 1: b(2) = 2: k = 2
  19.     For i = 1 To m
  20.         If a(i) = False Then k = k + 1: b(k) = i * 2 + 1
  21.     Next
  22.    
  23.     tim2 = Timer
  24.     Cells(1, 2) = "test9范围" & n & "耗时" & tim2 - tim1 & "秒"
  25.     ReDim Preserve b&(1 To k)
  26.     '[a9] = k: If k < 65536 Then [b:b] = "": [b1].Resize(k) = Application.Transpose(b)
  27.   
  28.    t1 = Timer
  29.    
  30.         ' r1 = Int((k - 1) / 100) + 1
  31.          r11 = Int((k - 1) / 2500) + 1
  32.         
  33.         
  34.         
  35. On Error Resume Next
  36.         For i = 1 To r11
  37.           For j = 1 To 25
  38.             Set tab1 = Cells(1 + (i - 1) * 10 + 1, 1 + (j - 1) * 10 + 1)
  39.             Range(tab1, tab1.Offset(9, 9)).Interior.Color = RGB(255 * (1 + (-1) ^ j) / 2, 255 * Round(Rnd), 255 * Round(Rnd)) '(1 + (-1) ^ (j + 1)) / 2)
  40.             For o = 1 To 100
  41.               Cells(Int((o - 1) / 10) + 1 + (i - 1) * 10 + 1, (o - 1) Mod 10 + 1 + (j - 1) * 10 + 1) = b((i - 1) * 2500 + (j - 1) * 100 + o)
  42.    
  43.         Next o, j, i
  44.   

  45.    t2 = Timer
  46.    Cells(1, 3) = "输出耗时" & t2 - t1 & "秒"
  47.    Cells(1, 4) = k & "个素数"
  48.    
  49. End Sub
复制代码
结果如下:

输出时间太长了,有办法缩短吗?

另外,为了直观上区分各个数据块,采取了给每个块添加不同底色(且相邻块色差很明显)的方式,但如下图所示,显然失败了,相邻区域经常出现相同底色,产生“连成一片”的效果了,第二问来了:如何设置,使得每块底色不同于四周且对比色差明显。楼下有人继续接吧。

缩放到最小后的整体

缩放到最小后的整体

截图

截图
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-5-12 14:41 , Processed in 0.041805 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

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