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;
    }
};