使用C#为字典中的一个键添加多个位图值

时间:2012-04-01 10:33:15

标签: c# dictionary lookup

我有一个字典来存储用于OCR目的的图案图像。我从字典中抓取这些位图并将其与我从图像裁剪的位图进行比较,如果它们匹配=>抓住钥匙(OCR部分完成)。

问题出在这里。一个密钥应由几个不同的位图(即值)表示。 如何向字典添加多个位图,以表示相同的密钥?

这就是我使用字典的方式:

    Dictionary<string, Bitmap> lookup = new Dictionary<string, Bitmap>();
    lookup.Add("A", new Bitmap(@"C:\08\letters\1\a1.bmp", true));
    lookup.Add("A", new Bitmap(@"C:\08\letters\1\a2.bmp", true)); // Error will be here, because key A already exists for one Bitmap value.
    lookup.Add("a", new Bitmap(@"C:\08\letters\1\aa1.bmp", true));
    lookup.Add("B", new Bitmap(@"C:\08\letters\1\b1.bmp", true));

现在,为了抓住图片和价值我做了以下事情:

var target = lookup.ToList();
bitmap b1 = target[j].Value; //grab value
//if value = cropped bitmap => proceed
string key = target[j].Key; //grab key

根据您的解决方案,此流程将如何变化?

P.S。我听说过“System.Linq.Lookup(Of TKey,TElement)”,但从未使用过它。这个“查找”会帮助我解决我的问题,还是一个完全不同的工具?谷歌也不太了解它,所以欢迎一个例子

请注意,我在程序启动时只加载一次字典,所以加入的速度并不重要。 Lookup,另一方面让我最困扰。我的两个词典中有120个元素,根据这篇文章http://www.dotnetperls.com/dictionary-time - 列表中的查找比字典慢得多..

无论如何我会做一些措施来测试下面建议的List解决方案 - 与我现在拥有的Dictionary解决方案进行比较,然后告诉结果,可能是今天晚上。

3 个答案:

答案 0 :(得分:2)

Lookup。它基本上是一个Key列表,而不是键值。

lookup.Add("a", "123"); // creates 'a' key and adds '123' to it
lookup.Add("a", "456"); // adds '456' to existing 'a' key
lookup.Add("b", "000"); // creates 'b' key and adds '000' to it

答案 1 :(得分:0)

您无法使用相同的密钥将项目添加到dictionary。我认为你使用的是错误的数据结构。我可能需要使用list<>进行调查。像这样:

var lookup=new List<KeyValuePair<string,Bitmap>>();
lookup.Add(new KeyValuePair<string,Bitmap>("A", new Bitmap(@"C:\08\letters\1\a1.bmp", true)));
lookup.Add(new KeyValuePair<string,Bitmap>("A", new Bitmap(@"C:\08\letters\1\a2.bmp", true)));
lookup.Add(new KeyValuePair<string,Bitmap>("a", new Bitmap(@"C:\08\letters\1\aa1.bmp", true)));
lookup.Add(new KeyValuePair<string,Bitmap>("B", new Bitmap(@"C:\08\letters\1\b1.bmp", true)));

你可以这样做。没有ToList()

bitmap b1 = target[j].Value; //grab value
string key = target[j].Key; //grab key

修改

但如果你在ToList()上进行Dictionary,那么你就错过了首先拥有Dictionary的意义。因为那时你正以Dictionary的方式访问list。我还可以在ToList()上看到Dictionary上的问题,因为Dictionary中的排序不是您插入它们时的排序,而是通过哈希。这意味着您无法确定索引1是否为索引1.您还必须考虑到add上的操作Dictionary不如add上的操作有效List。使用Dictionary的神物是查找速度快。但是你没有使用当前的解决方案。

所以我能看到两种方式。上面的那个或确保密钥是唯一的,并通过Dictionary中的查找来获取。像这样:

Dictionary<string, Bitmap> lookup = new Dictionary<string, Bitmap>();
lookup.Add("A", new Bitmap(@"C:\08\letters\1\a1.bmp", true));
lookup.Add("B", new Bitmap(@"C:\08\letters\1\a2.bmp", true));
lookup.Add("C", new Bitmap(@"C:\08\letters\1\aa1.bmp", true));
lookup.Add("D", new Bitmap(@"C:\08\letters\1\b1.bmp", true));

然后你就可以得到这样的Bitmap

Bitmap bm;
if(lookup.TryGetValue("A",out bm))
{
    //Do something
}

或者,如果您知道Dictionary中存在该密钥,那么您可以这样做:

Bitmap bm;
bm= lookup["A"];

答案 2 :(得分:0)

首先,将'多个bmp-s'与'表示键' - 或将“一个键”关联(映射)为多个'值'是不同的 - 这就是Yorye所建议的正确。
因此,如果您希望将更多值附加到单个键 - 那么您可以使用类似Dictionary<TKey, IList<TValue>>的内容 - 其中TKey和TValue是您需要的类型。
但这并不能解决索引和查询数据的问题 这假设你的'钥匙'在你的情况下只是'A' - 这不清楚它是什么 因此,在这种情况下,您使用“词典”来表示不应该使用它。字典是一种散列结构(基本上将其所有条目索引到存储桶等中),其目的是加速查询过程,定位“正确”值。
正如我在你的情况下看到的那样,“密钥”是“一组位图”,它们呈现出OCR图像的“签名”,如果我是对的?我是没有多少进入OCR,但我猜这里 这使事情变得复杂,你需要创建一种“复合”键
'key'而不是'value'(或值列表)将是位图(假设它们可以是可比较的,相等或不相等的,也存在如何将多个值与多个值进行比较等问题。 )。
如果通常是这种情况(但是对于比你更简单的情况),你将创建一个自定义类并使该类具有GetHashCode()Equals覆盖(或IEqualityComparer)等,以便它可以用作字典中的键。然后你用它作为钥匙。
再次,在你的情况下,我认为这有点拉伸(从某种意义上说,它不容易实现)。
基本上你需要考虑“查询”数据,而不是存储。什么是您系统的真正“钥匙”。如果它是一个位图,那总是一样的(或者如果不是你如何与签名bmps进行比较)那么你可以保存一些bmp哈希码,并将其用作一个键 - 然后比较它,而不是bmps。
即你需要考虑这样的事情 - 然后解决方案通常很明显,你需要使用什么 我不推荐列表,因为这是一个穷人的选择 - 除非你可能只有一对,所以很容易手工完成它,不知何故我不认为你的情况就是这样。
如果你需要通过一些键或键来“索引”某种方式 - 那么它通常是字典(或字典以某种方式或部分参与) - 但你可以有许多“字典” - 或组合。您还可以拥有“多种类型的键”和值等 你需要给我们一些数据。
希望这有助于 编辑最后 - 获得正确的'哈希代码'也不是一件简单的事情 - 就像你的自定义结构一样,这是你需要自己解决的事情 - 所以归结为什么是你的关键 - 什么代表'关键'(如在哪个属性中,值最能描述它并使其独特,难以对图像/ bmp做什么?),哈希值的分布等。