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

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

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

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

Dictionary lookup = new Dictionary(); 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 

这个过程将如何根据您的解决方案而变化?

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

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

无论如何,我将采取一些措施来测试下面建议的List解决方案 – 与我现在拥有的Dictionary解决方案进行比较并稍后告诉结果,可能是今晚。

查找 。 它基本上是值列表的键的字典,而不是键值。

 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 

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

 var lookup=new List>(); lookup.Add(new KeyValuePair("A", new Bitmap(@"C:\08\letters\1\a1.bmp", true))); lookup.Add(new KeyValuePair("A", new Bitmap(@"C:\08\letters\1\a2.bmp", true))); lookup.Add(new KeyValuePair("a", new Bitmap(@"C:\08\letters\1\aa1.bmp", true))); lookup.Add(new KeyValuePair("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 

编辑

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

所以我可以通过两种方式看到。 上面的那个或确保键是唯一的并通过Dictionary的查找获得它。 像这样:

 Dictionary lookup = new Dictionary(); 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"]; 

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