我需要一个数据结构,它可以通过与之关联的浮动键对对象进行排序,最低的是。问题是密钥代表成本所以经常有重复,我不关心这个,因为如果两个具有相同的成本,我只会抓住第一个,因为它没有区别,问题是编译器抱怨。 / p>
是否存在行为方式相同但允许重复键的数据结构?
编辑 - 我仍然需要重复项,因为如果结果是一个死胡同,我会抓住下一个(它们是a *搜索中的节点)
所以为了清楚起见,它需要允许按顺序排序的重复键。
答案 0 :(得分:10)
你写道:
相当于允许重复键的字典
我需要一种数据结构,可以通过与之关联的浮动键对对象进行排序,最先降低对象。
字典不会保留按键排序的项目,因此您要查找的结构实际上并不等同于Dictionary
。你想要的是类似于SortedList
或SortedDictionary
的东西,除了它应该允许重复的密钥。
.NET中不存在此类。但是你有几个选择:
SortedDictionary<double, List<TValue>>
,即使通常只需要第一个。首次插入密钥时,请创建新列表并将值添加到列表中。插入已存在的密钥时,请获取列表并将值附加到列表中。SortedDictionary<double, TValue>
并在插入前检查重复项。只存储每个键的第一个值,因此与上述方法不同,您无法使用此方法访问第二个值。相关强>
答案 1 :(得分:5)
我已多次遇到此问题,并且我总是使用Wintellect(http://powercollections.codeplex.com)的公共许可(即免费)Power Collections。他们有一个OrderedMultiDictionary,正是您正在寻找的。它允许重复键,它允许您遍历所有重复的键条目。
答案 2 :(得分:4)
您可以创建自己的类,该类派生自SortedSet
:
public class SortedTupleBag<TKey, TValue> : SortedSet<Tuple<TKey, TValue>>
where TKey : IComparable
{
private class TupleComparer : Comparer<Tuple<TKey, TValue>>
{
public override int Compare(Tuple<TKey, TValue> x, Tuple<TKey, TValue> y)
{
if (x == null || y == null) return 0;
// If the keys are the same we don't care about the order.
// Return 1 so that duplicates are not ignored.
return x.Item1.Equals(y.Item1)
? 1
: Comparer<TKey>.Default.Compare(x.Item1, y.Item1);
}
}
public SortedTupleBag() : base(new TupleComparer()) { }
public void Add(TKey key, TValue value)
{
Add(new Tuple<TKey, TValue>(key, value));
}
}
在控制台应用中使用:
private static void Main(string[] args)
{
var tuples = new SortedTupleBag<decimal, string>
{
{2.94M, "Item A"},
{9.23M, "Item B"},
{2.94M, "Item C"},
{1.83M, "Item D"}
};
foreach (var tuple in tuples)
{
Console.WriteLine("{0} {1}", tuple.Item1, tuple.Item2);
}
Console.ReadKey();
}
产生这个结果:
1.83 Item D
2.94 Item A
2.94 Item C
9.23 Item B
答案 3 :(得分:3)
您正在寻找Lookup。 与已经提出的其他基于字典的解决方案类似,它在每个键下存储IEnumerable以处理重复项。
var registry = Items.ToLookup(item=>item.Price);
foreach(var item in registry[desiredPrice])
{
//Here you handle items that all have Price == desiredPrice
}
答案 4 :(得分:1)
你仍然可以使用字典。您只需要将值的类型更改为集合而不是单个项目:
Dictionary<float, List<T>>
字典定义不允许重复键。
答案 5 :(得分:1)
你所说的是一个包。 bag 和 set 之间的区别在于,套装是唯一的,而行李允许重复。 {a,b,c}是一组; {a,b,c,a}是一个包。
抓取C5 Collections Library的副本。您需要课程HashBag<T>
或TreeBag<T>
。不同之处在于,底层数据存储在一个中是哈希,另一个是红黑树。在外部,它们的行为相同。要么给你你想要的东西。
答案 6 :(得分:1)
你可以通过重写CompareTo功能来实现。将一个aelement添加到SortedDictionary时,它使用CompareTo(),如果结果为0则表示异常,但是您可以更改键类实现的比较器行为,使其返回的值只大于或小于(1或-1)
public int CompareTo(int key)
{
if (this.key.CompareTo(key) < 1)
return 1;
else
return -1;
}
答案 7 :(得分:0)
您要找的是heap
或priority queue
。我敢肯定,如果你谷歌你将找到一个C#
答案 8 :(得分:-1)
您应该能够将SortedDictionary与IComparer的自定义实现一起使用以避免冲突。例如:
private class NonCollidingFloatComparer : IComparer<float>
{
public int Compare(float left, float right)
{
return (right > left) ? -1 : 1; // no zeroes
}
}
// silly method for the sake of demonstration
public void sortNodes(List<Node> nodesToSort)
{
SortedDictionary<float, Node> nodesByWeight = new SortedDictionary<float, Node>(new NonCollidingFloatComparer());
foreach (Node n in nodesToSort)
{
nodesByWeight.Add(n.FloatKey, n);
}
foreach (Node n in nodesByWeight.Values)
{
Console.WriteLine(n.FloatKey + " : " + n.UniqueID);
}
}