C++ 知识卡片1——
std::unordered_map
简介
std::unordered_map
是 C++11 中引入的一种关联容器,它存储的是键值对,其中每个键都是唯一的,并且每个键都映射到一个值。与std::map
不同的是,std::unordered_map
内部使用哈希表实现,因此它可以提供平均情况下对于元素的插入、访问和删除操作的常数时间复杂度(O(1)),但最坏情况下会退化到线性时间(O(n))。头文件
- 需要包含头文件
<unordered_map>
常用方法
- insert(): 插入键值对,如果键已经存在,则插入不会发生。
- emplace(): 尝试就地构造元素,这通常比
insert
更高效。- erase(): 通过键来删除元素。
- clear() :移除容器中的所有元素,但保留内存分配和哈希表的结构。这允许快速清空容器而不影响其容量或性能特性。
- find(key): 通过键查找元素,如果找到,则返回一个指向该元素的迭代器;如果未找到,则返回
end()
迭代器。- count(key) :返回某个键存在于容器中的次数。由于
unordered_map
中每个键都是唯一的,此方法只能返回 0(键不存在)或 1(键存在)。- `operator[]: 访问给定键对应的值。如果该键不存在,会插入一个新元素并返回其值的引用。
- at(): 访问给定键对应的值,如果键不存在,则抛出
std::out_of_range
异常。- empty(): 检查容器是否为空。
- size(): 返回容器中元素的数量。
- begin() 和 end(): 分别返回一个迭代器,这些迭代器支持前向遍历,但由于
unordered_map
是一个无序容器,遍历的顺序并不代表元素插入的顺序或任何特定排序。- 可以使用 for(auto xxx : xxx_unordered_map) 遍历 unordered_map,并且可以使用
xxx.first
和xxx.second
访问每个元素的 key 和 value。
相关示代码示例
#include <iostream> #include <string> #include <unordered_map> int main() { // 创建一个 unordered_map,键为 std::string 类型,值为 int 类型 std::unordered_map<std::string, int> myMap; // 插入键值对 myMap["apple"] = 1; myMap.insert({"banana", 2}); myMap.emplace("cherry", 3); // 访问元素 std::cout << "apple has value " << myMap["apple"] << std::endl; // 检查元素是否存在 if (myMap.find("banana") != myMap.end()) { std::cout << "Found banana in the map." << std::endl; } // 更新元素的值 myMap["apple"] = 10; // 遍历 unordered_map for (const auto& pair : myMap) { std::cout << pair.first << " has value " << pair.second << std::endl; } // 删除元素 myMap.erase("banana"); return 0; }
C++ 知识卡片2——
unordered_set
简介
unordered_set
是一个基于哈希表的容器,用于存储唯一元素的集合。头文件
- 需要包含头文件
<unordered_set>
常用方法
- insert(element) :向
unordered_set
中插入元素。如果元素已经存在,则操作不会改变容器。- emplace(args...) :直接在
unordered_set
中构造元素,避免了临时对象的创建和复制。其参数是用于构造元素的参数。- erase(key) :删除与指定键相匹配的元素。
- clear() :移除
unordered_set
中的所有元素,但不改变其容量。- find(key) :查找一个给定键的元素。如果找到,返回一个指向该元素的迭代器;如果未找到,返回
end()
。- count(key) :返回容器中等于给定键的元素数量。对于
unordered_set
,这个值只能是 0 或 1。- empty() :检查
unordered_set
是否为空。- size() :返回
unordered_set
中的元素数量。- max_size() :返回
unordered_set
可以容纳的最大元素数量,这通常是一个非常大的数值。- begin() , end() :提供遍历
unordered_set
的能力。begin()
返回指向第一个元素的迭代器,而end()
返回指向容器末尾的迭代器。
#include <iostream>
#include <unordered_set>
int main()
{
std::unordered_set<int> mySet = {1, 2, 3, 4, 5};
// 插入新元素
mySet.insert(6);
// 检查元素是否存在
if (mySet.find(3) != mySet.end()) {
std::cout << "3 is found" << std::endl;
}
// 删除元素
mySet.erase(4);
// 遍历并打印元素
for (auto& elem : mySet) {
std::cout << elem << " ";
}
std::cout << std::endl;
return 0;
}
C++ 知识卡片3——
std::sort
简介
std::sort
是标准模板库(STL)中的一个非常强大且灵活的排序函数,默认升序排序。- template void sort (RandomAccessIterator first, RandomAccessIterator last);
- 对[first, last) 范围内的数据进行排序
- 默认升序排列
- template <class RandomAccessIterator, class Compare> void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
- 对[first, last) 范围内的数据进行排序
- 按照自定义的比较函数 comp 进行排序 (见代码示例 1)
可排序的内容
- 基本数据类型数组或容器(如
int
、float
、char
、std::vector
、std::deque
、std::string
等)。- 字符串(
std::string
),将按每一个字符的 ASCII 或 Unicode 值排序。- 自定义对象的数组或容器,需要提供自定义的比较函数(见代码示例 1)或重载
<
操作符(代码示例 2)。头文件
- 需要包含头文件
#include <algorithm>
代码示例 1
#include <algorithm> #include <vector> #include <iostream> #include <string> class Person { public: std::string name; int age; Person(std::string n, int a) : name(n), age(a) {} }; // 自定义比较函数 bool comparePersons(const Person& a, const Person& b) { return a.age < b.age; } int main() { std::vector<Person> people = { {"Alice", 30}, {"Bob", 25}, {"Carol", 20} }; std::sort(people.begin(), people.end(), comparePersons); for (const Person& p : people) { std::cout << p.name << " is " << p.age << " years old.\n"; } return 0; }
代码示例 2
#include <algorithm> #include <vector> #include <iostream> #include <string> class Person { public: std::string name; int age; Person(std::string n, int a) : name(n), age(a) {} // 重载 '<' 操作符,根据年龄排序 bool operator<(const Person& other) const { return age < other.age; } }; int main() { std::vector<Person> people = { {"Alice", 30}, {"Bob", 25}, {"Carol", 20} }; std::sort(people.begin(), people.end()); for (const Person& p : people) { std::cout << p.name << " is " << p.age << " years old.\n"; } return 0; }
C++ 知识卡片4 ——
std::vector
简介
std::vector
是 C++ 标准模板库(STL)的一部分,它是一个序列容器,可以存储可变大小的数组。vector
提供了动态数组的功能,这意味着它可以在运行时动态地改变大小,自动管理存储空间。与普通数组相比,vector
提供了更高的灵活性和更广泛的功能集,如自动管理内存、提供对元素的直接访问等。头文件
要使用
std::vector
,需要包含头文件<vector>
。常用方法
- push_back(value) :在
vector
的末尾添加一个元素。- pop_back() :删除
vector
末尾的元素。- size() :返回
vector
中元素的数量。- empty() :检查
vector
是否为空。- clear() :删除
vector
中的所有元素。- insert(position, value) :在指定位置之前插入一个元素。
- erase(position) 或 erase(start, end) :删除指定位置的元素或删除一个范围内的元素。
- at(index) :访问指定位置的元素(带边界检查)。
- operator[] :访问指定位置的元素(无边界检查)。
- front() :访问第一个元素。
- back() :访问最后一个元素。
- begin() , end() :返回指向容器开始和结束的迭代器。
代码示例
#include <vector> #include <iostream> int main() { std::vector<int> vec; // 声明一个int类型的vector // 添加元素 vec.push_back(10); vec.push_back(20); // 访问元素 std::cout << "第一个元素: " << vec.front() << std::endl; std::cout << "最后一个元素: " << vec.back() << std::endl; // 使用迭代器遍历vector std::cout << "vector中的元素: "; for (auto it = vec.begin(); it != vec.end(); ++it) { std::cout << *it << " "; } std::cout << std::endl; // 删除最后一个元素 vec.pop_back(); // 检查大小和是否为空 std::cout << "vector大小: " << vec.size() << std::endl; std::cout << "vector是否为空: " << (vec.empty() ? "是" : "否") << std::endl; return 0; }
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string,vector<string>> strs_map;
for(string s :strs)
{
string key = s;
sort(key.begin(), key.end());
strs_map[key].push_back(s);
}
vector<vector<string>> result_arr;
for(auto kv: strs_map)
{
result_arr.push_back(kv.second);
}
return result_arr;
}
};