【STL】STL 中vector和list的使用

2 篇文章 0 订阅

        标准模板库(STL)是用于C ++编程语言的软件库,影响了C ++标准库的许多部分。它提供了六个组件,称为算法(alorithms),容器(containers),迭代器(iterators),仿函数(functions),配接器(adapters)和配置器(allocators)。STL提供了一组C ++的常用类,例如容器和关联数组,可以与任何内置类型一起使用,并且支持用户自定义类型的一些基本操作(如复制和分配)。 STL算法独立于容器,最后在以"胶合剂“(iterator)将它们粘合在一起,这显着降低了库的复杂性。

由http://www.cplusplus.com/reference/vector/vector/我们可以获得Vector的接口,在模拟实现之前,首先要对各个接口有详细的认识,所以今天就来熟悉各个接口的使用。

下面是各个接口:


在代码中应用这些接口:

void TestVector()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);

	Print1(v1);
	Print2(v1);
	Print3(v1);

	cout <<"the size of v1 is "<< v1.size() << endl;

	vector<int> v2(5, 2);  //存入5个2
	Print1(v2);
	v2.pop_back();
	Print1(v2);

	cout << "the size of v2 is " << v1.size() << endl;
}

由于系统中没有提供打印接口,这就需要我们手动写一个;

//普通迭代器--可读可写
void Print1(vector<int>& v)
{
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";       //读
		++it;

		//cout << ++(*it) << " ";    //写,每个值都加1
		//++it;
	}
	cout << endl;
}

在上述代码中我们用到了迭代器,已经知道迭代器是STL的一个接口。

迭代器的模式定义为:提供一种方法,使之能够依序访问某个聚合物(容器)所含的各个元素,而又无需暴露该聚合物的内部表达式。

iterator迭代器称为普通迭代器,意味着我们可以对它进行读写操作(通过operator*和operator++实现),但是有时候我们要求不能对数据进行修改,这时候就就需要const_iterator,只能读不能写,同样的,根据需求不同,还有reverse_iterator(反向迭代器)和const_reverse_iterator,顾名思义,反向迭代器就是逆序遍历,具体是怎样实现的我们在模拟实现iterator再进行学习。

//const迭代器--只能读
void Print2(const vector<int>& v)
{
	vector<int>::const_iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;

		//cout << (*it)++ << " ";    //写入会失败
		//++it;
	}
	cout << endl;
}


//反向迭代器/const反向迭代器--逆序遍历
void Print3(const vector<int>& v)
{
	vector<int>::const_reverse_iterator it = v.rbegin();
	{
		while (it != v.rend())
		{
			cout << *it << " ";
			++it;

			//cout << ++(*it1) << " ";   //不能修改
			//++it1;
		}
	}
	cout << endl;
}

运行结果:



接下来看看resize:Change size (public member function)这个接口:这个接口是对当前元素个数进行修改

如果n小于当前的容器大小,则将内容减少到其前n个元素,删除超出(并且销毁它们)的元素。

如果n大于当前的容器大小,则根据需要插入要达到n的元素来扩展内容。 如果指定了val,则新元素将被初始化为val的副本,否则它们被初始化。

如果n也大于当前的容器容量,则会自动重新分配已分配的存储空间。

void TestResize()
{
	vector<int> v1;
	for (size_t i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	Print1(v1);

	v1.resize(6);
	Print1(v1);

	v1.resize(9, 10);
	Print1(v1);

	v1.resize(20);
	Print1(v1);
}



reserveRequest a change in capacity(public member function)

如果n大于当前向量容量,则该函数使容器重新分配其存储空间,将其容量增加到n(或更大)。在所有其他情况下,函数调用不会导致重新分配,并且向量容量不受影响。此功能对矢量大小没有影响,不能更改其元素。

void TestReserve()
{
	vector<int> v1;
	
	for (size_t i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}

	cout << v1.size() << endl;
	cout << v1.capacity() << endl;

	v1.reserve(20);             //将容量扩展到20
	cout << v1.capacity() << endl;

	v1.reserve(2);             //2<20,但是容量不会减小
	cout << v1.capacity() << endl;
}


要访问容器中的数据除了我们最开始用到的迭代器,我们还可以使用operator[] 这个接口,通过索引的方式对数据进行访问,它的底层实现就是通过重载“[ ]”来达到下标访问的目的。类似的成员函数vector :: at具有与此运算符函数相同的行为,除了vector :: at被绑定检查,并通过抛出out_of_range异常来指示请求的位置是否超出范围。所以,在使用时一定要注意边界,否则很容产生越界问题。

void TestIndex()
{
	vector<int> v1(10);   //10个为0的初始化数据
	for (size_t i = 0; i < 10; i++)
	{
		v1[i] = i + 1;    //对数据元素进行修改
		cout << v1[i] << ' ';
	}
	cout << endl;
}


insert 有多个接口,这为我们插入数据提供了极大的方便。



void TestInsert()
{
	vector<int> v1(5, 1);  //11111
	vector<int>::iterator it = v1.begin();

	it = v1.insert(it, 2);  //211111

	v1.insert(it, 2, 3);  //33211111

	it = v1.begin();

	vector<int> v2(2, 4);   //44
	
	v1.insert(it + 2, v2.begin(), v2.end());  //3344211111

	int v3[] = { 5, 6, 7 };
	v1.insert(v1.begin(), v3, v3 + 3);   //5673344211111

	 it = v1.begin();
	while (it != v1.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}




vector还有很多的接口,但是其中有很多再以前的学习中都已经接触过,所以没有必要在进行解释。我们也可以以同样的方法模拟学习list,deque等。

接下来是对list中的几个接口的应用


splice:将元素从x转移到容器中,将它们插入位置。具体怎么转移要看传递的参数

1.将x的所有元素传输到容器中。
2.只将i指向的元素从x传送到容器。
3.将范围[起始位置,终止位置)从x传送到容器。

list<int> l1, l2;
	list<int>::iterator it;

	for (int i = 0; i < 4; ++i)    // l1: 0 1 2 3 4
		l1.push_back(i);

	for (int i = 1; i < 5; ++i)    // l2: 100 200 300 400 
		l2.push_back(i * 100);

	it = l1.begin();                // points to 1
	++it;

	l1.splice(it, l2);              // l1: 0 100 200 300 400 1 2 3 
	Print1(l1);

	l2.splice(l2.begin(), l1, it);   //l2: 1
	Print1(l2);

	it = l1.begin();
	++it;

	l1.splice(l1.begin(), l1, it, l1.end());// l1: 100 200 300 400 1 2 3 0
	Print1(l1);




unique:去重。不过要注意的是只有重复的元素是相邻的去重才会有效

void TestUnique()
{
	list<int> l1;
	l1.push_back(1);
	l1.push_back(1);
	l1.push_back(2);
	l1.push_back(3);
	l1.push_back(4);
	l1.push_back(4);
	l1.push_back(4);
	l1.push_back(5);
	Print1(l1);

	l1.unique();
	Print1(l1);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值