【问题标题】:C# equivalent of C++ map<string,double>C# 等效于 C++ map<string,double>
【发布时间】:2010-12-08 13:22:45
【问题描述】:

我想为不同的帐户保留一些总计。在 C++ 中,我会像这样使用 STL:

map<string,double> accounts;

// Add some amounts to some accounts.
accounts["Fred"] += 4.56;
accounts["George"] += 1.00;
accounts["Fred"] += 1.00;

cout << "Fred owes me $" << accounts['Fred'] << endl;

现在,我将如何在 C# 中做同样的事情?

【问题讨论】:

    标签: c# arrays hashmap


    【解决方案1】:

    最接近 C++ std::map&lt;&gt;(内部树)的等价物是 C# OrderedDictionary&lt;&gt;(内部树),而 C# OrderedDictionary&lt;&gt; 缺少 C++ std::map&lt;&gt; 中的一些非常重要的方法,即:std::map::findstd::map::lower_boundstd::map::upper_boundstd::map::equal_rangestd::mapiterators,基本上是前面4种方法的主干。

    为什么这 4 种方法很重要?因为它使我们能够定位给定键的“下落”,除了只能检查键是否存在,或者保证 SortedDictionary 是有序的。

    std::map 中键的“下落”是什么? key 不一定必须存在于集合中,我们想知道 key 可能在的位置,通常在两个迭代器之间,分别指向集合中两个相邻的现有 key,因此我们可以对 range 进行操作 关键在于O(logN) 复杂性。如果没有这 4 种方法(使用迭代器),每次针对键查询范围时,都必须对集合进行 O(N) 迭代。

    【讨论】:

      【解决方案2】:

      当我们谈论 STL、地图和字典时,我建议您查看 C5 库。它提供了几种我经常发现有用的字典和地图(以及许多其他有趣和有用的数据结构)。

      如果您是像我一样迁移到 C# 的 C++ 程序员,您会发现这个库是一个很好的资源(以及这个字典的数据结构)。

      -保罗

      【讨论】:

        【解决方案3】:

        这个代码就是你所需要的:

           static void Main(string[] args) {
                String xml = @"
                    <transactions>
                        <transaction name=""Fred"" amount=""5,20"" />
                        <transaction name=""John"" amount=""10,00"" />
                        <transaction name=""Fred"" amount=""3,00"" />
                    </transactions>";
        
                XDocument xmlDocument = XDocument.Parse(xml);
        
                var query = from x in xmlDocument.Descendants("transaction")
                            group x by x.Attribute("name").Value into g
                            select new { Name = g.Key, Amount = g.Sum(t => Decimal.Parse(t.Attribute("amount").Value)) };
        
                foreach (var item in query) {
                    Console.WriteLine("Name: {0}; Amount: {1:C};", item.Name, item.Amount);
                }
            }
        

        内容是:

        姓名:弗雷德;金额:8,20 雷亚尔;
        姓名:约翰;金额:10,00 雷亚尔;

        这就是在 C# 中执行此操作的方式 - 以声明的方式!

        希望对你有帮助,

        里卡多·拉塞尔达·布兰科堡

        【讨论】:

        • 好吧,我现在已经用 Dictionary 完成了,但是 XML 非常简单,只是一个标签列表,如下所示:跨度>
        【解决方案4】:

        虽然 System.Collections.Generic.Dictionary 匹配标签“hashmap”并且在您的示例中运行良好,但它并不完全等同于 C++ 的 std::map - std::map 是一个有序集合。

        如果订购很重要,您应该使用SortedDictionary

        【讨论】:

          【解决方案5】:

          字典是最常见的,但您可以使用其他类型的集合,例如 System.Collections.Generic.SynchronizedKeyedCollection、System.Collections.Hashtable 或任何 KeyValuePair 集合

          【讨论】:

            【解决方案6】:

            大概:-

            var accounts = new Dictionary<string, double>();
            
            // Initialise to zero...
            
            accounts["Fred"] = 0;
            accounts["George"] = 0;
            accounts["Fred"] = 0;
            
            // Add cash.
            accounts["Fred"] += 4.56;
            accounts["George"] += 1.00;
            accounts["Fred"] += 1.00;
            
            Console.WriteLine("Fred owes me ${0}", accounts["Fred"]);
            

            【讨论】:

            • 也许我应该通过说“我不知道这些名字,或者我将拥有多少个名字”来澄清该评论。在这个答案中,如果我添加了 accounts["Ron"] += 2.50;,它会抛出异常。实际上,我会向它扔一个包含大量名称和数字的 XML 文件。
            • 其实没有,如果你使用索引并试图设置一个不存在的键,它实际上会用指定的键为你创建对象。只有在 get 操作上才会抛出异常。看这里的评论:msdn.microsoft.com/en-us/library/9tee9ht2.aspx
            • @Alex: 因为 var 比 IParallelEnumerable> 短得多 :)
            • c# 中的字典不等同于 stl::map 只是你知道的 - c# 字典是哈希表,而 stl::map 是红黑树,底层算法完全不同。
            • 请注意,此示例中的 accounts["Fred"] = 0; 等同于 accounts.Add("Fred", 0);(两种变体请参见 dotnetfiddle.net/q3UteL)另外:*当您使用 Dictionary.Add( Key, Value ) 添加新的 KeyValuePair 时如果字典中已经存在Key,则将抛出 ArgumentException。 *使用索引器 (Dictionary[ Key ]) 你会得到一个隐含的 add-or-update 行为,因为如果 Key 不包含在 Dictionary 中,它将自动添加,否则相应的值将简单被更新。 *考虑使用小数作为货币
            【解决方案7】:

            你想要Dictionary 类。

            【讨论】:

              【解决方案8】:
              Dictionary<string, double> accounts;
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2014-08-15
                • 2010-11-25
                • 1970-01-01
                • 1970-01-01
                • 2018-01-25
                • 2020-07-18
                • 1970-01-01
                • 2019-10-06
                相关资源
                最近更新 更多