SortedDictionary<Color, int> bucket = new SortedDictionary<Color, int>(new MyComparer());
for (int col = 0; col < image.Width; col++)
{
for (int row = 0; row < image.Height; row++)
{
Color c = image.GetPixel(col, row);
if (bucket.ContainsKey(c))
bucket[c]++;
else
{
if (c == Color.FromArgb(255, 0, 15, 12))
MessageBox.Show("First time " + c + " " + bucket.ContainsKey(c));
bucket.Add(c, 1);
}
}
}
但MessageBox显示两次(对于普通的数字图片)。然后我想做一些像
这样的事情SortedDictionary<Color, int> newBucket = new SortedDictionary<Color, int>(bucket, new ColorComparer(channel));
以异常结束,它告诉我“已经添加了具有相同键的项目”。但我检查了它,在上面的代码中,它返回False
。我错过了什么吗?
顺便说一句。 MyComparer
class MyComparer : IComparer<Color>
{
public int Compare(Color x, Color y)
{
if (x == y)
return 0;
else if (x.R > y.R)
return 1;
else
return -1;
}
}
答案 0 :(得分:0)
我认为词典会混淆,因为如果颜色不相等且x.R == y.R
则Compare(x, y)
会返回-1
。如果在插入过程的后期,字典会以相反的顺序再次比较相同的值Compare(y, x)
再次返回-1
,但为了与之前的结果一致,它应返回+1
。所以字典就变坏了。
换句话说:如果a > b
,那么b < a
也必须为真。或者使用比较器:Compare(a, b) == -Compare(b, a)
必须为真!
使比较器保持一致的唯一方法是比较所有颜色通道(即使您只对订单的红色感兴趣。例如:
class MyComparer : IComparer<Color>
{
public int Compare(Color x, Color y)
{
if (x.R > y.R) return +1;
if (x.R < y.R) return -1;
return x.ToArgb().CompareTo(y.ToArgb());
}
}
另一种可能性是仅将红色组件存储在SortedDictionary<byte, int>
。