学会吊打面试官之map

学会吊打面试官之map_第1张图片

小白:大牛,我最近学习了一些C++的STL容器,但是我还是有一些疑惑,特别是对于map,我不太理解它的底层实现和具体用法。能否跟我讲一下?

大牛:当然可以啊,map是一种非常常用的关联式容器,它的底层实现是基于红黑树的,用于存储键-值对(key-value pair)。相比于其他容器,map的主要特点是键值对的唯一性和按照键排序,让我们来看一个具体例子:

#include 
#include 
#include 

int main() {
    std::map myMap;

    myMap.insert({"Alice", 23});
    myMap.insert({"Bob", 19});
    myMap.insert({"Charlie", 45});

    std::cout << "Charlie's age is " << myMap["Charlie"] << std::endl;

    for (auto& pair : myMap) {
        std::cout << pair.first << " is " << pair.second << " years old." << std::endl;
    }

    return 0;
}

这个例子中,我们创建了一个map,键是字符串类型,值是整型。然后我们插入了三个键值对,分别是“Alice”对应23,“Bob”对应19和“Charlie”对应45。注意,我们是用insert函数来插入键值对的。

接着,我们输出了“Charlie”对应的值,也就是45。

最后,我们用for循环输出了每一个键值对,这里用到了auto& pair来遍历map。

小白:我明白了,那如果我们想要查找一个键值对是否存在,应该怎么做呢?

大牛:很简单,你可以使用count函数来查找键值对的数量,如果存在,那么数量就是1,否则是0。另外,你也可以使用find函数来查找一个键,如果存在,那么find函数返回一个指向该键值对的迭代器,否则返回map的end迭代器。

#include 
#include 
#include 

int main() {
    std::map myMap;

    myMap.insert({"Alice", 23});
    myMap.insert({"Bob", 19});
    myMap.insert({"Charlie", 45});

    if (myMap.count("Bob") > 0) {
        std::cout << "Bob exists in myMap." << std::endl;
    } else {
        std::cout << "Bob does not exist in myMap." << std::endl;
    }

    auto it = myMap.find("Alice");
    if (it != myMap.end()) {
        std::cout << "Alice's age is " << it->second << std::endl;
    } else {
        std::cout << "Alice does not exist in myMap." << std::endl;
    }

    return 0;
}

大牛:好的,我们现在来看一下如何使用map进行查找操作。首先,我们需要创建一个map对象,并向其中插入一些数据:

#include 
#include 

using namespace std;

int main() {
    // 创建一个map对象,key为string类型,value为int类型
    map myMap;

    // 向map中插入数据
    myMap["apple"] = 10;
    myMap["banana"] = 20;
    myMap["orange"] = 30;

    // 查找key为"apple"的元素
    map::iterator iter = myMap.find("apple");
    if(iter != myMap.end()) {
        cout << "找到了,值为:" << iter->second << endl;
    } else {
        cout << "没找到!" << endl;
    }

    // 查找key为"pear"的元素
    iter = myMap.find("pear");
    if(iter != myMap.end()) {
        cout << "找到了,值为:" << iter->second << endl;
    } else {
        cout << "没找到!" << endl;
    }

    return 0;
}

这里我们用map对象myMap存储了三组键值对,然后分别查找了键为"apple"和"pear"的元素。可以看到,第一次查找返回了正确的结果,而第二次查找则返回了"没找到"。

小白:原来如此,这样使用map确实很方便啊!那么,map的底层实现是什么呢?

大牛:map的底层实现通常是使用红黑树(Red-Black Tree)来实现的。红黑树是一种自平衡二叉查找树,它的结构非常灵活,可以自动保持树的平衡状态,从而保证了查找、插入、删除等操作的时间复杂度都是O(logN)级别的。

小白:原来这就是所谓的“平衡树”啊,好厉害啊!

小白: 那我现在可以尝试用map来实现这个功能吗?

大牛: 当然可以,map就是专门用来处理键值对的容器。在这个例子中,你可以用学生的名字作为键,用他们的成绩作为值。这样就可以很方便地查找每个学生的成绩了。

小白: 那具体怎么实现呢?

大牛: 首先你需要定义一个map对象,并指定它的键和值的类型。代码应该像这样:

#include 
#include 

std::map student_scores;

这个代码定义了一个名为student_scores的map对象,它的键的类型是std::string,值的类型是int。

接下来,你可以用insert()函数向map中添加数据:

student_scores.insert(std::make_pair("Tom", 90));
student_scores.insert(std::make_pair("Jerry", 80));

这个代码将"Tom"和"Jerry"两个学生的成绩分别插入到了map对象中。

现在,你可以用find()函数来查找某个学生的成绩了:

std::map::iterator it = student_scores.find("Tom");
if (it != student_scores.end()) {
    std::cout << "Tom's score is " << it->second << std::endl;
} else {
    std::cout << "Tom is not found" << std::endl;
}

这个代码查找了名为"Tom"的学生的成绩,并将结果输出到控制台上。如果没找到,它就会输出一条错误信息。

小白: 好像很方便啊,map就是处理键值对最好的容器了。

大牛: 是的,map是一个非常强大的容器,它可以帮助你高效地存储和查找键值对数据。在实际开发中,我们会经常使用到它。

大牛:接下来我们看一下如何遍历map,即访问map中的所有元素。你可以使用迭代器进行遍历,例如:

for (auto it = myMap.begin(); it != myMap.end(); ++it) {
    std::cout << it->first << " => " << it->second << '\n';
}

小白:这里使用了auto关键字,我想请问它是什么?

大牛:auto是C++11引入的关键字,它能够根据初始化的表达式来推断变量的类型。在上述代码中,auto会被推断为std::map::iterator类型。

小白:哦,我懂了。那我可以使用range-based for loop来遍历map吗?

大牛:当然可以,range-based for loop非常适合遍历容器,让代码更加简洁易读。你可以这样使用:

for (const auto& pair : myMap) {
    std::cout << pair.first << " => " << pair.second << '\n';
}

小白:这段代码真的很简洁!那如果我想要查找map中是否存在某个key,应该怎么做呢?

大牛:可以使用map的find函数来查找。find函数接受一个key值,返回一个指向该key-value对的迭代器。如果map中不存在该key,则返回end()迭代器。下面是一个例子:

auto it = myMap.find(2);
if (it != myMap.end()) {
    std::cout << "The value of key 2 is " << it->second << '\n';
} else {
    std::cout << "Key 2 not found\n";
}

小白:嗯,我懂了。谢谢你的讲解!

大牛:不用谢,任何问题都可以问我。

你可能感兴趣的:(小白大牛漫话c++,c++,开发语言,学习,数据结构)