【问题标题】:C# : Using hashtables to store two of the same value. Is it possible?C#:使用哈希表来存储两个相同的值。是否可以?
【发布时间】:2010-10-15 22:04:49
【问题描述】:

我是 C# 编程的新手,我编写了一个使用哈希表存储数据的程序(在我的例子中,用户名,以及他们是“准备好”还是“未准备好”。我有 2 个表总计。第一个表在值框中具有作为用户名和客户端 IP 地址的键。第二个表具有键的就绪/未就绪状态(由组合框给出),IP 地址作为价值。

第一个表不是问题,因为我不希望用户名再次出现。但是,在第二张表中,我需要多次出现就绪/未就绪状态。但是,这不起作用,因为它说哈希表中已经有一个名为“Ready”的键。有没有办法解决这个问题?

【问题讨论】:

    标签: c# key hashtable


    【解决方案1】:

    您可以将Dictionary<Status,HashSet<IP>> 用于第二个表。这还有一个额外的优势,即插入/删除 IP 速度很快,因为它是 HashSet 中的一个键。

    【讨论】:

    • 虽然为了区分双重状态值(准备好/未准备好),字典实际上似乎有点矫枉过正。
    • 既然他谈到了组合框而不是复选框,我不确定是否有两个以上的状态。如果只有两个状态,那么肯定会首选使用两个 HashSet(每个状态一个)。
    • 是的,只有两种状态。我基本上为每个用户设置了 3 个值(IP 地址、用户名、就绪/未就绪状态)。有什么方法可以显示哈希表的值字段而不是键?
    【解决方案2】:

    那么,第二个哈希表的原因是为了快速查找谁准备好了,对吗?

    在这种情况下,请考虑将其分成 2 个不同的集合:一个用于准备好的人,一个用于尚未准备好的人。

    很可能,一个简单的List<T> 在这里就可以了,因为您只需要查看其中的人,而不是找到特定的人(因为如果您想这样做,您可以查看另一个哈希表)。如果具有与哈希表类似的查找属性很重要,您可以改用HashSet<T>,但这取决于您的需要。

    【讨论】:

    • 另外,我认为“哈希表”是指概念,不一定是 HashTable 类 - 在大多数情况下,由于类型安全,Dictionary 是更好的选择。跨度>
    【解决方案3】:

    键必须是唯一的。如果您尝试通过键访问一个值,它如何知道您真正想要的是哪个?

    【讨论】:

      【解决方案4】:

      听起来 Hashtable 可能不是解决您的问题的理想数据结构。

      哈希表/字典中的键必须是唯一的,所以不,从技术上讲,您不能在哈希表中存储共享完全相同键的两个条目。

      此外,您可能应该使用Dictionary&lt;TKey, TValue) 而不是实际的 Hashtable 类型,因为它具有更好的性能特征。

      你可以通过创建一个字典来模拟你想要的东西,它的值是某种集合:

      // Map containing two sets of IP addresses: those that are ready, 
      // and those that are not ready.
      var readyMap = new Dictionary<bool, HashSet<string>>();
      readyMap[true] = new HashSet<string>();
      readyMap[false] = new HashSet<string>();
      
      // Add an IP address that is ready.
      readyMap[true].Add(ipAddress1);
      
      // Add an IP address that is not ready.
      readyMap[false].Add(ipAddress2);
      

      但是,这可能不是理想的解决方案。您要解决的实际问题是什么?

      【讨论】:

      • 基本上,我正在尝试创建的解决方案与游戏中的“Ready Up”系统非常相似,如果用户准备好开始游戏,它会通知主机。我应该发布服务器和客户端程序的代码吗?
      • 我认为您不需要为整个程序发布代码。我认为有很多方法可以解决这个问题。您可能会考虑的另一种方法是使用一组最初包含所有人的未就绪地址。当机器转换为“就绪”时,您只需将其从“未就绪”集中删除即可。当集合为空时,每个人都准备好了。 HashSet 又是一个不错的选择。
      • 好吧,我终于想通了。我有 3 张桌子。第一个是键:用户名值:IP。其次是键:IP 值:用户名。第三是键:用户名值:准备好/未准备好。然后我简单地引用 htReady.Value (哈希表)。我的整个代码在这里:pastebin.com/Z60GEjK8。您要查看的部分是 ChatServer、AddUser、RemoveUser 和 AcceptClient 类的开头。
      【解决方案5】:

      好的,我终于想通了。我有 3 张桌子。第一个是键:用户名值:IP。其次是键:IP 值:用户名。第三是键:用户名值:准备好/未准备好。然后我简单地引用 htReady.Value (哈希表)。我的整个代码在这里:http://pastebin.com/Z60GEjK8。您要查看的部分是 ChatServer 类、AddUser、RemoveUser 和 AcceptClient 的开头。

      我是新手,所以如果您能提出更好的方法,我会全力以赴。

      【讨论】:

        猜你喜欢
        • 2018-06-04
        • 2020-10-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-23
        • 1970-01-01
        相关资源
        最近更新 更多