STL学习
总结
第一梯队:vector string
vector:主要就是用push_back这个方法,将元素添加到向量末尾,也会用到size,erase,begin,end这四个方法,大多数时间会用a[i]这种形式访问。看着和普通数组没太多区别,但是节省了分配内存那些困扰。
string:这个就超级常用,常用方法:size,length,empty这些都是和长度相关的。substr这个方法可以是很好用了,有时候处理字符串copy过来过去很麻烦,这个方法解决了很多问题。find,rfind方法查找子字符串。replace替换字符串,append在末尾添加字符串,insert在指定位置添加字符串。erase,clear和字符串清除有关系,不是很常用。c_str转换成C风格的字符串,这个又很常见了。
------------------------------------------------------------------------
第二梯队:stack,queue,proirity_queue,set,map
stack:push,pop,top,empty,size都是很常见的方法,学数据结构的时候都知道这些
queue:front,back返回队首队尾的元素的引用。push队尾添加一个元素,pop移处队尾元素。empty,size就不解释了
set:元组,就是不会重复元素。insert,erase,find,size,empty都是常见的用法
map:键值对,也是很常见的数据结构具体要这样定义
std::map<std::string, int> employees;
employees["Alice"] = 30;
------------------------------------------------------------------------
第三梯队:priority_queue,sort
priority_queue:优先队列,高级的数据结构,定义方法如下
struct compare {
bool operator()(int a, int b) {
return a > b; // 定义最小堆
}
};
// 创建一个自定义类型的优先队列,使用最小堆
std::priority_queue<int, std::vector<int>, compare> pq_min;
sort:排序,最常用的方法如下
bool compare(int a, int b) {
return a > b; // 降序
}
std::vector<int> vec = {5, 3, 8, 6, 2};
// 降序排序
std::sort(vec.begin(), vec.end(), compare);
第四梯队:
pair
#include <utility>
std::pair<Type1, Type2> myPair;
pair 中有两个公有成员变量:first:存储第一个值。second:存储第二个值。
iostream
#include <iostream>
int main() {
int age;
std::string name;
// 使用 std::cout 输出到屏幕
std::cout << "Enter your name: ";
// 使用 std::cin 从键盘读取输入
std::cin >> name;
std::cout << "Enter your age: ";
std::cin >> age;
// 输出读取到的数据
std::cout << "Hello, " << name << "! You are " << age << " years old." << std::endl;
return 0;
}
fstream
#include <fstream>
#include <iostream>
int main() {
std::fstream file;
file.open("example.txt", std::ios::out); // 以输出模式打开文件
if (!file) {
std::cerr << "Unable to open file!" << std::endl;
return 1; // 文件打开失败
}
//可以看到这里就是直接重定向到file而不是cout
file << "Hello, World!" << std::endl; // 写入文本
file.close(); // 关闭文件
return 0;
}
vector
#include <iostream>
#include <vector>
int main() {
// 创建一个空的整数向量
std::vector<int> myVector;
// 添加元素到向量中
myVector.push_back(3);
myVector.push_back(7);
myVector.push_back(11);
myVector.push_back(5);
// 访问向量中的元素并输出
std::cout << "Elements in the vector: ";
for (int element : myVector) {
std::cout << element << " ";
}
std::cout << std::endl;
// 访问向量中的第一个元素并输出
std::cout << "First element: " << myVector[0] << std::endl;
// 访问向量中的第二个元素并输出
std::cout << "Second element: " << myVector.at(1) << std::endl;
// 获取向量的大小并输出
std::cout << "Size of the vector: " << myVector.size() << std::endl;
// 删除向量中的第三个元素
myVector.erase(myVector.begin() + 2);
// 输出删除元素后的向量
std::cout << "Elements in the vector after erasing: ";
for (int element : myVector) {
std::cout << element << " ";
}
std::cout << std::endl;
// 清空向量并输出
myVector.clear();
std::cout << "Size of the vector after clearing: " << myVector.size() << std::endl;
return 0;
}
list
// 以下是 <list> 容器的一些基本操作:
// 包含头文件:#include <list>
// 声明列表:std::list<T> mylist;,其中 T 是存储在列表中的元素类型。
// 插入元素:mylist.push_back(value);
// 删除元素:mylist.pop_back(); 或 mylist.erase(iterator);
// 访问元素:mylist.front(); 和 mylist.back();
// 遍历列表:使用迭代器 for (auto it = mylist.begin(); it != mylist.end(); ++it)
#include <iostream>
#include <list>
int main() {
// 创建一个整数类型的列表
std::list<int> numbers;
// 向列表中添加元素
numbers.push_back(10);
numbers.push_back(20);
numbers.push_back(30);
// 访问并打印列表的第一个元素
std::cout << "First element: " << numbers.front() << std::endl;
// 访问并打印列表的最后一个元素
std::cout << "Last element: " << numbers.back() << std::endl;
// 遍历列表并打印所有元素
std::cout << "List elements: ";
for (std::list<int>::iterator it = numbers.begin(); it != numbers.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 删除列表中的最后一个元素
numbers.pop_back();
// 再次遍历列表并打印所有元素
std::cout << "List elements after removing the last element: ";
for (std::list<int>::iterator it = numbers.begin(); it != numbers.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
return 0;
}
stack
// push(): 在栈顶添加一个元素。
// pop(): 移除栈顶元素。
// top(): 返回栈顶元素的引用,但不移除它。
// empty(): 检查栈是否为空。
// size(): 返回栈中元素的数量。
#include <iostream>
#include <stack>
int main() {
std::stack<int> s;
// 向栈中添加元素
s.push(1);
s.push(2);
s.push(3);
// 访问栈顶元素
std::cout << "Top element is: " << s.top() << std::endl;
// 移除栈顶元素
s.pop();
std::cout << "After popping, top element is: " << s.top() << std::endl;
// 检查栈是否为空
if (!s.empty()) {
std::cout << "Stack is not empty." << std::endl;
}
// 打印栈的大小
std::cout << "Size of stack: " << s.size() << std::endl;
return 0;
}
queue
// 队列提供了以下常用操作:
// empty(): 检查队列是否为空。
// size(): 返回队列中的元素数量。
// front(): 返回队首元素的引用。
// back(): 返回队尾元素的引用。
// push(): 在队尾添加一个元素。
// pop(): 移除队首元素。
#include <iostream>
#include <queue>
int main() {
// 创建一个整数队列
std::queue<int> q;
// 向队列中添加元素
q.push(10);
q.push(20);
q.push(30);
// 打印队列中的元素数量
std::cout << "队列中的元素数量: " << q.size() << std::endl;
// 打印队首元素
std::cout << "队首元素: " << q.front() << std::endl;
// 打印队尾元素
std::cout << "队尾元素: " << q.back() << std::endl;
// 移除队首元素
q.pop();
std::cout << "移除队首元素后,队首元素: " << q.front() << std::endl;
// 再次打印队列中的元素数量
std::cout << "队列中的元素数量: " << q.size() << std::endl;
return 0;
}
priority_queue
在 C++ 中,priority_queue 默认是一个最大堆,这意味着队列的顶部元素总是具有最大的值。
// empty(): 检查队列是否为空。
// size(): 返回队列中的元素数量。
// top(): 返回队列顶部的元素(不删除它)。
// push(): 向队列添加一个元素。
// pop(): 移除队列顶部的元素。
#include <iostream>
#include <queue>
#include <vector>
struct compare {
bool operator()(int a, int b) {
return a > b; // 定义最小堆
}
};
int main() {
// 创建一个自定义类型的优先队列,使用最小堆
std::priority_queue<int, std::vector<int>, compare> pq_min;
// 向优先队列中添加元素
pq_min.push(30);
pq_min.push(10);
pq_min.push(50);
pq_min.push(20);
// 输出队列中的元素
std::cout << "最小堆中的元素:" << std::endl;
while (!pq_min.empty()) {
std::cout << pq_min.top() << std::endl;
pq_min.pop();
}
return 0;
}
set
C++ 标准库中的 set 是一个关联容器,它存储了一组唯一的元素,并按照一定的顺序进行排序。
set 提供了高效的元素查找、插入和删除操作。它是基于红黑树实现的,因此具有对数时间复杂度的查找、插入和删除性能。
set 容器中存储的元素类型必须满足以下条件:
元素类型必须可以比较大小。 元素类型必须可以被复制和赋值。
// insert(元素): 插入一个元素。
// erase(元素): 删除一个元素。
// find(元素): 查找一个元素。
// size(): 返回容器中元素的数量。
// empty(): 检查容器是否为空。
#include <iostream>
#include <set>
int main() {
// 声明一个整型 set 容器
std::set<int> mySet;
// 插入元素
mySet.insert(10);
mySet.insert(20);
mySet.insert(30);
mySet.insert(40);
// 输出 set 中的元素
std::cout << "Set contains: ";
for (int num : mySet) {
std::cout << num << " ";
}
std::cout << std::endl;
// 查找元素
if (mySet.find(20) != mySet.end()) {
std::cout << "20 is in the set." << std::endl;
} else {
std::cout << "20 is not in the set." << std::endl;
}
// 删除元素
mySet.erase(20);
// 再次输出 set 中的元素
std::cout << "After erasing 20, set contains: ";
for (int num : mySet) {
std::cout << num << " ";
}
std::cout << std::endl;
// 检查 set 是否为空
if (mySet.empty()) {
std::cout << "The set is empty." << std::endl;
} else {
std::cout << "The set is not empty." << std::endl;
}
// 输出 set 中元素的数量
std::cout << "The set contains " << mySet.size() << " elements." << std::endl;
return 0;
}
map
- 就是键值对,没啥特别的
#include <iostream>
#include <map>
#include <string>
int main() {
// 创建一个 map 容器,存储员工的姓名和年龄
std::map<std::string, int> employees;
// 插入员工信息
employees["Alice"] = 30;
employees["Bob"] = 25;
employees["Charlie"] = 35;
// 遍历 map 并打印员工信息
for (std::map<std::string, int>::iterator it = employees.begin(); it != employees.end(); ++it) {
std::cout << it->first << " is " << it->second << " years old." << std::endl;
}
return 0;
}
string
/*
size() 返回字符串的长度(字符数)。 std::cout << str.size();
length() 与 size() 相同,返回字符串的长度。 std::cout << str.length();
empty() 判断字符串是否为空。 std::cout << (str.empty() ? "Yes" : "No");
operator[] 访问字符串中指定位置的字符。 std::cout << str[0];
at() 访问字符串中指定位置的字符(带边界检查)。 std::cout << str.at(0);
substr() 返回从指定位置开始的子字符串。 std::string sub = str.substr(0, 5);
find() 查找子字符串在字符串中的位置。 std::cout << str.find("sub") << std::endl;
rfind() 从字符串末尾开始查找子字符串的位置。 std::cout << str.rfind("sub") << std::endl;
replace() 替换字符串中的部分内容。 str.replace(pos, length, "new_substring");
append() 在字符串末尾添加内容。 str.append("more");
insert() 在指定位置插入内容。 str.insert(pos, "inserted");
erase() 删除指定位置的字符或子字符串。 str.erase(pos, length);
clear() 清空字符串。 str.clear();
c_str() 返回 C 风格的字符串(以 null 结尾)。 const char* cstr = str.c_str();
data() 返回指向字符数据的指针(C++11 及之后的版本)。 const char* data = str.data();
compare() 比较两个字符串。 int result = str.compare("other");
find_first_of() 查找第一个匹配任意字符的位置。 size_t pos = str.find_first_of("aeiou");
find_last_of() 查找最后一个匹配任意字符的位置。 size_t pos = str.find_last_of("aeiou");
find_first_not_of() 查找第一个不匹配任意字符的位置。 size_t pos = str.find_first_not_of("aeiou");
find_last_not_of() 查找最后一个不匹配任意字符的位置。 size_t pos = str.find_last_not_of("aeiou");
*/
algorithm
/*
sort(container.begin(), container.end(), compare_function);
auto it = find(container.begin(), container.end(), value);
copy(source_begin, source_end, destination_begin);
bool result = equal(first1, last1, first2, compare_function);
*/
pair
const pair<int, string> valueSymbols[] = {
{1000, "M"},
{900, "CM"},
{500, "D"},
{400, "CD"},
{100, "C"},
{90, "XC"},
{50, "L"},
{40, "XL"},
{10, "X"},
{9, "IX"},
{5, "V"},
{4, "IV"},
{1, "I"},
};
class Solution {
public:
string intToRoman(int num) {
string roman;
for (const auto &[value, symbol] : valueSymbols) {
while (num >= value) {
num -= value;
roman += symbol;
}
if (num == 0) {
break;
}
}
return roman;
}
};