c++自学日记 day15

今日学习vector 和string容器

1、

vector容器
vector基本概念

功能:

  • vector数据结构和数组非常相似,也称为单端数组

vector与普通数组区别:

  • 不同之处在于数组是静态空间,而vector可以动态扩展

动态扩展:

  • 并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新空间,释放原空间
  • vector容器的迭代器是支持随机访问的迭代器

有关vector语法若分每一个小节来讲颇杂且短小,故放在一个大函数中,详见 

《黑马》——C++提高编程_c++ 提高黑马-CSDN博客

#include <iostream>
#include <string>
#include <vector>
#include <algorithm> //使用STL提供的算法
using namespace std;

void PrintVector(vector<int> v) {
    //for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
    //    cout << *it << " ";
    //}
    for (int i = 0; i < v.size(); i++) {
        //cout << v[i] << " ";通过数组下标访问
        cout << v.at(i) << " ";//通过at()函数访问
}
    cout << endl;


}

//void MyPrint(int val)
//{
//    cout << val << endl;
//}

//void test01() {
//    vector<int> v;
//    vector<int>::iterator itbegin = v.begin();//开始迭代器,itbegin是一个指针
//    vector<int>::iterator itend = v.end();//结束迭代器,vector<int>::iterator是迭代器类型
//
//    v.push_back(10);
//    v.push_back(20);

    //第一种遍历方式
    //while (itbegin != itend) { 
    //    cout << *itbegin << endl;
    //    itbegin++;//++访问后面的数据
    //}

    第二种遍历方式
    //for (vector<int>::iterator it = itbegin; it != itend; it++) {
    //    cout << *itbegin << endl;
    //} 前两种均使用的是普通循环,通过遍历itbegin指针来寻找值,第三种方式则是自带的for_each函数,使用也方便

    //第三种遍历方式
    //for_each(v.begin(), v.end(),print<int>);
//}

class Person {
public:
    string name;
    int age;
    Person(string name, int age) {
        this->name = name;
        this->age = age;
    }
};

//void test01() {
//    vector<Person> v;
//    vector<Person>::iterator vbegin = v.begin();
//    vector<Person>::iterator vend = v.end();
//
//    Person p1("a1", 10);
//    Person p2("b2", 20);
//    v.push_back(p1);
//    v.push_back(p2);
//
//    for(vector<Person>::iterator it = v.begin(); it != v.end(); it++) {
//        //cout << "name= " << it->name << " age= " << it->age << endl; //it是指向p1p2的指针,用->可取值
//        //还有一种方法是解引用然后使用.name来取值
//        cout << "name= " << (*it).name << " age= " << (*it).age << endl;
//    }
//}
//
//void test02() {
//    vector<Person*> v;
//    vector<Person*>::iterator vbegin = v.begin();
//    vector<Person*>::iterator vend = v.end();
//
//    Person p1("a1", 10);
//    Person p2("b2", 20);
//    v.push_back(&p1);
//    v.push_back(&p2);
//
//    for (vector<Person*>::iterator it = v.begin(); it != v.end(); it++) {
//        cout << "name= " << (*it)->name << " age= " << (*it)->age << endl;
//        //it是指向p1p2地址的指针,用*取到p1p2的地址,再用->取值
//    }
//}
//
//void test03() {
//    vector< vector<int> > v;//创建一个大容器,能够往下嵌套
//    vector<int> v1;//创建一个小容器,待会插入进大容器中。
//    vector<int> v2;
//    vector<int> v3;
//    //向小容器中插入元素
//    for (int i = 0; i < 4; i++) {
//    v1.push_back(10);
//    v2.push_back(20);
//    v3.push_back(30);
//    }
//    //向大容器中插入小容器
//    v.push_back(v1);
//    v.push_back(v2);
//    v.push_back(v3);
//    for (vector<vector<int>>::iterator it = v.begin(); it != v.end(); it++) {
//        for (vector<int>::iterator vit = (*it).begin(); vit != (*it).end();vit++) {
//            //(*it)解引用表示大容器指向小容器的指针
//            cout << *vit <<" ";
//        }
//        cout << endl;//遍历完小容器之后换行
//
//    }
//}

void test01()//四种构造方法
{
    //1、无参构造,默认里面无值
    vector<int> v1;
    for (int i = 1; i <= 10; i++) {
        v1.push_back(i);
    }
    PrintVector(v1);

    //2、使用迭代器构造,以两个迭代器参数传参
    vector<int> v2 (v1.begin(), v1.end());
    PrintVector(v2);

    //3、(n, elem)将n个elem拷贝赋值给本身。
    vector<int> v3(10, 666);
    PrintVector(v3);

    //4、拷贝构造函数
    vector<int> v4(v1);
    PrintVector(v4);
}


void test02()//三种赋值方法
{
    //初始化一个vector
    vector<int> v1;
    for (int i = 1; i <= 10; i++) {
        v1.push_back(i);
    }
    PrintVector(v1);

    //1、直接等号赋值
    vector<int> v2 = v1;
    PrintVector(v2);

    //2、assign(n, elem); //将n个elem拷贝赋值给本身。
    vector<int> v3;
    v3.assign(10, 555);
    PrintVector(v3);

    //3、迭代器赋值
    vector<int> v4;
    v4.assign(v1.begin(), v1.end());
    PrintVector(v4);
}

void PrintSize(vector<int> &v) {
    cout << "容器容量为:" << v.capacity() << endl;
    cout << "容器大小为:" << v.size() << endl;
}

void test03() {//容器的大小和容量以及判断是否为空
    //初始化一个vector
    vector<int> v1;
    for (int i = 1; i <= 10; i++) {
        v1.push_back(i);
    }
    PrintVector(v1);

    //v1.resize(0);若直接将大小设为0,会判断为空
    //if判断是否空
    if (v1.empty()) {
        cout << "当前容器为空" << endl;
    }
    else {
        cout << "当前容器不为空" << endl;
    }

    //输出容器和大小
    PrintSize(v1);

    //v1.resize(20);//重新定义容器大小,默认用0补齐
    //PrintVector(v1);
    //PrintSize(v1);

    v1.resize(5);//减少容器大小,会发现vector容器不会动态收缩,容量仍是最大的13
    PrintVector(v1);
    PrintSize(v1);

    vector<int>(v1).swap(v1);//匿名对象执行完当前行就释放,这里实际上使用了一个匿名函数与v1进行交换,v1得到的就是刚好符合他大小的容量,匿名对象换到的则是v1原来的容量,但是执行完当前行就被释放了,也没关系。
    //总结:可以利用swap函数进行内存的收缩
    PrintVector(v1);
    PrintSize(v1);
}

void test04() {//插入删除操作
    //初始化一个vector
    vector<int> v1;
    for (int i = 1; i <= 10; i++) {
        v1.push_back(i);//尾插数据
    }
    PrintVector(v1);

    v1.pop_back();//尾删数据
    PrintVector(v1);
    PrintSize(v1);

    v1.insert(v1.end(),10);//在迭代器的位置插入数据
    PrintVector(v1);
    PrintSize(v1);

    v1.erase(v1.begin());//在迭代器的位置删除数据
    PrintVector(v1);
    PrintSize(v1);

    //v1.erase(v1.begin(),v1.end());
    //PrintVector(v1);
    //PrintSize(v1);

    vector<int>::iterator it = v1.begin();
    cout << *it <<v1.front()<<v1.back(); 
    //v1.front()访问第一个元素,v1.back()访问最后一个元素


}

void test05() {
    vector<int> v1;
    int* p = NULL;
    int num=0;
    v1.reserve(100);
    for (int i = 1; i <= 100; i++) {
        v1.push_back(i);//尾插数据

        if (p != &v1[0]) {//因为v1每次动态拓展会开辟新内存,所以用p指针的判断统计v1有没有开辟新内存。
            p = &v1[0];
            num++;
        }
    }
    cout << num << endl;
    PrintVector(v1);
}
int main() {
    test05();
    return 0;
}

还有要补充几点:vector<int> v (100)就是指创建一个大小为100的容器,与数组定义类似

 2、string容器

string基本概念

本质:

  • string是C++风格的字符串,而string本质上是一个类

string和char * 区别:

  • char * 是一个指针
  • string是一个类,类内部封装了char*,管理这个字符串,是一个char*型的容器。

特点:

string 类内部封装了很多成员方法

例如:查找find,拷贝copy,删除delete 替换replace,插入insert

string管理char*所分配的内存,不用担心复制越界和取值越界等,由类内部进行负责

3.1.2 string构造函数

构造函数原型:

  • string(); //创建一个空的字符串 例如: string str;
    string(const char* s); //使用字符串s初始化
  • string(const string& str); //使用一个string对象初始化另一个string对象
  • string(int n, char c); //使用n个字符c初始化
#include <iostream>
#include <string> //使用string容器
#include <vector>
#include <algorithm> //使用STL提供的算法
using namespace std;

void test01() {//四种构造方法
    string s1;//空构造
    cout << "s1= " << s1 << endl;

    const char* p = "Hello World!";
    //cout << "p= " << p << " *p=" << *p << endl;
    //可以发现p指向的是字符数组"Hello World!",*p指向的是H首元素
    string s2(p);
    cout << "s2= " << s2 << endl;

    string s3(s2);//拷贝构造
    cout << "s3= " << s3 << endl;

    string s4(10, 'c');//使用n个字符初始化,若传入多个字符只会识别最后一个,'abc'->'c'
    cout << "s4= " << s4 << endl;
}

void test02() {
    string s1 = "hello";
    cout << "s1= " << s1 << endl;

    string s2 = s1;
    cout << "s2= " << s2 << endl;

    string s3;
    s3 = 'a';
    cout << "s3= " << s3 << endl;

    string s4;
    s4.assign("hello world");
    cout << "s4= " << s4 << endl;

    string s5;
    s5.assign("hello world", 7);
    cout << "s5= " << s5 << endl;

    string s6;
    s6.assign(s5);
    cout << "s6= " << s6 << endl;

    string s7;
    s7.assign(7, 's');
    cout << "s7= " << s7 << endl;
}

void test03() {
    string s1 = "hello";
    s1 += "world";
    cout << "s1= " << s1 << endl;

    string s2 = "friend";
    s2 += s1;
    cout << "s2= " << s2 << endl;

    string s3 = s1;
    s3.append("C++");//在末尾添加字符
    cout << "s3= " << s3 << endl;

    s3.append(s2, 4);//从第四个位置添加字符串
    cout << "s3= " << s3 << endl;

    s3.append(s2, 1, 4);//截取第1到4个字符
    cout << "s3= " << s3 << endl;
}

void test04() {
    string s1 = "hello world";
    int pos = s1.find('l');

    if (pos == -1)
    {
        cout << "未找到" << endl;
    }
    else
    {
        cout << "pos = " << pos << endl;
    }
    cout << "-------------" << endl;
    pos = s1.rfind('l');
    if (pos == -1)
    {
        cout << "未找到" << endl;
    }
    else
    {
        cout << "pos = " << pos << endl;
    }

    s1.replace(2, 5, "aaaaaaaa");//从第二个开始,替换五个字符
    cout << "s1=" << s1 << endl;
}

void test05()
{

    string s1 = "hello";
    string s2 = "hello";

    int ret = s1.compare(s2);

    if (ret == 0) {
        cout << "s1 等于 s2" << endl;
    }
    else if (ret > 0)//比较ASCII码大小,大于返回值1大于零,小于返回值-1小于零
    {
        cout << "s1 大于 s2" << endl;
    }
    else
    {
        cout << "s1 小于 s2" << endl;
    }

}

void test06() {//字符的读取和存取
    string s = "hello";
    for (int i = 0; i < s.size(); i++) {
        //cout << s[i] << " ";
        cout << s.at(i) << " ";//与vector类似,可以通过[]和at()访问
    }
    cout << endl;

    s[0] = 'x';
    s.at(1) = 'x';
    for (int i = 0; i < s.size(); i++) {
        cout << s[i] << " ";
        //cout << s.at(i) << " ";
    }
    cout << endl;
}

void test07()
{
    string str = "hello";
    str.insert(1,"999");
    cout << str << endl;

     //从1号位置开始4个字符
    str.erase(1, 4);
    cout << str << endl;
}

void test08() {
    string str = "lisi@QQ.com";
    string strson = str.substr(1, 4);
    cout << "strson = " << strson << endl;

    int pos = str.find("@");//通过find函数找到@的位置,从零到pos的位置就是几个 字符
    string username  = str.substr(0, pos);
    cout << "username = " << username << endl;
}
int main() {
    //test01();
    test08();
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值