根据 Dictionary 编写了个非重复的,可按索引访问的,可快速查找的,NonDupList

jmcooler 2015-05-17 04:28:57
有没有同样需求的,可以找我咨询。

准备写一篇博客,以解析 Dictionary 内部的实现代码,并会附上我这个 NonDupList 源码
...全文
232 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
非重复的,可按索引访问的,可快速查找的 这个跟Dictionary有什么区别呢?
本拉灯 2015-05-18
  • 打赏
  • 举报
回复
重复造车。。。。
於黾 2015-05-18
  • 打赏
  • 举报
回复
原理不就是链表吗?
jmcooler 2015-05-18
  • 打赏
  • 举报
回复
HashSet 和 Dictionary 完全一样,唯一区别只是一个单对象,一个存储键值对。 HashSet 仅仅提供了去重和 Forward 枚举,不提供按索引访问,向后枚举。查找,就提供一个 Contains() HashSet 和 Dictionary,没什么了不起的,你熟悉的话,半天可以重构完成。不熟悉的话,也最多花 1 天就搞定。 咋就那么怕麻烦呢
  • 打赏
  • 举报
回复
HashSet<T>完全满足快速查找的需要,可惜和hashtable一样是无序的,这正在哈希算法散列的体现,元素之间的地址通常都是不连续的 所谓的按索引快速访问,可以理解为: public T this[int index] { var key = this.Keys[index]; return this[key]; }
jmcooler 2015-05-18
  • 打赏
  • 举报
回复
引用 10 楼 Z65443344 的回复:
你只要求用索引访问,反而不要求用字符串内容去访问? 那完全可以使用List<string>啊,跟Dictionary有什么关系
如果只是成千上万,在 List<string> 搜索一个字符串,倒也不费事。遍历速度是很快的,关键是每个字符串,都要和正查找的字符串比对,这就慢了。假定有一个上 G 的字符串,你每搜索一次,你看要多久? 问题还在于 List<string> 不能去重啊,我还要动态去重啊
jmcooler 2015-05-18
  • 打赏
  • 举报
回复
回复 ojekleen: 是的,正是要重构 Dictionary,在它内部维护的 buckets 和 entries 上,添加一些按索引访问的函数即可。 因此,我没有重复造车,也不愿意干这种事。 我只需要一个适合需求的数据结构,而 .net 没法提供合适的。 绝不要认为,.NET 提供的类型,都够用了。总不愿意重复造车,这过左了
於黾 2015-05-18
  • 打赏
  • 举报
回复
我要处理成千上万的字符串 如果你只是要处理字符串,完全没看出有什么必要快速查找
於黾 2015-05-18
  • 打赏
  • 举报
回复
你只要求用索引访问,反而不要求用字符串内容去访问? 那完全可以使用List<string>啊,跟Dictionary有什么关系
jmcooler 2015-05-18
  • 打赏
  • 举报
回复
当然,办法多的是。完全可以用一个 List<string>,外加一个 HashSet<string> 两个数据结构,来模拟完成同样的需求。 List<string> 负责按索引访问,HashSet<string> 用来去重。可是要把他俩协调起来,比起重构 Dictionary 还要费事。我不是没试过。 而关键是,List<string> 根本就不能实现快速查找,如果用成 List< HashObject<string> >,那就得分配 4 G 的内存,才能实现按 hash 值快速查找。
ojekleen 2015-05-18
  • 打赏
  • 举报
回复
印象中dictionary中有int[]来维护插入顺序的,也就是连array[str.GetHashCode()]方法都不用封装,直接通过int[]来查找
ojekleen 2015-05-18
  • 打赏
  • 举报
回复
引用 6 楼 jmcooler 的回复:
是否我重复造车了呢? 现在我提出一个需求,我要处理成千上万的字符串,首先要求去重,其次要求能像数组一样用下标访问,还要具有像 Dictionary 一样的查找速度,还要尽量保持元素的添加顺序(但不要求删除元素)。 这些字符串,可以从磁盘加载(有可能被用户手动添加或者删除),并可能在运行期间动态增加 我想请问一下,.NET 的那个数据结构,能办到? Dictionary 貌似是可以的,但它不提供按下标访问元素,向前或向后遍历。 Dictionary 由 Enumerable.ElementAt( int index ) 扩展的方法,倒是可以按索引访问,但它是调用 IEnumerable() 并总是从头遍历到 index 位置,并返回该位置上的元素。如果 ElementAt() 大面积被调用,它就会造成大麻烦。 将 Dictionary 稍加剖析,就可以设计出一个满足这种要求的非重复的,按索引访问,向前向后遍历,查找速度快,保持元素添加顺序的数据结构。
你的意思不就是说dictionary少个下标访问吗?没理解错吧?如果需要,封装一下array[str.GetHashCode()]方法是不是就可以了?
jmcooler 2015-05-18
  • 打赏
  • 举报
回复
是否我重复造车了呢? 现在我提出一个需求,我要处理成千上万的字符串,首先要求去重,其次要求能像数组一样用下标访问,还要具有像 Dictionary 一样的查找速度,还要尽量保持元素的添加顺序(但不要求删除元素)。 这些字符串,可以从磁盘加载(有可能被用户手动添加或者删除),并可能在运行期间动态增加 我想请问一下,.NET 的那个数据结构,能办到? Dictionary 貌似是可以的,但它不提供按下标访问元素,向前或向后遍历。 Dictionary 由 Enumerable.ElementAt( int index ) 扩展的方法,倒是可以按索引访问,但它是调用 IEnumerable() 并总是从头遍历到 index 位置,并返回该位置上的元素。如果 ElementAt() 大面积被调用,它就会造成大麻烦。 将 Dictionary 稍加剖析,就可以设计出一个满足这种要求的非重复的,按索引访问,向前向后遍历,查找速度快,保持元素添加顺序的数据结构。
jmcooler 2015-05-18
  • 打赏
  • 举报
回复
Dictionary 具有如下特性:压缩了 hash 值范围,并基本上按 Array 一样访问元素,自适应元素的数量 我们假定有这样一个结构体: struct HashObject<T> { int HashCode; T Value; } 用这个结构体来存储一个泛型对象 T 及其 hash 值。 如果我们再用数组 HashObject<string>[] array; 来存储所有字符串对象,那么要查询一个字符串 str,则: string queryResult = array[str.GetHashCode()]; 这个查询的运算复杂度是 O(1)。Dictionary 原理上,就是用这种线程数组来存储对象及其 hash 值 但是,由于对象的 hash 值范围在 4 GB 的范围内,因此这个 array 应该分配 4 GB 的内存,这显然是不可能的。 那么就得找一个条件来压缩 hash 值范围。 Dictionary 本质上具有如下特性:压缩 hash 值范围,并基本上按 Array 一样存取元素,自适应元素的数量。 因此它的查询运算复杂度仍然接近 O(1)。 自适应元素的数量,是指它可以根据要存储的元素数量,动态压缩 hash 值范围
skyandcode 2015-05-17
  • 打赏
  • 举报
回复
非重复、可快速查找没看出是什么意思。

111,094

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧