📜  通过map c++(1)

📅  最后修改于: 2023-12-03 14:58:02.925000             🧑  作者: Mango

通过 map C++ 学习关联数组

在 C++ 中,可以使用 map 来实现关联数组,也就是将一组键值对组合在一起形成的数据结构。本文将介绍如何通过 map 实现关联数组,并提供代码示例,让你更好地学习与掌握这个常用的数据结构。

什么是 map?

在 C++ 中,map 是一种容器,存储了一组有序的键值对,也就是所谓的关联数组。每个元素都有一个键和一个值,通过键来访问对应的值。map 中的元素是按照键值的大小自动排序的,因此可以快速地查找、插入和删除元素。

map 的基本使用方法

使用 map 首先需要包含头文件 #include <map>。接下来,我们可以定义一个 map 对象,并使用 insert() 函数添加键值对。例如,下面是添加两个键值对的示例代码:

#include <iostream>
#include <map>

int main() {
    std::map<std::string, int> myMap;
    myMap.insert(std::pair<std::string, int>("one", 1));
    myMap.insert(std::make_pair("two", 2));

    // 输出所有键值对
    for (auto const& pair: myMap) {
        std::cout << pair.first << " : " << pair.second << std::endl;
    }

    return 0;
}

在上面的代码中,我们使用 std::map 定义了一个名为 myMap 的对象。这里指定了键的类型为 std::string,值的类型为 int。接下来,我们通过 insert() 函数向 myMap 对象中添加了两个键值对。第一个键值对是使用 std::pair<std::string, int> 类型的对象创建的,其中键为字符串 "one",值为 1。第二个键值对是使用 std::make_pair() 函数创建的,在这个函数中,我们只需要提供键和值即可。在最后的循环中,我们使用 range-based for 循环输出了 myMap 中的所有键值对。

除了 insert() 函数之外,map 还提供了很多其他的函数,可以用于查找、修改、删除元素等操作。下面是一些常用的函数:

  • find(key):查找键为 key 的元素,如果找到了,返回一个指向该元素的迭代器,否则返回 end()。例如,auto it = myMap.find("one"); 将返回一个指向第一个键值对的迭代器。
  • operator[]:通过键来访问对应的值。例如,std::cout << myMap["one"] << std::endl; 将输出键为 "one" 的值。
  • erase(key):删除键为 key 的元素。例如,myMap.erase("two"); 将删除键为 "two" 的元素。
  • clear():删除所有元素。
  • size():返回元素个数。
  • empty():判断是否为空。
map 的高级用法
自定义比较函数

在默认情况下,map 的元素是按照键值的大小自动排序的。如果你需要按照自己的规则排序,就需要自定义比较函数。比较函数是一个接收两个参数的函数,返回一个 bool 值,表示第一个参数是否应该排在第二个参数之前。例如,下面是按照字符串长度排序的比较函数:

struct CompareString {
    bool operator()(const std::string& s1, const std::string& s2) const {
        return s1.length() < s2.length();
    }
};

int main() {
    std::map<std::string, int, CompareString> myMap;
    myMap["one"] = 1;
    myMap["three"] = 3;
    myMap["two"] = 2;

    // 输出所有键值对
    for (auto const& pair: myMap) {
        std::cout << pair.first << " : " << pair.second << std::endl;
    }

    return 0;
}

在上面的代码中,我们定义了一个名为 CompareString 的比较函数对象,并将其作为 myMap 的第三个模板参数传入。在比较函数中,我们使用字符串的长度来比较两个字符串的大小,因此 "one" 排在 "two" 之前,而 "two" 又排在 "three" 之前。运行上面的代码,输出的结果为:

one : 1
two : 2
three : 3
使用多个键作为索引

在 map 中,每个元素只有一个键。但如果我们需要使用多个键来索引元素,就需要使用一些技巧。一种常用的方法就是使用结构体作为键。例如,下面是使用结构体作为键的示例代码:

#include <iostream>
#include <map>

struct Person {
    std::string name;
    int age;
    bool operator<(const Person& other) const {
        if (name < other.name) return true;
        if (name == other.name && age < other.age) return true;
        return false;
    }
};

int main() {
    std::map<Person, int> myMap;
    myMap[{ "Alice", 20 }] = 1;
    myMap[{ "Bob", 30 }] = 2;
    myMap[{ "Alice", 25 }] = 3;

    // 输出所有键值对
    for (auto const& pair: myMap) {
        std::cout << pair.first.name << ", " << pair.first.age << " : " << pair.second << std::endl;
    }

    return 0;
}

在上面的代码中,我们定义了一个名为 Person 的结构体,并重载了 < 运算符来比较两个 Person 对象的大小。接下来,我们使用 Person 对象作为键,通过花括号的形式来创建一个 Person 对象,并将其作为 myMap 的下标来访问。在最后的循环中,我们输出了所有键值对的信息。运行上面的代码,输出的结果为:

Alice, 20 : 1
Alice, 25 : 3
Bob, 30 : 2
使用 unordered_map

map 的底层实现是基于红黑树,因此在查找和插入元素时具有较好的时间复杂度,但在空间占用方面比较浪费。如果对空间要求较高,可以使用 unordered_map,它的底层实现是基于哈希表,具有更好的空间利用率。使用 unordered_map 的方法与 map 类似,只需要将头文件 #include <unordered_map>,并将数据类型改为 std::unordered_map 即可。

总结

map 是 C++ 中非常常用的数据结构之一,它通过键值对来存储和访问元素,具有快速的查找、插入和删除等操作。本文介绍了 map 的基本使用方法和高级用法,并提供了代码示例。在实际编程中,要灵活应用 map 的各种功能,从而更好地完成自己的任务。