• c++中的string和vector


    知识点1【STL的概述】

    STL(Standard Template Library,标准模板库)
    STL的三大组件:容器(container)、算法(algorithm)、迭代器(iterator)。
    算法操作数据,容器存储数据,迭代器是算法操作容器的桥梁,迭代器和容器一一对应。
    在这里插入图片描述
    STL六大组件
    容器 算法 迭代器 仿函数 适配器 空间配置器
    容器:存放数据
    算法:操作数据
    迭代器:容器和算法的桥梁
    仿函数:为算法提供更多的策略
    适配器:为算法提供更多的参数接口
    空间配置器:管理容器和算法的空间
    算法的分类:
    质变算法:是指运算过程中会改变区间元素的内容。例如拷贝,替换,删除等。
    非质变算法:是指运算过程中不会区间的元素内容,例如查找、计数、遍历、寻找极值。
    迭代器的分类
    在这里插入图片描述

    知识点2【迭代器的案例】

    在这里插入图片描述
    案例:容器vector

    #include 
    #include 
    #include
    
    void myPrintInt(int num);
    using namespace std;
    
    void test01(){
    
        //单端动态数组vector类模板
        vector<int> arr(0);
        //push_back()尾部插入数据
        arr.push_back(100);
        arr.push_back(200);
        arr.push_back(300);
        arr.push_back(400);
    
        //访问数据
        //定义一个迭代器存储arr的起始迭代器
        vector<int>::iterator beginIt = arr.begin();
        //定义一个迭代器存储arr的结束迭代器
        vector<int>::iterator endIt = arr.end();
    
        //for循环遍历1
        for(vector<int>::iterator i = beginIt; i != endIt; i++){
            //对迭代器取* 代表的是 容器的元素
            //*biginIt
            cout << *i << " ";
        }
        cout << endl;
        //for循环遍历2(推荐)
        for(vector<int>::iterator beginIt = arr.begin(); beginIt != arr.end();beginIt++){
            cout << *beginIt << " ";
        }
        cout << endl;
    
        //STL提供的算法来遍历容器(包含算法头文件algorithm)
        //for_each从容器的起始--->结束,逐个元素取出
        //myPrintInt容器数据的打印方式
        for_each(arr.begin(),arr.end(),myPrintInt);
    
    }
    
    void myPrintInt(int num){
        cout << num << " ";
    }
    
    int main(int argc, char *argv[])
    {
        test01();
        return 0;
    }
    

    运行结果:
    在这里插入图片描述
    案例2:容器存放自定义数据类型

    #include 
    #include 
    #include
    #include 
    
    using namespace std;
    
    class Person{
        friend void myPrintInt1(Person &ob);
    private:
        string name;
        int age;
    public:
        Person(string name,int age){
            this->name = name;
            this->age = age;
        }
    };
    
    void myPrintInt1(Person &ob){
        cout << ob.age << " " << ob.name << endl;
    }
    
    void test02(){
        vector<Person> arr;
        Person p1("tom",15);
        arr.push_back(p1);
        arr.push_back(Person("davi",16));
        arr.push_back(Person("mary",17));
        arr.push_back(Person("peter",18));
        for_each(arr.begin(),arr.end(),myPrintInt1);
    }
    
    
    int main(int argc, char *argv[])
    {
        test02();
        return 0;
    }
    

    运行结果:
    在这里插入图片描述
    案例3:容器嵌套容器

    void test03(){
        vector<int> v1;
        vector<int> v2;
        vector<int> v3;
        v1.push_back(10);
        v1.push_back(20);
        v1.push_back(30);
        v1.push_back(40);
    
    
        v2.push_back(100);
        v2.push_back(200);
        v2.push_back(300);
        v2.push_back(400);
    
        v3.push_back(1000);
        v3.push_back(2000);
        v3.push_back(3000);
        v3.push_back(4000);
    
        vector< vector<int>> v4;
        v4.push_back(v1);
        v4.push_back(v2);
        v4.push_back(v3);
    
        for(vector<vector<int>>::iterator it = v4.begin(); it != v4.end(); it++){
            for(vector<int>::iterator mit = (*it).begin(); mit != (*it).end();mit++){
                cout << (*mit) << " ";
            }
            cout << endl;
        }
    
    }
    

    运行结果:
    在这里插入图片描述

    知识点2【string类】

    1、案例:string的构造和赋值

    #include 
    #include 
    
    using namespace std;
    /*
    3.1.2.1 string 构造函数
    string();//创建一个空的字符串 例如: string str;
    string(const string& str);//使用一个 string 对象初始化另一个 string 对象
    string(const char* s);//使用字符串 s 初始化
    string(int n, char c);//使用 n 个字符 c 初始化
    3.1.2.2 string 基本赋值操作
    string& operator=(const char* s);//char*类型字符串 赋值给当前的字符串
    string& operator=(const string &s);//把字符串 s 赋给当前的字符串
    string& operator=(char c);//字符赋值给当前的字符串
    string& assign(const char *s);//把字符串 s 赋给当前的字符串
    string& assign(const char *s, int n);//把字符串 s 的前 n 个字符赋给当前的字符串
    string& assign(const string &s);//把字符串 s 赋给当前字符串
    string& assign(int n, char c);//用 n 个字符 c 赋给当前字符串
    string& assign(const string &s, int start, int n);//将 s 从 start 开始 n 个 字符赋值给字符串
    */
    
    void test01(){
        //string(const char* s);//使用字符串s初始化
        string str1 = "hello";
        cout << str1 << endl;
    
        //string(int n, char c);//使用n个字符c初始化
        string str2(10,'H');
        cout<<str2<<endl;//"HHHHHHHHHH"
    
        string str3 = str2;
        cout << str3 << endl;//"HHHHHHHHHH"
    
        string str4;
        //string& operator=(const string &s);//把字符串s赋给当前的字符串
        str4 = str1;
        cout << str4 << endl;//hello
    
        //string& operator=(const char* s);//char*类型字符串 赋值给当前的字符串
        string str5;
        str5 = "hello str5";
        cout << str5 << endl; //hello str5
    
        //string& operator=(char c);//字符赋值给当前的字符串
        string str6;
        str6 = 'H';
        cout << str6 << endl;//"H"
    
        //string& assign(const char *s);//把字符串s赋给当前的字符串
        string str7 = "dsds";
        str7.assign("hello str7");
        cout<<str7<<endl;//"hello str7"
    
        //string& assign(const char *s, int n);//把字符串s的前n个字符赋给当前的字符串
        string str8;
        str8.assign("hello str8",5);
        cout << str8 << endl;
    
        //string& assign(const string &s);//把字符串s赋给当前字符串
        string str9;
        str9.assign(str8);
        cout << str8 << endl;//"hello"
    
        //string& assign(int n, char c);//用n个字符c赋给当前字符串
        string str10;
        str10.assign(10,'w');
        cout << str10 << endl;//"wwwwwwwwww"
    
        //string& assign(const string &s, int start, int n);//将s从start开始n个赋给当前字符串
    
        string str11;
        str11.assign("hehehahahaxixi", 4, 6);
        cout<<str11<<endl;//"hahaha"
    
    
    }
    
    int main(int argc, char *argv[])
    {
        test01();
        return 0;
    }
    
    

    2、string的字符的存取(注意)

    void test02(){
        string str1="hello string";
        cout<<str1[1]<<endl;//'e'
        cout<<str1.at(1)<<endl;//'e'
    
        str1[1]='E';
        cout<<str1<<endl;//"hEllo string"
        str1.at(7) = 'T';
        cout<<str1<<endl;//"hEllo sTring"
        //[]和at的区别
        try{
            //str1[1000]='G';//越界 []不抛出异常
            str1.at(1000)='G';//越界 at会抛出异常
        }catch(exception &e){
            cout<<"异常:"<<e.what()<<endl;
        }
    }
    

    运行结果:
    在这里插入图片描述

    3、字符串拼接2-1

    /*
     * 3.1.2.4 string拼接操作
     * string& operator+=(const string& str);//重载+=操作符
     * string& operator+=(const char* str);//重载+=操作符
     * string& operator+=(const char c);//重载+=操作符
     * string& append(const char *s);//把字符串s连接到当前字符串结尾
     * string& append(const char *s, int n);//把字符串s的前n个字符连接到当前字符串 结尾
     * string& append(const string &s);//同operator+=()
     * string& append(const string &s, int pos, int n);//把字符串s中从pos开始的n个 字符连接到当前字符串结尾
     * string& append(int n, char c);//在当前字符串结尾添加n个字符c
    */
    
    void test03(){
        string str1="hello";
        string str2=" string";
        //string& operator+=(const string& str);//重载+=操作符
        str1 += str2;
        cout<<str1<<endl;//"hello string"
    
        string str3="hello";
        //string& operator+=(const char* str);//重载+=操作符
        str3 += " string";
        cout<<str3<<endl;//"hello string"
    
        string str4="hello";
        //string& append(const char *s, int n);//把字符串s的前n个字符连接到当前字 符串结尾
        str4.append("hehehaha",4);
        cout<<str4<<endl;//"hellohehe"
        
        //string& append(const string &s, int pos, int n);//把字符串s中从pos开始 的n个字符连接到当前字符串结尾
        string str5="hello";
        string str6="hehehahaha";
        str5.append(str6,4,6);
        cout<<str6<<endl;//"hellohahaha"
    }
    int main(int argc, char *argv[])
    {
        test03();
        return 0;
    }
    

    运行结果:
    在这里插入图片描述

    4、字符串的查找替换

    /*
     * 3.1.2.5 string查找和替换
     * int find(const string& str, int pos = 0) const; //查找str第一次出现位置,从p os开始查找
     * int find(const char* s, int pos = 0) const; //查找s第一次出现位置,从pos开始 查找
     * int find(const char* s, int pos, int n) const; //从pos位置查找s的前n个字符 第一次位置
     * int find(const char c, int pos = 0) const; //查找字符c第一次出现位置
     * int rfind(const string& str, int pos = npos) const;//查找str最后一次位置,从 pos开始查找
     * int rfind(const char* s, int pos = npos) const;//查找s最后一次出现位置,从po s开始查找
     * int rfind(const char* s, int pos, int n) const;//从pos查找s的前n个字符最后 一次位置
     * int rfind(const char c, int pos = 0) const; //查找字符c最后一次出现位置
     * string& replace(int pos, int n, const string& str); //替换从pos开始n个字符 为字符串str
     * string& replace(int pos, int n, const char* s); //替换从pos开始的n个字符为 字符串s
     *
    */
    
    void test04(){
        //int find(const string& str, int pos = 0) const; //查找str第一次出现位 置,从pos开始查找
        string str1="hehe:haha:xixi:haha:heihei";
        //从str1中找haha
        string tmp="haha";
        cout<<str1.find(tmp)<<endl;//5
        cout<<str1.find(tmp,10)<<endl;//15
        //int find(const char* s, int pos = 0) const; //查找s第一次出现位置,从pos 开始查找
        cout<<str1.find("haha")<<endl;//5
        str1.replace(5,4,"###");
        cout<<str1<<endl;//"hehe:###:xixi:haha:heihei"
        string str2="www.sex.117114.sex.person.77.com";
        //需求:将字符串中的所有"sex"用***屏蔽
        int ret = 0;
        while((ret = str2.find("sex")) < str2.size()){
            str2.replace(ret,strlen("sex"),"***");
        }
    
        cout<<str2<<endl;
    
    }
    int main(int argc, char *argv[])
    {
        test04();
        return 0;
    }
    

    运行结果:
    在这里插入图片描述

    5、字符串比较

    /*
     * compare函数在>时返回 1,<时返回 ‐1,==时返回 0。
     * 比较区分大小写,比较时参考字典顺序,排越前面的越小。
     * 大写的A比小写的a小。
     * int compare(const string &s) const;//与字符串s比较
     * int compare(const char *s) const;//与字符串s比较
    */
    
    void test05(){
        string str1="hehe";
        string str2 = "haha";
        cout<<str1.compare(str2)<<endl;//1
        cout<<str1.compare("lala")<<endl;//‐1
        cout<<str1.compare("hehe")<<endl;//0
    }
    
    
    int main(int argc, char *argv[])
    {
        test05();
        return 0;
    }
    

    运行结果:
    在这里插入图片描述

    6、字符串提取

    /*
     * string substr(int pos = 0, int n = npos) const;//返回由pos开始的n个字符组成 的字符串
    */
    
    void test06(){
        string str1="hehehe:ha:xixixi:lalala:heihei";
        //cout<
    
        //案例:将分割的所有字符串提取出来
        int pos = 0;
        while(1){
            int ret = str1.find(":",pos);
            if(ret < 0){
                string tmp = str1.substr(pos,(str1.size() - pos));
                cout<<tmp<<endl;
                break;
            }
            string tmp = str1.substr(pos,ret-pos);
            cout<< tmp <<endl;
            pos = ret+1;
        }
    }
    
    int main(int argc, char *argv[])
    {
        test06();
        return 0;
    }
    

    运行结果:
    在这里插入图片描述

    7、字符串的插入删除

    /*
     * string& insert(int pos, const char* s); //插入字符串
     * string& insert(int pos, const string& str); //插入字符串
     * string& insert(int pos, int n, char c);//在指定位置插入n个字符c
     * string& erase(int pos, int n = npos);//删除从Pos开始的n个字符
     *
    */
    
    void test07(){
        string str1="hello world";
        str1.insert(5,"hehe");
        cout<<str1<<endl;//"hellohehe world
    
        str1.erase(5,4);//删除字符串中hehe
        cout<<str1<<endl;//"hello world"
    
        //清空字符串 str1.size()得到字符串的总大小
        str1.erase(0,str1.size());
        cout<<str1.size()<<endl;//0
    }
    
    int main(int argc, char *argv[])
    {
        test07();
        return 0;
    }
    

    运行结果:
    在这里插入图片描述

    8、string 和c风格的字符串转换

    void test08(){
    
        string str1;//对象
        char *str2 ="hello str";
    
        //将char * 转成 string (直接完成)
        str1 = str2;
        cout<<str1<<endl;//hello str
    
        string str3="hello str3";
        //不能直接将string 转换成 char * 必须借助string中的c_str方法完成
        //char *str4 = str3;//err
        char *str4 = const_cast<char *> (str3.c_str());
        cout<<str4<<endl;//"hello str3"
    
    }
    
    int main(int argc, char *argv[])
    {
        test08();
        return 0;
    }
    

    知识点3【vector】单端动态数组

    1、vector容器的概述

    在这里插入图片描述vector容器的迭代器 :随机访问迭代器
    随机访问迭代器:迭代器+n 可以通过编译 就是随机访问迭代器

    2、vector的容量capacity和大小sized

    capacity:空间能容纳元素的最大个数。
    size:空间中实际存放的元素个数

    #include 
    #include 
    
    using namespace std;
    
    void test01(){
        vector<int> v;
        int i = 0;
        for(i = 0; i < 100; i++){
            v.push_back(i);
        }
    
        cout << "v的容量capacity:" << v.capacity() << endl;
        cout << "v的大小size:" << v.size() << endl;
    }
    
    int main(int argc, char *argv[])
    {
        test01();
        return 0;
    }
    
    

    运行结果:
    在这里插入图片描述

    3、vector另寻地址的次数

    void test02(){
        vector<int> v;
        int *p = NULL;
        int count = 0;
        for(int i = 0; i < 1000; i++){
            v.push_back(i);
            if(p != &v[0]){
                count++;
                p =  &v[0];
            }
        }
        cout << "另寻地址的次数" << count << endl;
    }
    
    int main(int argc, char *argv[])
    {
        test02();
        return 0;
    }
    

    运行结果:
    在这里插入图片描述
    只要空间满,就会另寻空间

    4、vector的未雨绸缪机制(了解)

    void test03(){
        vector<int> v;
        int *p = NULL;
        int count = 0;
        for(int i = 0; i < 1000; i++){
            if(p != &v[0]){
                cout << "---------"<< count++ << "--------"<< endl;
                p =  &v[0];
            }
            v.push_back(i);
            cout<<"cacapity = "<<v.capacity()<<", size = "<<v.size()<<endl;
        }
    }
    
    int main(int argc, char *argv[])
    {
        test03();
        return 0;
    }
    

    在这里插入图片描述

    5、vector的构造函数

    /*
     * vector v; //采用模板实现类实现,默认构造函数
     * vector(v.begin(), v.end());//将v[begin(), end())区间中的元素拷贝给本身。
     * assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
     * assign(n, elem);//将n个elem拷贝赋值给本身。
     * vector& operator=(const vector &vec);//重载等号操作符
     *
    */
    void printVectorInt(vector<int> &v){
        for(vector<int>::iterator it=v.begin();it!=v.end();it++){
            cout<<*it<<" ";
        }
        cout << endl;
    }
    
    void test05(){
        //vector(n, elem);//构造函数将n个elem拷贝给本身
        vector<int> v1 = vector<int>(10,5);
        printVectorInt(v1);
    
        //vector(v.begin(), v.end());//将v[begin(), end())区间中的元素拷贝给本身
        vector<int> v2(v1.begin()+2,v1.end()-2);
        printVectorInt(v2);
    
        vector<int> v3(v1);
        printVectorInt(v3);
    
        //vector& operator=(const vector &vec);//重载等号操作符
        v2 = v1;
        printVectorInt(v2);
    
        //assign(n, elem);//将n个elem拷贝赋值给本身
        vector<int> v4;
        v4.assign(5,100);
        printVectorInt(v4);
    
        //assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身
        vector<int> v5;
        v4.assign(v4.begin(), v4.end());
        printVectorInt(v4);
    
        //swap(vec);// 将vec与本身的元素互换。
        vector<int> v6(5,20);
        vector<int> v7(10,40);
        printVectorInt(v6);
        printVectorInt(v7);
        v6.swap(v7);
        printVectorInt(v6);
        printVectorInt(v7);
    
    }
    int main(int argc, char *argv[])
    {
        test05();
        return 0;
    }
    

    运行结果:
    在这里插入图片描述

    6、vector大小操作

    /*
     * size();//返回容器中元素的个数
     * empty();//判断容器是否为空
     * resize(int num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。 如果容器变短,则末尾超出容器长度的元素被删除。
     * resize(int num, elem);//重新指定容器的长度为num,若容器变长,则以elem值填充新 位置。如果容器变短,则末尾超出容器长>度的元素被删除。
     * capacity();//容器的容量
     * reserve(int len);//容器预留len个元素长度,预留位置不初始化,元素不可访问
    */
    
    void test06(){
        vector<int> v;
        v.push_back(10);
        v.push_back(20);
        v.push_back(30);
        v.push_back(40);
    
        if(v.empty()){
            cout<<"v容器为空"<<endl;
        }else{
            cout<<"容器非空"<<endl;
            cout<<"size = "<<v.size()<<endl;
            cout<<"capacity = "<<v.capacity()<<endl;
            //容量 >= size
        }
    
        printVectorInt(v);//10 20 30 40
        //resize(int num);//重新指定容器的长度为num
        //多出的部分 自动补0
        v.resize(8);
        printVectorInt(v);//10 20 30 40 0 0 0 0
    
        //resize(int num, elem);//重新指定容器的长度为num,
        //若容器变长,则以elem值填充
        v.resize(10,5);
        printVectorInt(v);//10 20 30 40 0 0 0 0 5 5
    
        v.resize(2);
        printVectorInt(v);//10 20
     	//resize 作用的容器的大小 不会更改容器的容量
        cout<<"size = "<<v.size()<<endl;
        cout<<"capactiy = "<<v.capacity()<<endl;
    
    }
    
    int main(int argc, char *argv[])
    {
        test06();
        return 0;
    }
    

    运行结果:
    在这里插入图片描述使用resize swap收缩容器的容量:

    在这里插入图片描述

     void test04()
     { 
     	vector<int> v; 
     	for(int i=0;i<1000;i++)
     	{ 
     		v.push_back(i); 
     	} 
     	cout<<"size = "<<v.size()<<endl;//1000
     	cout<<"capactiy = "<<v.capacity()<<endl;//1024 
     	
     	//使用reszie将空间 置成10个元素(可以吗?)
     	v.resize(10);//不能修改容量 只能修改size
    	cout<<"size = "<<v.size()<<endl;//10
    	cout<<"capactiy = "<<v.capacity()<<endl;//1024 
     	
     	//使用swap收缩容器的容量 
     	vector<int>(v).swap(v);
     	
     	cout<<"size = "<<v.size()<<endl;//10 
     	cout<<"capactiy = "<<v.capacity()<<endl;//10 
     }
    

    运行结果:
    在这里插入图片描述

    7、reserve预留空间大小

    void test09(){
        //reserve(int len);//容器预留len个元素长度,预留位置不初始化,元素不可访问
        vector<int> v;
        //一次性 给够空间 叫空间预留
        v.reserve(1000);//预留空间 1000个元素
        int *p = NULL;
        int count = 0;
        for(int i = 0; i<1000; i++){
            v.push_back(i);
            if(p != &v[0]){
                count++;
                p = &v[0];
            }
        }
        cout << "重新另寻空间次数" << count <<endl;
    }
    
    int main(int argc, char *argv[])
    {
        test09();
        return 0;
    }
    

    运行结果:
    在这里插入图片描述
    如果没有:v.reserve(1000); 结果为11
    如果有:v.reserve(1000); 结果为1

    8、数据的存取

    void printVectorInt(vector<int> &v){
        for(vector<int>::iterator it=v.begin();it!=v.end();it++){
            cout<<*it<<" ";
        }
        cout << endl;
    }
    
    void test10(){
       vector<int> v;
       v.push_back(10);
       v.push_back(20);
       v.push_back(30);
       v.push_back(40);
    
       printVectorInt(v);
    
       cout<<v[2]<<endl;//30
       cout<<v.at(2)<<endl;//30
    
       //[] 越界 不抛出异常
       //at 越界 抛出异常
    
       cout<<"front = "<<v.front()<<endl;//10
       cout<<"back = "<<v.back()<<endl;//40
    }
    
    
    int main(int argc, char *argv[])
    {
        test10();
        return 0;
    }
    

    9、vector容器的插入与删除

    
    void printVectorInt(vector<int> &v){
        for(vector<int>::iterator it=v.begin();it!=v.end();it++){
            cout<<*it<<" ";
        }
        cout << endl;
    }
    
    void test11(){
        vector<int> v;
        v.push_back(10);
        v.push_back(20);
        v.push_back(30);
        v.push_back(40);
        printVectorInt(v);//10 20 30 40
    
        //insert(const_iterator pos, int count,ele);
        //迭代器指向位置pos插入count个元素ele.
        v.insert(v.begin()+2,3,100);
        printVectorInt(v);//10 20 100 100 100 30 40
    
    
        //尾部删除:pop_back();//删除最后一个元素
        v.pop_back();//将40删除了
        printVectorInt(v);//10 20 100 100 100 30
    
    
        //erase(const_iterator start, const_iterator end);
        //删除迭代器从start到end之间的元素
        v.erase(v.begin()+2,v.end()-1);
        printVectorInt(v);//10 20 30
    
        //erase(const_iterator pos);//删除迭代器指向的元素
        v.erase(v.begin()+1);//删除20的位置
        printVectorInt(v);//10 30
    
        cout<<"size = "<<v.size()<<", capacity = "<<v.capacity()<<endl;
    
        //clear();//删除容器中所有元素
        v.clear();
        printVectorInt(v);//啥也没有
        cout<<"size = "<<v.size()<<", capacity = "<<v.capacity()<<endl;
    
    }
    
    
    int main(int argc, char *argv[])
    {
        test11();
        return 0;
    }
    

    运行结果:
    在这里插入图片描述

  • 相关阅读:
    谈一谈AI对人工的取代
    leetcode题型分析《链表》
    vue2 - 基于Export2Excel.js导出Excel案例(js-xlsx插件二次封装使用)
    Mac和Windows使用n管理工具快速切换node版本【node10.13.0开发稳定版】
    Linux下python安装与pip常用命令
    这种考勤方式,居然能轻松实现!
    一本通1053;最大数输出
    Java算术运算符
    华为性格测试通关指南
    告诉你,赚钱狠的人,都有一个特点?
  • 原文地址:https://blog.csdn.net/DUANJIAWEIDUANJIAWEI/article/details/126954146