【问题标题】:Retrieving the key of a value from a hash table c#从哈希表 c# 中检索值的键
【发布时间】:2011-09-21 14:22:42
【问题描述】:

我有一个包含 a^j 值的哈希表。 j 是键,a^j 是值。 我现在正在计算另一个值 a^m。我基本上想看看 a^m 是否在哈希表中。 我使用了 ContainsValue fn。找到价值。我将如何找出价值的关键?

这是我想在哪里实现值搜索的小sn-p。

    Dictionary<BigInteger, BigInteger> b = new Dictionary<BigInteger, BigInteger>();
     ***add a bunch of BigIntegers into b***
    for(int j=0; j < n; j++)
    {
       z =  q* BigInteger.ModPow(temp,j,mod);
       ***I want to implement to search for z in b here****
    }

这有什么改变吗?我在 for 循环中搜索的事实?

【问题讨论】:

  • 你没用Dictionary
  • 我不知道如何使用字典,而且我已经知道如何使用哈希表来做我需要做的事情,至少在大多数情况下是这样。将我的 BigIntegers 哈希表转换为字典容易吗?
  • 如果你的键是指数,你为什么不检查键mis present
  • @NullUser 我已经创建了一个包含所有值 (j,a^j) 的哈希表。然后我使用 for 循环来计算数字 z=r* BigInteger.ModPow(a,j,mod)。在 for 循环中,0

标签: c# hashtable


【解决方案1】:

最快的方法可能是遍历哈希表的DictionaryEntry 项以找到值,这反过来会为您提供密钥。我看不出还有什么办法。

【讨论】:

    【解决方案2】:

    首先,您绝对应该使用Dictionary&lt;TKey, TValue&gt; 而不是Hashtable - 如果您使用.NET 4 中的BigInteger,没有理由不使用泛型集合无处不在 .在大多数情况下,您可能会发现它的使用方式没有区别 - 只需使用以下方式创建它:

    Dictionary<BigInteger, BigInteger> map = 
        new Dictionary<BigInteger, BigInteger>();
    

    开始。需要注意的一件事是,如果键不存在于映射中,索引器将引发异常 - 使用 TryGetValue 获取值(如果存在)并使用 bool 来判断它是否存在 确实存在

    至于按值查找键 - 从Dictionary 无法有效地 做到这一点。您可以搜索所有条目,这是使用 LINQ 最容易完成的:

    var key = map.Where(pair => pair.Value == value)
                 .Select(pair => pair.Key)
                 .First();
    

    但这会遍历整个字典,直到找到匹配项,所以这是一个 O(n) 操作。

    如果您想有效地执行此操作,您应该保留两本字典 - 一本从 aa^j,一本从 a^ja。添加条目时,双向添加。在 Stack Overflow 上的某个地方,我有一些类的示例代码可以为您执行此操作,但我怀疑我是否能够轻松找到它。编辑:有一个可以处理多个映射here; “单一映射”版本在该版本下方的答案中。

    无论如何,一旦你有两个字典,每个方向一个,这很容易 - 显然你只需在第二个字典中查找 a^m 作为键来找到创建它的原始值。

    请注意,您需要考虑两个原始键是否有可能以相同的值结束 - 那时您显然无法同时拥有 both 映射字典(除非它是 Dictionary&lt;BigInteger, List&lt;BigInteger&gt;&gt; 或类似的东西)。

    【讨论】:

    • 嗯,值 a^m 正是我为这个问题输入的值。在程序中它是 q = j* BigInteger.ModPow(a(inverse),j,mod) 并且 for 循环从 0
    • 我想你之前的答案在这里:stackoverflow.com/questions/255341/…
    • @Nook:这真的无关紧要——基本上你有键,它们映射到值。如果您想以一种高效的方式走另一条路,则需要构建另一个映射。如果你不关心这个查找是 O(n),你可以直接迭代。
    【解决方案3】:

    编辑: 改为使用Dictionary&lt;TKey, TValue&gt;

    Dictionary&lt;TKey, TValue&gt; 是一个IEnumerable&lt;KeyValuePair&lt;TKey, TValue&gt;&gt;。如果您直接对其执行foreach,您可以获得每个条目的键和值。

    class SomeType
    {
        public int SomeData = 5;
    
        public override string ToString()
        {
            return SomeData.ToString();
        }
    }
    
    // ...
    
    var blah = new Dictionary<string, SomeType>();
    blah.Add("test", new SomeType() { SomeData = 6 });
    
    foreach (KeyValuePair<string, SomeType> item in blah)
    {
        if(e.Value.SomeData == 6)
        {
            Console.WriteLine("Key: {0}, Value: {1}", item.Key, item.Value);
        }
    }
    

    如果您有较新版本的 .Net 框架,您可以使用 Linq 查找您的匹配项,并将它们放在自己的集合中。这是一个代码示例,展示了一点 Linq 语法:

    using System;
    using System.Collections;
    using System.Linq;
    
    class SomeType
    {
        public int SomeData = 5;
    
        public override string ToString()
        {
            return SomeData.ToString();
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            var blah = new Dictionary<string, SomeType>();
            blah.Add("test", new SomeType() { SomeData = 6 });
    
            // Build an enumeration of just matches:
    
            var entriesThatMatchValue = blah
                .Where(e => e.Value.SomeData == 6);
    
            foreach (KeyValuePair<string, SomeType> item in entriesThatMatchValue)
            {
                Console.WriteLine("Key: {0}, Value: {1}", item.Key, item.Value);
            }
    
            // or: ...
    
            // Build a sub-enumeration of just keys from matches:
    
            var keysThatMatchValue = entriesThatMatchValue.Select(e => e.Key);
    
            // Build a list of keys from matches in-line, using method chaining:
    
            List<string> matchingKeys = blah
                .Where(e => e.Value.SomeData == 6)
                .Select(e => e.Key)
                .ToList();
        }
    }
    

    【讨论】:

    • 我按照...几乎每个人的建议从哈希表更改为字典。那么现在我会改变我在字典 b 中搜索值 v 的方式吗?并找到 v 的键?
    • @Nook:您仍然可以在此答案中使用该解决方案,您只需摆脱演员表。 Dictionary&lt;TKey, TValue&gt;IEnumerable&lt;KeyValuePair&lt;TKey, TValue&gt;&gt;,而 Hashtable 是普通的 IEnumerable(返回 object 类型为 DictionaryEntry 的实例)。我将编辑答案以反映此更改...
    • 谢谢!但我也想知道对我来说最好的方法是什么,因为我已经从 o 运行 for 循环
    • @Nook:除了对原始表进行O(N) 操作之外,没有其他方法可以对其进行转换。关联数组/哈希表/字典并非旨在解决该问题......您可以同时构建两者,尽管这不会为您节省太多(由于必须处理两个表而可能根本没有重复重新分配在调整大小的同时)。
    • @Nook:这个问题可能很有趣 - stackoverflow.com/questions/268321/… - 尽管我发现的所有这些问题和答案只是在封面下使用了两个字典。
    【解决方案4】:
    private object GetKeyByValue(object searchValue)
    {
        foreach (DictionaryEntry entry in myHashTable)
        {
            if (entry.Value.Equals(searchValue))
            {
                return entry.Key;
            }
        }
    
        return null;
    }
    

    【讨论】:

      猜你喜欢
      • 2013-02-12
      • 2014-01-02
      • 2011-01-28
      • 1970-01-01
      • 2014-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多