如何快速取出一个dictionary 中top N的值所对应的键?

索思索想 2016-01-13 09:32:21
需要从一个很大的字典中取出值最大的20个键,请问有没有什么比较快的方法?时间复杂度大概是多少?
...全文
360 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
索思索想 2016-01-14
  • 打赏
  • 举报
回复
引用 13 楼 sp1234 的回复:
如 Dictionary 和 sortedList 都是必要的,那么你可以分别建立这样两个类型的对象,对于同一个数据实体分别放入这两个数据结构中(删除也是一样去分别删除)。
引用 14 楼 sp1234 的回复:
“多花一倍的时间”是什么数量级的时间?
谢谢你的意见。 因为数据集比较大,所以尽量想避免多次的循环遍历。 想了一下,在插入时做排序应该是O(NLogK)的时间复杂度,这个时间开销应该是可承受的。
索思索想 2016-01-14
  • 打赏
  • 举报
回复
引用 10 楼 starfd 的回复:
这么说吧,在Dictionary里面,数据都是乱序排列的,所以如果你必须Dictionary,而且没有任何key与value的特殊关系(比如key大,value也大),那么没有任何办法,只能循环遍历 如果你的Dictionary的值在加载完后就不会发生变化,那你还可以通过其它数据结构来存储value的部分 还有如果你不是要通过key来取值,那么你也可以考虑用List<KeyValuePair<T1,T2>>这种
谢谢你的建议,因为的确是要用到Key的检索,数据集又比较大,所以只能用Dictionary。 目前想到的方法只能是同时维护两个数据结构了。
xuzuning 2016-01-14
  • 打赏
  • 举报
回复
因为 Dictionary 是无序的,所以一趟遍历是少不掉的 你需要取出值最大的 20 个元素,所以可以创建一个规模为 20 的 List(排序是针对该 List 的) 对于每一个 KeyValuePari 如果其 Value 大于 List<KeyValuePari>[0].Value则替换入 List<KeyValuePari> 并排序
  • 打赏
  • 举报
回复
引用 12 楼 Rino 的回复:
谢谢,目前我想到的也是再建立一个List用来存储Top 20的数据。 不过这样时间复杂度似乎也不低,因为做插入删除时等于要多花一倍的时间。 我再想想看有没有其它方法来解决这个问题。
“多花一倍的时间”是什么数量级的时间?
  • 打赏
  • 举报
回复
如 Dictionary 和 sortedList 都是必要的,那么你可以分别建立这样两个类型的对象,对于同一个数据实体分别放入这两个数据结构中(删除也是一样去分别删除)。
索思索想 2016-01-14
  • 打赏
  • 举报
回复
引用 4 楼 Forty2 的回复:
[quote=引用 3 楼 Rino 的回复:] ...我要的不是key排序,而是Value值最大的N个KeyValuePair的键值...
时间复杂度为O(N*log(K)),其中N是字典中项目总数,K是你要取得的项目数。 如果操作主要集中在取最大的20个上,你也可以维护一个双重的数据结构,即数据同时放在一个字典,和一个排序数列中。 从排序列中拿20个最大值就很简单了,O(K)。缺点就是双重数据结构的空间消耗,以及插入和删除等写操作需要同步到两个结构。 [/quote] 谢谢,目前我想到的也是再建立一个List用来存储Top 20的数据。 不过这样时间复杂度似乎也不低,因为做插入删除时等于要多花一倍的时间。 我再想想看有没有其它方法来解决这个问题。
正怒月神 2016-01-14
  • 打赏
  • 举报
回复
引用 9 楼 Rino 的回复:
[quote=引用 7 楼 hanjun0612 的回复:] 用list<T>然后orderby value一下,take(20)就好了
这种方法当然可以,但是时间复杂度高了不少吧? Top20以后的所有元素也进行排序了,而这是没有必要的,特别是在数据集很大的情况下,时间开销有点大了。[/quote] 那能否 在 数据添加到 list中的时候,进行一个排序,或者说添加一个字段,添加过程中,标记一下(类似于索引的概念了)然后在获取时,通过这个标记列来拿。当然这个方法 dictionary是没办法采用了。
  • 打赏
  • 举报
回复
这么说吧,在Dictionary里面,数据都是乱序排列的,所以如果你必须Dictionary,而且没有任何key与value的特殊关系(比如key大,value也大),那么没有任何办法,只能循环遍历 如果你的Dictionary的值在加载完后就不会发生变化,那你还可以通过其它数据结构来存储value的部分 还有如果你不是要通过key来取值,那么你也可以考虑用List<KeyValuePair<T1,T2>>这种
索思索想 2016-01-14
  • 打赏
  • 举报
回复
引用 7 楼 hanjun0612 的回复:
用list<T>然后orderby value一下,take(20)就好了
这种方法当然可以,但是时间复杂度高了不少吧? Top20以后的所有元素也进行排序了,而这是没有必要的,特别是在数据集很大的情况下,时间开销有点大了。
索思索想 2016-01-14
  • 打赏
  • 举报
回复
引用 6 楼 starfd 的回复:
如果你是要取value,那为啥还要用Dictionary呢?
因为这个Dictionary还有其它的用处,取top 20的Value对应的Key只是一部分而已。
正怒月神 2016-01-14
  • 打赏
  • 举报
回复
用list<T>然后orderby value一下,take(20)就好了
  • 打赏
  • 举报
回复
如果你是要取value,那为啥还要用Dictionary呢?
Justin-Liu 2016-01-14
  • 打赏
  • 举报
回复
说白了就是一个排序算法
Forty2 2016-01-14
  • 打赏
  • 举报
回复
引用 3 楼 Rino 的回复:
...我要的不是key排序,而是Value值最大的N个KeyValuePair的键值...
时间复杂度为O(N*log(K)),其中N是字典中项目总数,K是你要取得的项目数。 如果操作主要集中在取最大的20个上,你也可以维护一个双重的数据结构,即数据同时放在一个字典,和一个排序数列中。 从排序列中拿20个最大值就很简单了,O(K)。缺点就是双重数据结构的空间消耗,以及插入和删除等写操作需要同步到两个结构。
索思索想 2016-01-13
  • 打赏
  • 举报
回复
引用 1 楼 starfd 的回复:
不要用Dictionary,而是用SortedDictionary,这样你只要顺序或者倒序遍历20个就可以了(具体顺序还是倒序看你是怎么排序的)
引用 2 楼 shingoscar 的回复:
SortedDictionary也是用于键排序的 所以,如果事先不是排序好的,只能通过遍历,复杂度为O(nN)
我要的不是key排序,而是Value值最大的N个KeyValuePair的键值,SortedDictionary应该是按键的大小排序的吧?
Poopaye 2016-01-13
  • 打赏
  • 举报
回复
SortedDictionary也是用于键排序的 所以,如果事先不是排序好的,只能通过遍历,复杂度为O(nN)
  • 打赏
  • 举报
回复
不要用Dictionary,而是用SortedDictionary,这样你只要顺序或者倒序遍历20个就可以了(具体顺序还是倒序看你是怎么排序的)

110,529

社区成员

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

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

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