c++ - 在 map 中存储结构;检查 map 中是否存在结构

标签 c++ search dictionary constructor struct

Q#1) 下面的结构不想被复制并给出编译错误 - 为什么以及如何处理它?<​​/p>

#include <iostream>
#include <string>
#include <map>

using namespace std;

struct person
{
    person(string n)
        :name(n)
    {}

    string name;
};

int main()
{
    map<string, person> my_map;

    my_map["one"] = person("Tom");

    return 0;
}

Q#2) 我们可以通过省略结构构造函数“person(const string& n)”并一一分配结构值来避免上述问题:

#include <iostream>
#include <string>
#include <map>

using namespace std;

struct person
{
    string name;
};

int main()
{
    map<string, person> my_map;

    person p;
    p.name = "Tom";
    my_map["one"] = p;

    return 0;
}

所以,假设我是这样做的,在 map 中存储了很多人之后,我想检查某个特定的人是否存在于 map 中。据我所知,正确的做法是:

if(my_map.find("one") == my_map.end()) { //it doesn't exist in my_map }  
else {//it exists}

但据我了解,这将一张一张地遍历整个 map ,不是吗?如果是,那么可以这样做吗:

using namespace std;

struct person
{
    string name;
    string identifier; // <--
};

int main()
{
    map<string, person> my_map;

    person p;
    p.name = "Tom";
    p.identifier = "something"; // <--
    my_map["one"] = p;

    if(my_map["unknown"].identifier == "something") // <--
        cout << "Found" << endl;
    else 
        cout << "Not found" << endl;

    return 0;
}

通过这样做,我们避免了迭代,并且内存中的垃圾与我们的标识符匹配的可能性是……我猜很小,特别是如果我们使用一些散列。 那么这样做可以(安全)吗?

最佳答案

1) 由于以下表达式,第一个示例中的代码无法编译:

my_map["one"]

my_map["one"]构造一个 std::string来自 "one" , 并将其传递给 std::map::operator[] . map::operator[]确保将值映射到提供的键(如果键尚未与值关联,则通过将键与默认构造的值关联)并返回对该值的引用。

这不会编译,因为 person没有默认构造函数(“默认构造函数”是不带参数的构造函数)。

有几种方法可以解决这个问题。

一种方法是您采用的方法 - 删除构造函数。它之所以有效,是因为如果您不提供任何构造函数,则会隐式定义一个默认构造函数。

另一种方法是为 person 显式定义默认构造函数:

struct person
{
    person():name(){} //or person()=default; if your compiler supports this
    person(string n)
        :name(n)
    {}
    string name;
};

另一种方法是不使用 operator[]完全没有,而是使用 map::insert ,如下:

auto pair(my_map.insert(std::make_pair(std::string("one"),person("Tom"))));
if (!pair.second) {
    *pair.first = person("Tom");
}

2) 在 map 中查找元素的正确方法是(如您所说)使用:

if(my_map.find("one") == my_map.end()) {/*it doesn't exist in my_map*/}
else {/*it exists*/}

不会检查 map 中的每个元素 - 事实上它可能只检查 O(log(map.size()))元素。

您的担心完全没有根据,这是在 map 中查找元素的正确方法,但是您继续使用的方式表明您对 operator[] 的内容存在严重误解。

您问“如果 my_map["unknown"].identifier == "something" 在 map 中不存在,"unknown" 返回真值的概率是多少?”。

这个问题的答案是没有任何机会返回 true,因为如果键 std::string("unknown") 没有值存在于 map 中,则operator[]会联想std::string("unknown")默认构造 person ,等等 identifier将是一个空字符串。

关于c++ - 在 map 中存储结构;检查 map 中是否存在结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10309828/

相关文章:

python - 在简单的 dict 上使用 kwargs(或 args)有什么好处?

python - 如何使用字典中的键获取索引?

c++ - 如何在 UML 中对两个 C++ 类(在不同线程中)之间的消息接口(interface)进行建模?

c++ - 优化掉未使用的参数化字段

search - 在Elasticsearch中使用正则表达式进行搜索

Ruby:如何测试两个文本 block 之间的相似性?

C++:从基类实例构造子类?

java - CountDownLatch 等价物

regex - 如何在一行中找到第二个和第四个搜索项?

java - 如何在java中迭代和比较Hashtable<String, Map<String, Set<String>>>