ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[原创] 打造自己的字典

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2017-12-19 09:30 | 显示全部楼层
非技术人员(财会,营销,市场,HR,采购,物流)用excel现在的字典足够了。但话说回来,如果你是专业技术人员的话。。。。。。那学什么VBA啊?

TA的精华主题

TA的得分主题

发表于 2017-12-19 10:46 | 显示全部楼层
除了惊叹于Zamyi大侠的水平,无语!
单元有机会领悟并能用此字典!!
谢谢Zamyi赐教赐惠于大家!!

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-12-19 11:04 | 显示全部楼层
本帖最后由 Zamyi 于 2017-12-19 11:21 编辑
aman1516 发表于 2017-12-18 21:28
这句声明显示红色:
Private Declare PtrSafe Function hash Lib "ntdll.dll" Alias "RtlComputeCrc32" (  ...

本程序在win64位没问题,没有32位系统,试试把PtrSafe删除看行不?再不行把它删除,自定义一个,调用它也修改一下:
  1. Private Function Hash(s As String) As Long
  2. Dim i&
  3. For i = 1 To Len(s)
  4.   Hash = Hash * 127 + AscB(Mid(s, i, 1))
  5. Next
  6. End Function
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-12-19 11:09 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
zopey 发表于 2017-12-18 22:31
建立在 随机数上的 哈希数组 比较占内存吧。

如何多占用内存?Hash_Index为Long,为BCount两倍,比pKeys()还小。

TA的精华主题

TA的得分主题

发表于 2017-12-19 18:18 | 显示全部楼层
Dict(Key)=Item的写法,可参考这个贴:
http://club.excelhome.net/thread-1244670-1-1.html

用API函数生成hash值,好!

用固定种子的Rnd序列来产生下一个hash位置的思想,很有创意,但不知会不会出现存在的Key找不到等情况,我没想清楚。

目前的字典,存在取不到Item值的情况,楼主可测试一下。

期待楼主进一步完善之。

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-12-19 20:14 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
三坛老窖 发表于 2017-12-19 18:18
Dict(Key)=Item的写法,可参考这个贴:
http://club.excelhome.net/thread-1244670-1-1.html

原来如此,谢谢。

TA的精华主题

TA的得分主题

发表于 2017-12-19 22:24 | 显示全部楼层
是用類模組啊,沒法看懂
太強大了
但我也沒覺得字典很慢,要多大的數據才會覺得字典慢啊?
難道每每是數十萬至百萬?

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-12-20 11:06 | 显示全部楼层
本帖最后由 Zamyi 于 2017-12-20 14:54 编辑

采用最极端的测试,Add过程改为:
  1. Public mm&
  2. Public Sub Add(Key As Variant, Item As Variant)
  3. Dim i&, R As Single
  4. k = Key Mod Hash_Count  ' (hash(0, StrPtr(Key), LenB(Key)) And &H7FFFFFFF) Mod Hash_Count
  5. If pCount = BCount Then Call Dilate
  6. R = Rnd(pSeed)
  7. Do
  8.   If Hash_Index(k) = 0 Then Exit Do
  9.   If StrComp(Key, pKeys(Hash_Index(k))) = 0 Then MsgBox "该关键字已存在!": End
  10.   k = (k + Hash_Count * Rnd) Mod Hash_Count
  11.   mm = mm + 1
  12. Loop
  13. pCount = pCount + 1
  14. pKeys(pCount) = Key
  15. pItems(pCount) = Item
  16. Hash_Index(k) = pCount
  17. End Sub
复制代码

测试程序如下:
  1. Public Sub test()
  2. Dim d As New zDict, i&, n&, a()
  3. n = 10000
  4. ReDim a(1 To n)
  5. Randomize
  6. For i = 1 To n
  7.   a(i) = (i - 1) * n * 2 + 1
  8. Next
  9. t = Timer
  10. d.SetBudgetCount n
  11. For i = 1 To n
  12.   d.Add a(i), i
  13. Next
  14. [e1] = Timer - t
  15. [f1] = d.mm/n
  16. End Sub
复制代码

相当于每增加一个不同Key,都是相同的k值,结果依然不出错,只是寻找达6000多次(1万Keys)。而一般随机数,查找仅为1.3~1.4次。说明Rnd还是可行的。

TA的精华主题

TA的得分主题

发表于 2017-12-20 13:18 | 显示全部楼层
win7-32 ,无法运行,什么时候我换个64位的系统试一下。

不过我觉得如果数据量巨大,比如有10^6个不行同的数据,也就是有10^6个键值。如果使用单个字典当数据量达到一定数据量时字典的效率明显降低,假设这个拐点值数为10^5,那可建一个字典数组1 to 10,因为10^5以下字典的速度基本线性,那数组内所有字典的速度也是线性的。

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-12-20 14:13 | 显示全部楼层
一把小刀闯天下 发表于 2017-12-20 13:18
win7-32 ,无法运行,什么时候我换个64位的系统试一下。

不过我觉得如果数据量巨大,比如有10^6个不行同 ...

已修改,再试试 32位行不。另,10^6和10^5也就差10倍左右,完全无必要建立多个字典。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

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

GMT+8, 2024-12-24 04:33 , Processed in 0.046018 second(s), 6 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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