c语言 单词按字典排序,关于C#:根据键对字典进行排序

我有一本C语言的字典

Dictionary

我想把字典按照键(class person中的一个字段)进行排序。我该怎么做?互联网上所有可用的帮助都是列表帮助,没有特定的字典就地排序示例。任何帮助都将不胜感激!

我不确定我理解你的问题,因为字典没有按任何顺序列举?您可以迭代键或值,这些键或值可以很容易地动态排序…

这不可能是你真正想要的。数组可以就地排序,因为对数组排序的结果是一个数组。但是字典不是数组,因此不能用对其条目排序的结果替换它。排序条目并将结果保存到数组或列表中。接受的答案可能不是你想要的…从SortedList或SortedDictionary输入和访问条目比从字典输入和访问条目慢得多。

你不能对一个Dictionary进行排序——它本质上是无序的。(或者更确切地说,条目的检索顺序是特定于实现的。您不应该以相同的方式在版本之间工作,因为排序不是其设计功能的一部分。)

您可以使用SortedList或SortedDictionary,这两种类型都是按键排序的(以可配置的方式,如果您将IEqualityComparer传递到构造函数中),这些可能对您有用吗?

很少注意名称SortedList中的单词"list"——它仍然是一个字典,因为它将键映射到值。它是在内部使用一个列表来实现的,非常有效——因此,它不使用哈希代码进行查找,而是进行二进制搜索。SortedDictionary同样基于二进制搜索,但通过树而不是列表。

但是,要小心使用SortedList:如果构建一个大的列表(假设项目不是预先排序的),它将非常慢。通常您应该使用SortedDictionary来代替,或者使用第三方BDictionary来获得与SortedDictionary类似的性能,而不会丢失按索引或"查找最近的键"访问项目的能力。

二进制搜索的优势是什么,而不是在排序的键旁边维护哈希?如果我不是只做有序的枚举,为什么我关心元素是有序的?如果我更关心单个元素的查找,但第二种情况是想根据键顺序进行枚举,那么我是不是一直在管理一个单独的键列表,一个La Steve的答案?如果这是我的理想用途,那么SortedList和SortedDictionary实际上是错误的工具,对吗?也就是说,如果我真的只想在适当的位置对字典键进行排序呢?

@鲁芬:优势在于避免复杂性。是的,据我所知,没有内置的"排序和散列"集合。注意,这样的集合很难使用,也很难构建——必须同时提供相等比较、哈希代码函数以及排序函数。当然,保存这两个集合也需要一定的内存成本。您需要测量二进制搜索与散列查询的成本,以查找实际数据——您很可能会发现,除非您的收集量很大,否则它实际上并不重要。

@Ruffin"二进制搜索的优点是什么,而不是在排序键旁边维护哈希?"--哈希表的内存以及添加或删除条目时维护它的时间。"为什么我关心元素的顺序呢?——如果你不关心元素的顺序,那么就使用字典(我通常建议使用SortedList或SortedDictionary),但第二种方法是根据键顺序进行枚举——当你偶尔需要时,对枚举的键值对进行排序是很简单的:dict.orderby(kV= kV键

@Ruffin"如果我真的只想在适当的位置对字典键进行排序怎么办?"--没有这样的事情——这是一个类别错误。数组可以就地排序…任何不是数组的东西都不能。(好吧,除了具有可变节点的链表,但是在适当的位置对这样的东西进行排序是非常困难和昂贵的。)但是当然,您可以做一些类似于var array = dict.Keys.ToArray(); array.Sort();的事情。

@拉芬:"我是不是一直在管理一个单独的钥匙列表,一个拉斯蒂夫的答案?"--他的答案中没有"单独的钥匙列表"…只是dict.Keys…尽管通常通过,比如说,dict.OrderBy(kv => kv.Key)对keyValuePairs进行操作比较好。

尝试使用SortedDictionary

你的回答比上帝慢了21秒。还不错。

正确的答案已经说明(只使用sorteddictionary)。

但是,如果您偶然需要将集合保留为字典,则可以按顺序访问字典键,例如,通过对列表中的键进行排序,然后使用此列表访问字典。一个例子…

Dictionary dupcheck = new Dictionary();

…一些填充"dupcheck"的代码,然后…

if (dupcheck.Count > 0) {

Console.WriteLine("

dupcheck (count: {0})

----", dupcheck.Count);

var keys_sorted = dupcheck.Keys.ToList();

keys_sorted.Sort();

foreach (var k in keys_sorted) {

Console.WriteLine("{0} = {1}", k, dupcheck[k]);

}

}

别忘了这件事。

"如果您偶然需要将集合保留为字典"--保留它的明显原因是它的插入、删除和查找速度更快。至于var keys_sorted = dupcheck.Keys.ToList(); keys_sorted.Sort();——更简单的是keys_sorted = dupcheck.Keys.OrderBy(k => k).ToList();…如果要使用这些值,那么只需foreach (var ent in dupcheck.OrderBy(kv => kv.Key)) Console.WriteLine($"{ent.Key} = {ent.Value}");

按设计,字典是不可排序的。如果您在字典中需要此功能,请查看SortedDictionary。

看看SortedDictionary,甚至还有一个构造函数重载,这样您就可以传入自己的IComparable进行比较。

当字典实现为哈希表时,SortedDictionary实现为红黑树。

如果不利用算法中的顺序,只需要在输出前对数据进行排序,那么使用sortedDictionary将对性能产生负面影响。

您可以这样"排序"字典:

Dictionary dictionary = new Dictionary();

// algorithm

return new SortedDictionary(dictionary);

如果要按键对条目进行排序,只需使用dictionary.OrderBy(kv => kv.Key)。

由于这个答案的高搜索位置,我认为Linq Orderby解决方案值得展示:

class Person

{

public Person(string firstname, string lastname)

{

FirstName = firstname;

LastName = lastname;

}

public string FirstName { get; set; }

public string LastName { get; set; }

}

static void Main(string[] args)

{

Dictionary People = new Dictionary();

People.Add(new Person("John","Doe"), 1);

People.Add(new Person("Mary","Poe"), 2);

People.Add(new Person("Richard","Roe"), 3);

People.Add(new Person("Anne","Roe"), 4);

People.Add(new Person("Mark","Moe"), 5);

People.Add(new Person("Larry","Loe"), 6);

People.Add(new Person("Jane","Doe"), 7);

foreach (KeyValuePair person in People.OrderBy(i => i.Key.LastName))

{

Debug.WriteLine(person.Key.LastName +"," + person.Key.FirstName +" - Id:" + person.Value.ToString());

}

}

输出:

Doe, John - Id: 1

Doe, Jane - Id: 7

Loe, Larry - Id: 6

Moe, Mark - Id: 5

Poe, Mary - Id: 2

Roe, Richard - Id: 3

Roe, Anne - Id: 4

在本例中,对名字也使用thenby是有意义的:

foreach (KeyValuePair person in People.OrderBy(i => i.Key.LastName).ThenBy(i => i.Key.FirstName))

则输出为:

Doe, Jane - Id: 7

Doe, John - Id: 1

Loe, Larry - Id: 6

Moe, Mark - Id: 5

Poe, Mary - Id: 2

Roe, Anne - Id: 4

Roe, Richard - Id: 3

对于需要它的人,Linq还具有orderByDescending和ByDescending。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值