通过值</key,>高效地对<key,value =“”>进行排序

时间:2010-02-05 17:44:20

标签: c# .net performance sorting

我正在寻找通过值对一堆pairs<string, float>进行排序的最有效方法,因为我需要获得大量对的3个最高条目。

我的自然反应是使用sortedList,但显然它只按键排序,我不能使用反向列表解决方案,因为我知道字符串是唯一的,但浮点数可能不是。< / p>

我忽略了任何简单而有效的解决方案?

7 个答案:

答案 0 :(得分:13)

如果您只需要知道前三个值,则无需对整个列表进行排序 - 您只需执行一次传递,一次存储前三个值。这将使它成为O(n)而不是O(n log n)...但你必须自己实现它。

如果您对O(n log n)感到满意,最简单的方法可能是使用LINQ:

var ordered = pairs.OrderBy(pair => pair.Value).Take(3).ToList();

实现类似的东西可能不会太难:

public static IEnumerable<TSource> TakeTop<TSource, TKey>
    (this IEnumerable<TSource> source,
     Func<TSource, TKey> keySelector,
     int count)

可能具有O(n * count)的复杂度。如果我有更多的时间,我会为了好玩而做...

答案 1 :(得分:2)

您可以使用linq:

yourDictionary.OrderBy(kv => kv.Value).Take(3);

我不知道效率,但肯定是短暂而富有表现力的。

答案 2 :(得分:2)

创建您自己的配对对象并实施IComparable interface,并根据您的值进行比较。

答案 3 :(得分:0)

我不知道它是否效率最高,但您可以尝试:

List<KeyValuePair<string,float>> myList = new List<KeyValuePair<string,float>>():

... //adding whatever...

myList.Sort(delegate(KeyValuePair<string,float> pair1, KeyValuePair<string,float> pair2) { return pair1.Value.CompareTo(pair2.Value); });

答案 4 :(得分:0)

如果您想要均衡的red-black tree,可以在C5中找到一个:

using Bag = C5.TreeBag<C5.KeyValuePair<string, float>>;
using Comparer = C5.DelegateComparer<C5.KeyValuePair<string, float>>;

...

var bag = new Bag(new Comparer(
  (pair1, pair2) => 
    pair1.Value == pair2.Value ? 
    pair1.Key.CompareTo(pair2.Key) :
    // inverted because you need the highest entries 
    pair2.Value.CompareTo(pair1.Value))); 

...

var topN = bag.Take(N).ToList();

Retrieval(以及所有其他操作)具有O(log n)复杂度。

答案 5 :(得分:0)

跟进Jons扩展方法这里是一个实现

public static IEnumerable<TSource> TakeTop<TSource, TKey>
    (this IEnumerable<TSource> source,
     Func<TSource, TKey> keySelector,
     int count)
{
  var top = source.Take(count).OrderBy(keySelector).ToArray();
  var last = count-1;
  foreach(var item in source.skip(count))
  {
    if(keySelector(top[last]) < keySelector(item))
    {
      top[last] = item;
      //depending on count this might be faster as buble sort
      top = top.OrderBy(keySelector).ToArray();
    }
  }
  return top;
}

考虑到我在SO文本框中“实施”它的草案:)

答案 6 :(得分:0)

上述方法的另一种解决方案 - 将值插入到地图中时会添加新值,因为新的键/值对会被添加,并在构建地图时构建前三个(asumming您没有被传递给从当然外部的东西映射)