【问题标题】:What is the best data structure for this in-memory lookup table?这个内存查找表的最佳数据结构是什么?
【发布时间】:2010-10-13 04:40:15
【问题描述】:

我需要将查找表作为实例成员存储在我的一个类中。该表将在构造对象时进行初始化。每个“行”将有 3 个“列”:

StringKey (e.g., "car")
EnumKey (e.g., LookupKeys.Car)
Value (e.g, "Ths is a car.")

我想选择能够通过 StringKey EnumKey 进行查找时产生最佳性能的数据结构。

对于同一个字典值有 2 个键有点尴尬。我以前从未遇到过这种情况,所以我想知道这种事情的标准是什么。

我可以创建一个 Key/Value/Value 结构而不是 Key/Key/Value,但我想知道这会产生什么类型的性能影响。

我认为这一切都错了吗?

【问题讨论】:

    标签: data-structures dictionary lookup


    【解决方案1】:

    嗯...“错误”是一种苛刻的表达方式。我认为因为最常见的字典是“值的单键”,并且为此付出了很多努力(映射),所以通常最好只使用其中的两个,共享内存的值,如果完全有可能。

    【讨论】:

      【解决方案2】:

      你有两个哈希图。

      • StringKey 到 value 一个。

      • 一个从 EnumKey 到 value。

      您不必复制所有的 Value 实例,这些对象可以在两个 hashmap 之间共享。

      如果项目很多,您可能希望使用两个树形图而不是两个哈希图。但基本原则(“分享价值观”)适用于这两种结构。一组具有两个映射的值。

      【讨论】:

      • OK - 所以在我的例子中,“值实例”只是字符串。我将制作 2 个字典(一个带有 StringKey,一个带有 EnumKey),其值包含相同的字符串引用变量。听起来对吗?
      • 没错。在 Python 中,这就是它的全部。在 Java 中,有一个 string.intern() 可以确保所有 intern() 的字符串都被简化为一个公共字符串池,从而消除了一些可能的冗余。
      • 我正在使用 C#...你知道当我将字符串添加到每个字典时 .NET 是否会复制它吗?
      • 为每个字典添加一个reference。字符串存在一次。对一个字符串的多次引用。
      • 知道了。字典有自己对字符串的references,但它们都指向同一个字符串对象。字符串 s = "乔"; dct1.Add("key", s); -- 即使正在传递的参数被称为 s,dct1.Add 也会获得它自己对“joe”的引用。谢谢!
      【解决方案3】:

      真的有必要用两种类型的键键入相同的结构吗?您可能不需要自己重建复杂的数据结构。您可以对查找表进行某种封装,以便在内存不是问题的情况下确实有两个查找表。您可以使用这种封装结构来模拟能够使用任一类型的键从“相同”结构中提取值。

      如果有某种方法可以在枚举值和字符串键之间进行映射,您可以只使用一种查找表就可以走这条路。

      【讨论】:

        【解决方案4】:

        LINQ 的 ILookup(TKey, TElement) 接口可能会有所帮助。假设您的字典类似于:

        Dictionary<carKey, carValue> cars;
        

        你可以使用:

        ILookUp<carValue, carKey> lookup = cars.ToLookup(x => x.Value, x => x.Key);
        

        (...实际上我认为我可能稍微误读了这个问题 - 但 ILookUp 可能仍然符合要求,但键/值集可能需要是键和枚举。)

        【讨论】:

          【解决方案5】:

          如果保证每个值都可以被两种类型的键访问,另一种想法是将一种类型的键转换为另一种类型的键。例如:

          public Value getValue(String key)
          {
              dictionary.get(key); // normal way
          }
          
          public Value getValue(Enum enumKey)
          {
              String realKey = toKey(enumKey);
              getValue(realKey); // use String key
          }
          

          你可以让你的 Enum 实现一个 toKey() 方法来返回它们的 String 键,或者可能有另一个字典来将 Enum 值映射到 String 对应项。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-02-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-05-08
            • 2021-12-12
            相关资源
            最近更新 更多