C++ Vector容器与常用STL

前言:

本文主要讲解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不会报错,可能是覆盖重写的关系

}

有帮助的话记得点个赞再走吧  \( ̄︶ ̄*\))

上一篇:力扣242 有效的字母异位词


下一篇:C++中的字符串