前言:
本文主要讲解C++中的Vector容器和常用的STL库,适用于学完c语言同时有一定数据结构基础的刚接触C++的同学
由于楼主水平有限,写的注释可能比较多,如有问题欢迎在评论区指正 ヾ(•ω•`)o
Vector容器
Vector可以理解为可变数组
它既可以像数组一样下标访问,又可以像链表一样动态改变长度,具体操作代码如下
void learn_vector() {
vector<int> arr(100);
//既可以像数组一样下标访问,又可以像链表一样动态改变长度
vector<int> list;
list.push_back(1); //往vector list的最后一位塞数据
list.push_back(2);
list.push_back(3);
//两种输入方式
int n, tem;
cin >> n;
for (int i = 0; i < n; i++) {
scanf("%d", &list[i]);
}
for (int i = 0; i < n; i++) {
cin >> tem;
list.push_back(tem);
}
//一种输出方式
for (int i = 0; i < list.size(); i++) { //list.size()返回list的长度
cout << list[i] << " ";
}
//迭代器,类似于指针,以下为迭代器与指针方法相对比
vector<int> arr1(100);
int arr2[100] = {};
vector<int>::iterator p1;
for (p1 = arr1.begin(); p1 != arr1.end(); p1++) {
//注意这里的arr1.end()无需-1,就是vector的最后一位有效数据的下一个
cout << *p1 << endl;
}
/*----------------------------------------------------*/
int i; int* p2;
for (p2 = arr2, i = 0; i < 100; i++, p2++) {
cout << *p2 << endl;
}
//vector数组常见操作
list.size(); //返回vector长度,o(1)复杂度
list.clear(); //清空数组,挨个删除所有结点,o(n)复杂度
list.empty(); //判断数组是否为空
list.begin(); //返回数组首元素的迭代器
list.end(); //数组最后一个元素的下一个元素的迭代器(该元素实际在数组中不存在)
list.erase(p1); //删除数组在p1迭代器所在位置中的数字 vector<int>::iterator p1;
list.push_back(1); //向数组的最后添加一个值为x的元素
list.pop_back(); //删除数组中的最后一个元素
}
常用STL
STL(Standard Template Library,中文译名:标准模板库)。本文主要展示部分常用STL的用法
#include<cstdlib>
包括qsort、rand伪随机数、malloc动态内存分配等
void learn_cstdlib() {
int a[5] = { 2,3,5,1,4 };
qsort(a, a+5); //c语言中的快排。我的评价是:不如c++的sort()
rand(); //伪随机数,一般用time()配合srand()来生成真正的随机数
malloc(1); free(0); //c语言动态内存分配
}
#include<algorithm>
包括C++中的sort快速排序、min、max、reverse转置、swap交换、binary_search二分查找、unique查重去重等
void learn_algorithm() {
//vector和数组使用sort的方式
vector<int> arr1 { 2,3,1,5,4 };
sort(arr1.begin(), arr1.end());
for (int i = 0; i < arr1.size(); i++) {
cout << arr1[i] << " ";
}
int arr2[5] = {2, 3, 1, 5, 4};
sort(arr2, arr2 + 5);
for (int i = 0; i < 5; i++) {
cout << arr2[i] << " ";
}
//定义比较函数的sort方法,例题1:cmp1()的定义在下方
sort(arr2, arr2 + 5, cmp1);//以cmp1的方式进行排序
//定义比较函数的sort方法,例题2:cmp2()、point的定义在下方
point pt[10];
sort(pt, pt + 10, cmp2);//以cmp2的方式进行排序
//其他algorithm
min(1, 2); max(1, 2);
min_element(arr1.begin(), arr1.end()); //返回容器的最小值
max_element(arr2, arr2+5); //返回容器的最大值
nth_element(arr1.begin(), arr1.begin() + 2, arr1.end());
//把数组中第n小的元素放到指定位置,类似快排,而且拍好序的元素左小右大
swap(arr1[0], arr1[1]); //交换单个元素
reverse(arr1.begin(), arr1.end()); //转置数组
unique(arr1.begin(), arr1.end());
//假设数组为{1,2,2,3,3,3},则unique会优先挑选第一次出现的元素放在前端,把数组顺序更改为{1,2,3,2,3,3}
int newLength = unique(arr1.begin(), arr1.end()) - arr1.begin(); //新的数组长度即为newLength
bool isExist = binary_search(arr1.begin(), arr1.end(), 2); //二分查找(Binary_search)对应元素是否存在,时间复杂度为O(logN)
int firstLoc = lower_bound(arr1.begin(), arr1.end(), 2) - arr1.begin(); //把2插入数组的第一个位置
int lastLoc = upper_bound(arr1.begin(), arr1.end(), 2) - arr1.begin(); //把2插入数组的最后一个位置
int n = firstLoc - lastLoc + 1; //如果存在该数,则n是该数重复的数量
}
/*-------------------------------------------*/
int cmp1(int a, int b) {
return a > b;
}
struct point {
int x, y;
point() { ; }
point(int x1, int y1) {
x = x1; y = y1;
}
};
bool cmp2(point a, point b) {//优先比较x坐标,若x相等则比较y坐标
if (a.x != b.x) {
return a.y > b.y;
}
return a.x > b.x;
}
//拓展:把cmp2换成operator<,也就是定义了小于号<的用法可以比较两个point值
bool operator<(point a, point b) {//优先比较x坐标,若x相等则比较y坐标
if (a.x != b.x) {
return a.y > b.y;
}
return a.x > b.x;
}
#include<cstring>
包括字符串的读取、strlen、strcmp、strcpy、memset暴力清空(速度快于for循环归零)memcpy(楼主暂时还不太明白)
void learn_cstring() {
char str1[10]; char* str2;
cin.getline(str1, 100);
int len = strlen(str1); strcmp(str1, str2); strcpy(str1, str2);
memset(str1, 1, sizeof(str1)); //暴力清空,把str1中连续的一段数全部改为1
memset(str1, INF, sizeof(str1)); //直接把所有元素都清空
//memcpy(str1, *str2, 10); //暴力复制,用于内存复制(我也不太懂)
}
#include<ctime>
包括time生成随机种子、clock返回程序运行时间
void learn_ctime() {
time(0); //返回从1970年到现在的秒数,用于生成随机数种子
clock(); //程序启动到目前的毫秒数
/*
int a = clock(0);
a = clock(0) - a;
*/
}
其他STL
包括但不限于<stack> <queue> <priority_queue> <map> <set>等标准库函数
void learn_Other() {
/*
包括但不限于<stack> <queue> <priority_queue> <map> <set>
*/
stack<int> stk;
stk.push(1);
int topElement = stk.top();
stk.pop(); //pop()无返回值,也就是说不能int res = stk.pop(),必须int res = stk.top(); stk.pop();
bool isEmpty1 = stk.empty(); //判断栈是否为空
int len1 = stk.size(); //返回当前栈中存在的元素数量
queue<int> que;
que.push(1);
int frontElement = que.front(); //队列的首元素
int lastElement = que.back(); //队列的尾元素
que.pop(); //出队
bool isEmpty2 = que.empty(); //判断队列是否为空
int len2 = que.size(); //返回size
//优先队列priority_queue,默认小的在前,大的在后
priority_queue<int> que2;
que2.push(1);
int minElement = que2.top();
que2.pop();
bool isEmpty3 = que2.empty();
int len3 = que2.size();
//集合set,用来保存很多元素,同时在集合里各数不重复且有序
//可以在(logN)的时间内高速的访问某个元素
set<int> st;
st.insert(1); //在集合st中插入1
st.find(1);
st.erase(1);
//多重集合multiset,允许集合重复,通过库函数count()返回某个数的数量
multiset<int> mst;
mst.insert(2);
mst.find(2);
mst.count(2);
//映射map,包含了pair和map,具体使用方法以后展示
pair<string, int> pr1{ "seven", 7 };
//通过string和int的pair,把两个值关联起来,也就是字符串seven和数字7
pair<int, int> pr2{ 1, 2 };
//把int型数据1和2关联起来,如果比较pair大小,默认先比较第一个元素,再比较第二个元素
map<string, int> mp;
mp["six"] = 6;
mp["two"] = 2;
mp.insert(pr1); //在map中插入数对pr1
mp.erase("seven"); //在map中删除"seven",但mp.erase(6)会报错,好像是只能根据map的第一类元素擦除
map<string, int> mp2 = {
{"one", 1}, {"two", 2}, {"three", 3}, {"four", 4}, {"five", 5}, {"one", 11}, {"fifty", 5}
}; //暂时不清楚映射中一对多和多对多会出现什么结果,但目前Visual Studio不会报错,可能是覆盖重写的关系
}
有帮助的话记得点个赞再走吧 \( ̄︶ ̄*\))