STL标准库的使用【2】

我们继续来介绍STL的相关容器的使用

一、vector

vector 是将元素置于一个动态数组中加以管理的容器

vector 可以随机存取元素 (用 [] 操作符 或 at () 方法)

vector 尾部添加或移除元素非常快速,但是在中部和头部时比较费时


1、vector 数据的访问

void func1()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(6);

	// 第一个元素
	cout << v.front() << endl;

	// 最后一个元素
	cout << v.back() << endl;

	// 返回值是一个引用
	v.front() = 10;
	v.back()  = 8;

	while(!v.empty())
	{
		cout << v.back() << endl;

		// 删除最后一个元素,没有返回值
		v.pop_back();
	}
}

2、遍历

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

3、构造

void func2()
{
	// 定义一个容器,一开始赋予10个对象空间
	vector<int> v1(10);
	cout << "当前元素个数: " << v1.size() << endl;

	v1[0] = 17;
	v1.at(1) = 9;
	v1.push_back(7);
	cout << "当前元素个数: " << v1.size() << endl;
	printV(v1);

	vector<int>  v2(10, 2);
	printV(v2);

	vector<int> v3 = v2;
	printV(v3);
	v3 = v1;
	printV(v3);

	vector<int>  v4(v3.begin(), v3.begin()+4);
	printV(v4);
}

4、元素删除

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

	vector<int>::iterator it = find(v1.begin(), v1.end(), 5);
	// 单个元素删除
	v1.erase(it);
	printV(v1);

	vector<int>::iterator it1 = find(v1.begin(), v1.end(), 3);
	vector<int>::iterator it2 = find(v1.begin(), v1.end(), 8);
	// 区间删除
	v1.erase(it1, it2);
	printV(v1);

	// 清空容器
	// v1.clear();
	vector<int> v2;   // 空的容器

	// 容器交换
	v1.swap(v2);

	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(2);
	v1.push_back(6);
	v1.push_back(2);
	v1.push_back(2);

	//for(vector<int>::iterator it = v1.begin(); it != v1.end();)
	//{
	//	if (*it == 2)
	//	{
	//		// 返回指向删除元素下一个元素的迭代器,需要接收回来
	//		it = v1.erase(it);
	//	}
	//	else
	//	{
	//		it ++;
	//	}
	//		
	//}

	it = v1.begin();
	while(it != v1.end())
	{
		if (*it == 2)
			it = v1.erase(it);
		else
			it++;
	}


	printV(v1);
}

5、元素插入

void func4()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(6);

	v.insert(v.begin(), 10);
	printV(v);

	v.insert(v.begin()+2, 3);
	printV(v);

	v.insert(v.end(), 4);
	printV(v);

	vector<int> v1;

	v1.insert(v1.begin(), v.begin(), v.end());
	printV(v1);
}

二、stack 和 queue

stack是堆栈容器,是一种“先进后出”的容器

queue是队列容器,是一种“先进先出”的容器


栈这个容器的相关操作

void func1()
{
	stack<int> s;
	s.push(1);
	s.push(5);
	s.push(3);
	s.push(10);         //插入

	cout << "栈顶元素: " << s.top() << endl;
	cout << "元素个数: " << s.size() << endl;

	while (!s.empty())
	{
		cout << s.top() << endl;  // 打印栈顶元素
		s.pop();  
	}
}

队列的相关操作(和栈类似)

void func2()
{
	queue<int> q;
	q.push(1);
	q.push(10);
	q.push(2);
	q.push(5);

	cout << "队头元素: " << q.front() << endl;
	cout << "队尾个数: " << q.back() << endl;

	while (!q.empty())
	{
		cout << q.front() << endl;  // 打印栈顶元素
		q.pop();  
	}
}

用两个栈实现一个队列

class MyQueue
{
public:
	// 出队
	void pop()
	{
		// 第一种:
		// 1、先把 s1 留一个元素, 其他导入到 s2 中
		// 2、s1 出栈
		// 3、将 s2 元素再导入到 s1 中

		// 第二种
		// 1、先判断 s2 是否为空
		// 2、不为空,s2直接出栈
		// 3、如果空,将 s1 留一个元素, 其他导入到 s2 中
		// 4、s1出栈
		if(s2.empty())
		{
			while (s1.size() > 1)
			{
				s2.push(s1.top());
				s1.pop();
			}

			if (!s1.empty())
				s1.pop();
		}
		else
		{
			s2.pop();
		}
	}

	// 入队
	void push(int num)
	{
		// 入 s1
		s1.push(num);
	}
private:
	stack<int> s1;
	stack<int> s2;
};


三、list容器

list是一个双向链表容器,可以高效地进行插入和删除
list不可以随机的存储元素

1、list 的赋值 删除  反序

void func1()
{
	list<int> list1;
	list1.push_back(1);
	list1.push_back(2);
	list1.push_back(2);
	list1.push_back(2);
	list1.push_back(2);
	list1.push_back(2);
	list1.push_back(2);
	list1.push_back(3);

	list1.push_front(-1);
	list1.push_front(-2);
	list1.push_front(-3);

	printL(list1);

	list<int>::iterator it = list1.begin();
	it++;
	it++;

	// list1.erase(list1.begin(), list1.end());       删除区间数据返回下一个数据的位置
	//list1.erase(list1.begin(), list1.begin());
	//printL(list1);

	list1.remove(2);           //删除匹配的元素
	printL(list1);

	list1.reverse();          //反序列表
	printL(list1);
}

2、list 与  迭代器

void func2()
{
	vector<int> v(10);
	for (int i = 0; i < 10; i++)
	{
		v[i] = i;
	}

	// 正向迭代器
	for(vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;

	// 反向迭代器
	for(vector<int>::reverse_iterator it = v.rbegin(); it != v.rend(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;

}

四、优先级队列 priority_queue

优先级队列内部数据是排完序的,默认是从大到小排序

void func1()
{
	// 优先级队列内部数据是排完序的,默认是从大到小排序
	// priority_queue<int> q;
	// priority_queue<int, vector<int>, less<int>> q;
	priority_queue<int, vector<int>, greater<int>> q;
	q.push(10);
	q.push(4);
	q.push(2);
	q.push(65);


	while (!q.empty())
	{
		cout << q.top() << endl;
		q.pop();
	}
}


五、set/multiset

set 是一个集合容器,其中所包含的元素是唯一的,集合中的元素按一定顺序排列

元素插入过程是按排序规则插入,所以不能指定插入位置


multiset与set的区别:set支持唯一键值,每个元素值只能出现一次;

而multiset中同一值可以出现多次。


set.insert(elem);     //在容器中插入元素。

set.begin();  //返回容器中第一个数据的迭代器。

set.end();  //返回容器中最后一个数据之后的迭代器。

set.rbegin();  //返回容器中倒数第一个元素的迭代器。

set.rend();   //返回容器中倒数最后一个元素的后面的迭代器。


set<int,less<int> >  setIntA;  //该容器是按升序方式排列元素。

set<int,greater<int>> setIntB;   //该容器是按降序方式排列元素。


六、map/multimap

map的使用  容器:存的是键  值   对

map 和 set 一样会自动排序,是以键进行排序 ,map 键唯一

通过 map 插入有3种方式

void func1()
{
	// 键 : int 类型
	// 值 : string 类型
	// 存学生的 id 和 姓名
	map<int, string> m;
	
	// 数据插入:
	// 1、通过 pair 键值对插入数据
	m.insert(pair<int, string>(7, "郑"));
	m.insert(pair<int, string>(8, "王"));

	// 2、通过 make pair 构建键值对
	m.insert(make_pair(5, "周"));
	m.insert(make_pair(1, "赵"));

	// 3、通过map类型插入
	m.insert(map<int, string>::value_type(3, "孙"));
	m.insert(map<int, string>::value_type(2, "钱"));

	// 4、通过 [] 方式插入数据,  []不代表数组下标,[]内部的值是 map 键
	m[4] = "李";
	m[6] = "吴";

	printM(m);
}

还有一种方式是通过 [ ] 方式插入数据,[ ] 不代表数组下标, [ ] 内部的值是 map 键  


添加用户(这个用户是类呢)

class Student 
{
public:
	Student(int id, string name)
	{
		this->id = id;
		this->name = name;
	}
private:
	int id;
	string name;
};

class UserManager
{
public:
	UserManager()
	{

	}

	// 添加用户
	void add(int id, string name)
	{
		Student *ps = new Student(id, name);

		m.insert(pair<string, Student*>(name, ps));
	}

	~UserManager()
	{
		map<string, Student*>::iterator it =  m.begin();
		while(it != m.end())
		{
			delete it->second;
			it = m.erase(it);
		}
	}
private:
	// 键: 学生名字  值 : 学生   
	map<string, Student*> m;
};

map 迭代器的删除和查找

// 迭代器删除
	m.erase(m.begin());
	printM(m);

	// 通过键删除数据
	cout << "-----------------" << endl;
	m.erase("赵");
	printM(m);


	cout << "-----------------" << endl;
	// 查找数据: 查找通过键查找
	map<string, int>::iterator it = m.find("孙");
	if (it != m.end())
	{
		cout << "id = " << it->second << endl;
	}

	pair<map<string, int>::iterator, map<string, int>::iterator> ret = m.equal_range("孙");
	if (ret.first != m.end())
		cout << "id = " << ret.first->second << endl;

	if (ret.second != m.end())
		cout << "id = " << ret.second->second << endl;
}

void func4()
{
	map<string, int> m1;
	m1.insert(make_pair("王", 8));

	// [] 不一定是插入  
	// 如果键存在,修改原键的值,如果键不存在,就创建一个新的键值对
	m1["张"] = 10;
}

multimap与map的区别:map支持唯一键值,每个键只能出现一次;

而multimap中相同键可以出现多次。multimap不支持[]操作符。




  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值