【问题标题】:Have in C++ analog ContainsKey (TKey) from C# - what is best practics?有来自 C# 的 C++ 模拟 ContainsKey (Key) - 最佳实践是什么?
【发布时间】:2018-01-11 03:54:25
【问题描述】:

在 C++ 中有模拟 IDictionary.ContainsKey (TKey) 或 List.Contains (T) 来自 C# 吗?

例如,我有一个元素数组,需要知道这个数组是否有一些值? 什么是最佳方式或最佳实践 - 每个元素都没有“foreach”! 例如,如果它来自 std 库,那就太好了。

UPD 1:在标准库中有很多容器,但我想找到一个最好的方法——更快、代码少、复杂度低等等......

如果继续this logic,则更好的设计是std::unordered_set

    #include <unordered_set>

    std::unordered_set<std::string> NamesOfValues = { 
    "one", 
    "two", 
    "Date",
    "Time" 
    };

  // and now check is value exists in set
  if(NamesOfValues.count(value))
    {
        // value exists
    }

【问题讨论】:

标签: c++ c++11 stl containers


【解决方案1】:

使用count 似乎最简洁,这应该适用于任何容器。

if ( my_map.count(key) ) { // shorthand for `count(key) != 0`
    // It exists
} else {
    // It does not
}

如果我们谈论的是最接近原始字典类型的[unordered_]map 和[unordered_]set,那么这些容器会强制执行唯一键,因此返回的.count() 只能是0 或1,并且无需担心代码一旦找到匹配项就会毫无意义地迭代容器的其余部分(就像支持重复的容器一样)

无论哪种方式,简单地使用隐式转换为bool 会导致最简洁的代码。如果您最终的设计可能允许/需要每个键的不同计数,那么您可以与特定值进行比较。

【讨论】:

  • 如果 (my_map.count(key) > 0) 可能会更好?
  • 我不明白为什么。 map 和 set 都不能包含超过 1 个给定键的元素。所以结果要么是 0 要么是 1。为什么要把事情复杂化?但是,如果您更喜欢写 &gt; 0 的语义,那么当然,请随意。我想这可能会使代码以后更容易转移到另一种类型的容器中。
  • @Alexander 我更新它只是为了将返回的计数隐式转换为bool,看起来更加简洁。
  • 不简单吗?如果您不关心订单,请使用无序版本,这样您就不会为您不关心的强制订购付费。如果您只需要一个键,那么不要使用映射,它也有一个您不关心的值。更一般地,请咨询In which scenario do I use a particular STL container?
  • 不客气!享受 C++ 和标准库中的许多选项。 :D
【解决方案2】:

您正在寻找std::find。 Find 查找任意可迭代对象的任意类型输入,并返回该元素的迭代器。

例如,要在字典中查找元素,您可以执行以下操作:

std::unordered_map<char,int> my_map = { {'a', 1},{'b', 2}};

auto found_element = std::find(my_map.begin(), my_map.end(), 'a');
if( found_element == my_map.end() ){
   //nothing was found
}
else{
   // do something
}

对于标准地图,您还可以使用 map.find(T) 进行 O(1) 访问而不是 O(n)。

if( my_map.find('a') != my_map.end() ){
   //something was found!
}
else{
   //nothing was found
}

这比my_map.count() 更清楚...只有在您真正想弄清楚您拥有多少个元素并且您使用的是非唯一键时,您才会使用它。

【讨论】:

  • @Alexander 你所说的“大代码”是什么意思,我现在也举了一个例子。据我所知,没有其他标准方法可以做到这一点
  • @Alexander 您可以将这样的代码包装在一个布尔函数中,然后传递参数。这样你就可以有类似 .containsKey(...) return true or false
  • @Alexander 如果您使用无序地图,这没有多大意义......它也会占用相同数量的空间,我将编辑我的帖子以显示它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-27
  • 2013-01-13
  • 2013-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多