day15 容器有好多东西需要记住的

Vector

vector数据结构和数组非常相似 ,也称为单端数组 , 与数组不同在于 数组是静态空间,而vector可以动态扩展 , 动态扩展不是在原有空间之后续接空间,而是找更大的内存空间,将原数据拷贝到新空间,释放原空间。

构造方式

//vector 
构造方式
vector<int>v1;//默认,无参构造
vector<int>v2(v1.begin(), v1.end());//通过区间的方式进行构造
vector<int>v3(5, 20);//n个elem构造
vector<int>v4(v2);//拷贝构造

赋值操作

重载 = 运算符    assign(beg , end)  assign(n , elem)

写一个打印容器里元素的代码

void printvector(vector<int> & v)
{
    for(vector<int>::iterator it = v.begin() ; it != v.end() ; it++)
    {
        cout << *it << "  " ;
    }
    cout << endl;
}

void test01() 
{
	vector<int>v1;//默认 , 无参
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	printvector(v1);
	vector<int>v2 = v1;
	printvector(v2);
	vector<int>v3;
	v3.assign(v2.begin(), v2.end());
	printvector(v3);
	vector<int>v4;
	v4.assign(4, 24);
	printvector(v4);
}

vector容器容量和大小操作

使用capacity和size函数

1、empty() 判断容器是否为空  capacity() 容量    

2、size()元素个数 

3、resize(int num)  重新指定长度,变长 默认值填充,变短就删除

4、resize(int num ,elem) 重新指定长度num 若容器变长用elem填充 ,变短则删除后面元素

void test01() 
{
	vector<int>v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	printvector(v1);
	if (v1.empty()) //为真 , 容器为空
	{
		return;
	}
	else 
	{
		cout << v1.size() << endl;
		cout << v1.capacity() << endl;
	}
	
	v1.resize(15);//默认0填充(15,100)100填充
	printvector(v1);
	v1.resize(8);
	printvector(v1);
}

删除 插入

1、push_back()
2、pop_back()
3、insert(const_iterator pos , ele)  第一个参数需要提供一个迭代器
4、insert(const_iterator pos ,int count, ele)第一个参数需要提供一个迭代器
5、erase(const_iterator pos)第一个参数需要提供一个迭代器
6、erase(const_iterator start , const_iterator end)
7、clean()

void test01()
{
	vector<int>v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	v1.pop_back();
	printvector(v1);

	v1.insert(v1.begin(), 100);//第一个参数需要提供一个迭代器
	printvector(v1);
	v1.insert(v1.begin(), 2, 1000);
	printvector(v1);
	
	v1.erase(v1.begin());//位置迭代器
	printvector(v1);
	//v1.erase(v1.begin(),v1.end());
	v1.clear();
	printvector(v1);

}

数据存储

1、at(int idx) 

2、operator[]

3、front()返回容器中第一个数据元素

4、back()返回最后一个元素

void test01()
{
	vector<int>v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	for (int i = 0; i < v1.size(); i++) 
	{
		//cout << v1[i] << " ";
		cout << v1.at(i) << " ";
	}
	cout << endl;


}

互换容器

 swap(vec)  将vec和本身的元素互换

这个函数有点意思,巧用可以收缩内存空间

void test02() 
{
	/*vector<int>v;
	for (int i = 0; i < 100000; i++) 
	{
		v.push_back(i);
	}*/
	cout <<"v的容量:" << v.capacity() << endl;
	cout << "v的大小:" << v.size() << endl;
	v.resize(3);//容量不变
	cout << "v的容量:" << v.capacity() << endl;
	cout << "v的大小:" << v.size() << endl;
	//巧用swap   底层vector<int>(v)是匿名对象  匿名函数的特点 当前函数执行完之后就回收内存
 	vector<int>(v).swap(v);
	cout << "v的容量:" << v.capacity() << endl;
	cout << "v的大小:" << v.size() << endl;
}
vector<int>(v).swap(v);

该方法的底层逻辑是上述这行代码,当我原始有一个很长的数组,然后通过resize将数组变成很短,那么该数组的容量是不会变的,当使用这一行代码的时候,会先创建vector<int>(v)这一个匿名函数,是用v赋值 给这个匿名函数,所以匿名函数的大小和容量就是v.size(),然后再使用swap函数进行交换,这时候就将匿名函数的内容和v进行交换,那么v.capacity()也就变小了。由于匿名函数本身的特点,当前函数执行完之后系统就会自动收回其内存,这样就不用担心内存泄漏了。

vector预留空间

reserve(int len);容器预留len个长度,预留位置不初始化,元素不可访问

void test02() 
{
	vector<int>v;

	//利用reserve预留空间
	v.reserve(100000);
	int num = 0;//统计开辟次数
	int* p = NULL;
	for (int i = 0; i < 100000; i++)
	{
		v.push_back(i);
		if (p != &v[0]) 
		{
			p = &v[0];
			num++;
		}
	}
	cout << "Num = " << num << endl;  //没使用reserve的时候num的大小是30   当使用了reserve的时候num为1.
}

没使用reserve的时候num(开辟次数)的大小是30   当使用了reserve的时候num为1。

string

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

string 和 char* 的区别:string是一个类,类内部封装了char* ,是一个char*型的容器。

特点:string内部封装了很多成员方法,eg find、copy、delete、replace、insert , string管理char*所分配的内存。

构造方式

1、string()

2、string(const char* s)

3、string(const string&str)

4、string(int n ,char c)

void test02() 
{
	string s1;
	const char* str = "hello world";

	string s2(str);
	cout << s2 << endl;

	string s3(s2);
	cout << "S3= " << s3 << endl;

	string s4(10, 'a');
	cout << s4 << endl;

}

赋值操作

1、string& operator=(const char* s);
2、string& operator=(const string&s);
3、string& operator=(char c );
4、string& assign(const char*s)
5、string& assign(const char*s , int n )
6、string& assign(const string&s)

字符串拼接 (实现在字符串末尾拼接字符串)

1、string& operator+=(const char* s);
2、string& operator+=(const string&s);
3、string& operator+=(char c );
4、string& append(const char*s) // 连接到结尾
5、string& append(const char*s , int n )//前n个字符连接到结尾
6、string& append(const string&s)
7、string& append(const string&s , int pos , int n );//从pos开始的n字符连接到结尾

void test01()
{
	string str1;
	str1 = "hello world";
	cout << "str1 = " << str1 << endl;
	string str2;
	str2.assign(str1);
	string str3;
	str3 = "我爱玩游戏:";
	string str4 = "LOL";
	str3 += str4;
	cout << str3 << endl;
	string str5 = "DNF";
	str3.append(str5);
	cout << str3 << endl;
	str3.append("game abcde", 4);
	cout << str3 << endl;
	str3.append("LOL DNF", 4, 3);

	cout << str3 << endl;
}

字符串查找替换

find() rfind()

rfind 和find区别:  rfind从右往左查找  find 从左往右查找。

void test01() 
{
	string str1 = "abcdefde";
	int pos = str1.find("de"); // 返回下标位置 如果没找到返回-1
	cout << pos << endl;

	//rfind 和find区别  rfind从右往左查找  find 从左往右查找
	pos = str1.rfind("de");
	cout << pos << endl;
}
void test02() 
{
	string str1 = "abcdefg";
	str1.replace(1, 3, "1111");//从1号位置起 3 个字符替换
	cout << str1 << endl;//a1111efg
}

比较

字符串比较是按字符的ascii码进行对比 = 返回 0; > 返回 1 ; < 返回 -1

compare()

字符存取

1、通过[]方式取字符char& operator[](int n )

2、char& at(int n )通过at方法获取 

void test02()
{
	string str = "hello";
	/*cout << str[1] << endl;
	cout << str.at(2) << endl;*/
	for (int i = 0; i < str.size(); i++) 
	{
		//cout << str[i] <<" " ;
		cout << str.at(i) << " ";
	}
	cout << endl;

	//修改
	str[0] = 'x';
	cout << str << endl;
}

插入 insert   删除erase

void test02() 
{
	string str = "hello";
	str.insert(1, "111");
	cout << str << endl;//h111ello

	str.erase(1, 3);
	cout << str << endl;
}

string子串

获取想要的子串  substr(int pos = 0 ,int n = npos) 返回由pos开始的n个字符串,该方法一般常和find一起使用,比如说获取邮件中人的信息等

void test01()
{
    string email ="zhangsan@163.com";
    string name = substr(0 , email.find('@'));
    cout << name << endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值