Excel精英培训网

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

[分享] 【烟花原创】VBA零基础之第132篇 字典(九)

[复制链接]
发表于 2014-3-22 23:05 | 显示全部楼层 |阅读模式
四、实战
3双向查询
平时在字典中我们都是根据KeyItem,如果要根据ItemKey了?
当然可以,不过得思路稍作转变。
在添加KeyItem时,如果把Item当成KeyKey当成Item添加到字典中,这样不就可以实现双向查询了嘛。
不过需要注意的是Item必须具有唯一性。

数据源:


代码:

数据源中特意加了简称重复的城市名,然后利用错误处理机制,再给出提示后再接着运行。
另外,对于数据源中的城市名与简称数据(KeyItem)没有做检测,实际中使用还是添加数据校验比较好。虽然代码会显得冗长,但是这是一种好的习惯。


思考:
是否还可以利用别的方法(简易与复杂均可)或者字典本身来实现双向查询?
发表于 2014-3-23 19:29 | 显示全部楼层
如果数据都是一对一,那么把key对应的item存入字典后,
再把item作为key、key作为item存入同一字典即可实现你所谓的【双向查询】。毫无技巧可言。

回复

使用道具 举报

发表于 2014-3-23 21:23 | 显示全部楼层
香川群子 发表于 2014-3-23 19:29
如果数据都是一对一,那么把key对应的item存入字典后,
再把item作为key、key作为item存入同一字典即可实现 ...

但不可否认的是,这对于初学者来说确是很好的一种解决方案!
如果您有更好的解决方案,不妨共享一下,让我们大家一起学习一下!!
回复

使用道具 举报

发表于 2014-3-23 23:36 | 显示全部楼层
FF7 发表于 2014-3-23 21:23
但不可否认的是,这对于初学者来说确是很好的一种解决方案!
如果您有更好的解决方案,不妨共享一下,让 ...

如有实际使用必要,倒还是分开两个字典为好……逻辑结构的清晰很重要。

省去一个字典能带来额外的好处么?

所以这个想法虽然在条件限定时可行,仍会被我当做奇巧淫技,不予认可。

…………
编程时,算法比手段更重要。
而所谓好的算法,应该是能采用越简单的手段高效解决问题时水平越高。

另外,人是聪明的、复杂的,
但要让计算机高效工作,却往往需要采取简单愚蠢的方法反而更可靠、更有效。



回复

使用道具 举报

发表于 2014-3-24 00:06 | 显示全部楼层
香川群子 发表于 2014-3-23 23:36
如有实际使用必要,倒还是分开两个字典为好……逻辑结构的清晰很重要。

省去一个字典能带来额外的好处 ...

大家都是编程爱好者,耍嘴皮子有什么用。
你有什么高招尽管拿出来,好的东西,大家自然推崇备至。
你所说的两个字典,这也叫好的算法?
显然一个字典的用法比你的两个字典的用法代码更精练,而功能却一模一样!
如果要比较算法,且不如就以此贴所列条件为核心,城市和简称一一对应且不重复。如何更高效的达到双向查询。
如果你能给出更简单高效的代码,我即刻辞任版主,说到做到!

烟花技法虽然我觉得并不一定很成熟,但hwc2ycy却是一如既往的坚持在做,而且代码基本都经过详细编注,以提供给更多想学习的人学习,这是非常难能可贵的。但如此这般却被人冠以奇巧淫技,要么你技艺超群,傲视天下,要么不过哗众取宠一跳梁小丑罢了!

点评

谢谢77,淡定。  发表于 2014-3-24 16:45
回复

使用道具 举报

发表于 2014-3-24 08:24 | 显示全部楼层
用2个字典何以就一定不如只用一个字典的代码好?

【就以此贴所列条件为核心,城市和简称一一对应且不重复。】
这个往往只是前期数据处理的工作,真正的使用那是后来的事。
应该根据实际需求来决定。所以就前面部分来判断优劣,甚为不妥。

…………
不过你斗气都到这个份上了,我也就呵呵了。


回复

使用道具 举报

发表于 2014-3-24 08:57 | 显示全部楼层
率性之人,有口无心,不必当真,一个哈哈而已


就这东东,用一个字典两个字典,谁就绝对比谁好?看来难说,也没必要纠结于此
到是版主on error,此处不用也罢,个人常称其为万恶之源
回复

使用道具 举报

发表于 2014-3-24 16:04 | 显示全部楼层
本帖最后由 香川群子 于 2014-3-24 20:36 编辑
FF7 发表于 2014-3-24 00:06
大家都是编程爱好者,耍嘴皮子有什么用。
你有什么高招尽管拿出来,好的东西,大家自然推崇备至。
你所 ...


正好现在有些空余时间,简单写了个模拟代码:
  1. Sub test()
  2.     Dim arr$(), d, d1, d2, i&, j&, k&, m&, p&, tms#
  3.     p = 2
  4.     m = 10 ^ 4
  5.     ReDim arr$(1 To m, 1 To 2)
  6.     For i = 1 To m
  7.         arr(i, 1) = Chr(Int(Rnd * 26 + 65)) & Int(Rnd * m)
  8.         arr(i, 2) = Chr(Int(Rnd * 26 + 65)) & Int(Rnd * m)
  9.     Next
  10.    
  11.     Debug.Print vbCr; Format(m * 10 ^ p, "#,##0"); vbCr
  12.     tms = Timer
  13.     Set d = CreateObject("Scripting.Dictionary")
  14.     For j = 1 To 10 ^ p
  15.         For i = 1 To m
  16.             d(arr(i, 1)) = arr(i, 2)
  17.             d(arr(i, 2)) = arr(i, 1)
  18.         Next
  19.     Next
  20.     Debug.Print d.Count
  21.     Set d = Nothing
  22.     Debug.Print Format(Timer - tms, "0.000s")
  23.    
  24.     tms = Timer
  25.     Set d1 = CreateObject("Scripting.Dictionary")
  26.     Set d2 = CreateObject("Scripting.Dictionary")
  27.     For j = 1 To 10 ^ p
  28.         For i = 1 To m
  29.             d1(arr(i, 1)) = arr(i, 2)
  30.             d2(arr(i, 2)) = arr(i, 1)
  31.         Next
  32.     Next
  33.     Debug.Print d1.Count; vbCr; d2.Count
  34.     Set d1 = Nothing
  35.     Set d2 = Nothing
  36.     Debug.Print Format(Timer - tms, "0.000s")
  37.    
  38. End Sub
复制代码
代码有i修改……
        arr(i, 1) = Chr(Int(Rnd * 26 + 65)) & Int(Rnd * m)
        arr(i, 2) = Chr(Int(Rnd * 26 + 65)) & Int(Rnd * m)
我下午发代码时,忘了加转换为英文字符的Chr()函数了。
另外修改后的代码,增加了字典项数d.Count结果的输出。

毫无疑问数据量较大时,使用2个字典反而速度效率更好。

为啥呢?不知道你是否看了我前面的科普帖子。
http://www.excelpx.com/thread-320803-1-1.html

如果你本来就知道字典的算法原理,那么应该很容易理解为什么用2个字典会更快一些。
回复

使用道具 举报

发表于 2014-3-24 17:58 | 显示全部楼层
香川群子 发表于 2014-3-24 16:04
正好现在有些空余时间,简单写了个模拟代码:毫无疑问数据量较大时,使用2个字典反而速度效率更好。

为 ...

每个人都不容易,不管是做什么,人与人之间需要的是多一些体谅,多一些理解。
OK,我不是什么高手,不是科班出身,VBA全部靠自学来的。我大学学的是植物保护,与计算机毫不沾边,所以对于你的高深理论才疏学浅,不仅仅看不懂,甚至完全无知。

作为EP的版主,hwc2ycy所倾注的时间是若干人的N倍,烟花技法可能不那么成熟,但绝对是hwc2ycy呕心沥血的作品,而且其严谨性、知识性和实用性是绝对值得一看的。
我话说得有点过头,无所谓,男子汉大丈夫,头顶天,脚踏地,言出必行,就算是输了版主的职务,我依然会力挺hwc2ycy,他的作品绝非您这位大师所呲之以鼻的不予认可的毫无技巧的玩意儿。

再言之,就算我辈技不如人,但不蒸馒头争口气,就算是版主与版主之间的惺惺相惜也好,也不至于被人冠以“淫”技也毫不反击。

代码你看好了:
  1. Sub test()
  2. Dim arr$(), d As Object, d1 As Object, d2 As Object, i&, j&, k&, m&, p&, tms#
  3. p = 2
  4. m = 10 ^ 4
  5. ReDim arr$(1 To m, 1 To 2)
  6. For i = 1 To m
  7. arr(i, 1) = 2 * i - 1
  8. arr(i, 2) = 2 * i
  9. Next


  10. Debug.Print vbCr; Format(m * 10 ^ p, "#,##0"); vbCr
  11. tms = Timer
  12. Set d1 = CreateObject("Scripting.Dictionary")
  13. Set d2 = CreateObject("Scripting.Dictionary")
  14. For j = 1 To 20000
  15. For i = 1 To 128
  16. d1(arr(i, 1)) = arr(i, 2)
  17. d2(arr(i, 2)) = arr(i, 1)
  18. Next
  19. Next
  20. Set d1 = Nothing
  21. Set d2 = Nothing
  22. Debug.Print "You:" & Format(Timer - tms, "0.000s")


  23. tms = Timer
  24. Set d = CreateObject("Scripting.Dictionary")
  25. For j = 1 To 20000
  26. For i = 1 To 128
  27. d(arr(i, 1)) = arr(i, 2)
  28. d(arr(i, 2)) = arr(i, 1)
  29. Next
  30. Next
  31. Set d = Nothing
  32. Debug.Print "Me :" & Format(Timer - tms, "0.000s"), vbCrLf


  33. tms = Timer
  34. Set d1 = CreateObject("Scripting.Dictionary")
  35. Set d2 = CreateObject("Scripting.Dictionary")
  36. For j = 1 To 1000
  37. For i = 1 To 2560
  38. d1(arr(i, 1)) = arr(i, 2)
  39. d2(arr(i, 2)) = arr(i, 1)
  40. Next
  41. Next
  42. Set d1 = Nothing
  43. Set d2 = Nothing
  44. Debug.Print "You:" & Format(Timer - tms, "0.000s")

  45. tms = Timer
  46. Set d = CreateObject("Scripting.Dictionary")
  47. For j = 1 To 1000
  48. For i = 1 To 2560
  49. d(arr(i, 1)) = arr(i, 2)
  50. d(arr(i, 2)) = arr(i, 1)
  51. Next
  52. Next
  53. Set d = Nothing
  54. Debug.Print "Me :" & Format(Timer - tms, "0.000s")
  55. End Sub
复制代码
你自己测试。
为什么我会改变循环的范围,原因在于字典上面代码中,字典的最大数目是256个。
为什么用128。因为你的两个数组d1,d2和d数组均不会超出256的范围。也就是d(arr(i,1))循环会始终在范围内运行。

才疏学浅,我解释不了为什么时间长短不一,或许当字典元素超出256个范围,不存在的情况下,每循环一次可能都要“完全寻址”一次,所以时间长短不一吧!!!!
回复

使用道具 举报

发表于 2014-3-24 20:16 | 显示全部楼层
呵呵,我到这里的时间不长……对于版主们的圈子没兴趣。

版主辛苦为了大家这个我能理解。

但我发表一些个人意见的自由应该是有的。
且即使我认为某个解法不好,也只是我个人的意见,仅供参考。我也没那么大的影响力。
再说,这肯定不代表着我是冲着某个发帖的人来的……无冤无仇啊。

呵呵。你火气这么大我真的不能理解,不过也算了。没啥好争的。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-2 08:26 , Processed in 0.360454 second(s), 7 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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