【问题标题】:adding multiple bitmap values for one key in dictionary with C#使用 C# 为字典中的一个键添加多个位图值
【发布时间】:2012-05-01 08:26:00
【问题描述】:

我有一本字典来存储用于 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

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

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

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

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

【问题讨论】:

    标签: c# dictionary lookup


    【解决方案1】:

    Lookup。它基本上是一个键到值列表的字典,而不是键到值。

    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
    

    【讨论】:

    • 如何声明查找?我试过“查找查找=新查找();”结果是“类型 'System.Linq.Lookup' 没有定义构造函数”
    • 它应该可以工作,至少在 .Net4 上是这样,但您也可以通过此处显示的方式间接创建它:msdn.microsoft.com/en-us/library/bb460184(v=vs.90).aspx
    【解决方案2】:

    您不能使用相同的密钥将项目添加到dictionary。我认为您使用了错误的数据结构。我觉得你可能不得不考虑使用list&lt;&gt;。像这样:

    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
    

    编辑

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

    所以我可以看到两种方式。上面的一个或确保密钥是唯一的,并通过在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"];
    

    【讨论】:

    • 好的,所以我有几个问题:与 Dictionary 相比,这个“列表方法”慢/快多少?根据这篇文章“dotnetperls.com/dictionary-time”,列表的速度是字典的两倍,只有 12 个!元素..我在一本字典中存储了 120 个元素,所以有些东西告诉我 List 不是最好的解决方案..
    • 更新了答案。看看
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2012-04-22
      • 2017-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-08
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      相关资源
      最近更新 更多