STL学习笔记

#include<iostream>
using namespace std;
//要想使用STL中的标准算法,必须包含它的头文件
#include<algorithm>
//STL中的每个容器在使用时都要包含它的头文件
class fang
{
public:
	bool operator()(int v1, int v2)
	{
		return v1 > v2;
	}
};
void myPrint(int a)
{
	cout << a << endl;
}
//
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
#include<vector>
void text01()
{
	vector<int> v;//创建容器v

	v.push_back(10);
	v.push_back(20);
	v.push_back(30);//向容器尾部插入数据

	vector<int>::iterator Begin = v.begin();//头指针
	vector<int>::iterator End = v.end();//尾指针的下一个指针
	//-----------迭代器类型-------------可抽象理解为指针

	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << endl;//循环遍历打印
	}
	//利用STL中的标准算法遍历
	for_each(v.begin(), v.end(), myPrint);//使用MyPrint函数来打印,for_each负责循环


	vector<int> v1;                      //默认构造     ||
	vector<int> v2(v1.begin(), v1.end());//区间构造     ||
	vector<int> v3(10, 100);             //存入10个100  ||---->构造函数
	vector<int> v4(v1);                  //拷贝构造     ||

	vector<int> f1;                                          //||
	vector<int> f2;                                          //||
	vector<int> f3;                                          //||
	f1 = f2;                        //等号赋值                 ||---->赋值操作
	f1.assign(f2.begin(), f2.end());//从begin取值到end的上一个 ||
	f3.assign(10, 100);             //存入10个100              ||

	  
	vector<int> rl(10,100);//调用构造进行初始化                                  //||
	if (rl.empty())                                                              //||
	{                                                                            //||
		cout << "rl为空!" << endl;                                              //||
	}                                                                            //||
	else                                                                         //||
	{                                                                            //||
		cout << "rl不为空!" << endl;                                            //||---->关于容量和大小的操作
		cout << "rl的容量为=" << rl.capacity() << endl;                          //||
		cout << "rl的大小为=" << rl.size() << endl;//注意!一般容量是大于“大小”的||
		rl.resize(15);//重新指定大小,用0填补                                    //||
		cout << "重新指定的容量为=" << rl.capacity() << endl;                    //||
		cout << "重新指定大小为=" << rl.size() << endl;                          //||
		rl.resize(15, 100);//重新指定大小,用100填补                             //||
		//如果重新指定的比原来短,则超出的会被删除(注意!size变了但是容量不变!)//||
	}                                                                            //||

	vector<int> cr;                                                              //||
	cr.push_back(10);                                                            //||
	cr.push_back(20);//使用尾插法插入数据                                        //||
	cr.push_back(30);                                                            //||
	cr.pop_back();//尾删,这里吧30删了                                           //||
	cr.insert(cr.begin(), 100);//在头部插入一个100,第一个参数是迭代器           //||---->插入和删除
	cr.insert(cr.begin(), 2, 1000);//在头部插入2个1000                           //||
	cr.erase(cr.begin());//在头部删除一个1000                                    //||
	cr.erase(cr.begin(), cr.end());//相当于全部清空                              //||
	cr.clear();//清空操作                                                        //||

	vector<int> cq(10,100);                                            //||
	for (int i = 0; i < cq.size(); i++)                                //||
	{                                                                  //||
		cout << cq[i] << " ";                                          //||
		cout << cq.at(i) << endl;//两种访问方式                        //||---->数据存取
	}                                                                  //||
	cout << "获取第一个元素为=" << cq.front() << endl;                 //||
	cout << "获取最后一个元素=" << cq.back() << endl;                  //||

	vector<int> h1(10,99);                                             //||
	vector<int> h2(10,22);                                             //||
	h1.swap(h2);//将两个容器里的内容进行互换                           //||
	//当使用resize小型化调整容器后,可以                               //||
	//巧妙的使用swap进行缩小占用的空间                                 //||
	//vector<int>(v).swap(v);                                          //||
	//前半部分vector<int>(v)为匿名对象                                 //||
	vector<int> vs;                                                    //||
	int num = 0;                                                       //||
	int* p = NULL;                                                     //||
	for (int i = 0; i < 100000; i++)                                   //||
	{                                                                  //||---->互换与预留空间
		vs.push_back(i);                                               //||
		if (p != &vs[0])                                               //||
		{                                                              //||
			p = &vs[0];//push_back在每次尾插时候(如果空间不够)都会重新//||
			num++;     //分配另一个更大的空间,会引起头指针变化        //||
		}                                                              //||
	}                                                                  //||
	cout << num << endl;                                               //||
	vs.reserve(100000);//通过reserve来预留空间来进行防止,             //||
	//预留的空间不可访问!                                             //||


}                      
//
#include<deque>
void text03()
{
	//deque与vector很相似,也可以使用iteroter和const iteroter迭代器

	deque<int> d1;                                     //||
	deque<int> d2(d1.begin(), d1.end());//[begin,end)//||
	deque<int> d3(10, 100);                            //||---->构造函数(与vector完全一样)
	deque<int> d4(d3);                   //拷贝构造    //||

	deque<int> f1;                      //||
	deque<int> f2 = f1;                 //||
	f2.assign(d1.begin(), d1.end());    //||---->赋值操作(与vector完全一样)
	f2.assign(10, 100);                 //||

	deque<int> dx;                   //||
	dx.empty();//为空返回真!          ||
	dx.size();//大小                   ||---->大小操作(与vector完全一样)
	dx.resize(2);//调整大小            ||
	//deque没有容量的概念!          //||

	deque<int> cr, cr2;
	cr.push_back(10); //尾插                               ||
	cr.push_front(22);//头插                               ||
	cr.pop_back();    //尾删10                             ||
	cr.pop_front();   //头删22                             ||
	cr.insert(cr.begin(), 1000);//插入一个1000              ||
	cr.insert(cr.begin(), 2, 999);//插入2个999             ||---->插入删除(类似vector)
	cr.insert(cr.begin(), cr2.begin(), cr2.end());//片段插入||
	cr.erase(cr.begin());//删除begin指向的元素             ||
	cr.erase(cr.begin(), cr.end());//                      ||
	cr.clear();//全删                                      ||

	deque<int> cq(10, 100);                  //||
	cout << cq[1];                          //||
	cout << cq.at(1);                       //||---->数据存取(与vector完全一样)
	cout << "访问第一个元素" << cq.front(); //||
	cout << "访问最后一个元素" << cq.back();//||

	sort(cq.begin(), cq.end());//默认排序为升序||

}
/* deqque与vector的区别
vector对于头部插入删除效率低,数据量越大,效率越低。
deque相对而言,对头部的插入删除速度会比vector快
vector访问元素时的速度会比deque快。
*/
#include<list>//链表
void text06()//迭代器为双向,不支持随机访问
{   //将数据进行链式存储,可以对任意的位置进行快速的插入和删除。
	//对于元素的遍历速度没有数组快,占用的空间会比数组大//!!!!也可使用iterator迭代器!用法都一样
	list<int> L;                             //||
	list<int> L2(L.begin(), L.end());//区间构造||
	list<int> L3(L);//拷贝构造               //||---->构造函数
	list<int> L4(10, 100);//存入10个100      //||

	list<int> L5;                 //||
	L5 = L;                       //||
	L5.assign(L.begin(), L.end());//||---->赋值操作
	L5.assign(10, 100);           //||
	L5.swap(L);//交换函数         //||

	list<int> rl(10, 100);//调用构造进行初始化                                   //||
	if (rl.empty())                                                              //||
	{                                                                            //||
		cout << "rl为空!" << endl;                                              //||
	}                                                                            //||
	else                                                                         //||
	{                                                                            //||
		cout << "rl不为空!" << endl;                                            //||---->关于容量和大小的操作
		cout << "rl的大小为=" << rl.size() << endl;//注意!一般容量是大于“大小”的||
		rl.resize(15);//重新指定大小,用0填补                                    //||
		cout << "重新指定大小为=" << rl.size() << endl;                          //||
		rl.resize(15, 100);//重新指定大小,用100填补,如果过小会“丢失“         //||
	}

	list<int> cr, cr2;
	cr.push_back(10); //尾插                                ||
	cr.push_front(22);//头插                                ||
	cr.pop_back();    //尾删10                              ||
	cr.pop_front();   //头删22                              ||
	cr.insert(cr.begin(), 1000);//插入一个1000              ||
	cr.insert(cr.begin(), 2, 999);//插入2个999              ||---->插入删除(类似vector)
	cr.insert(cr.begin(), cr2.begin(), cr2.end());//片段插入||
	cr.erase(cr.begin());//删除begin指向的元素              ||
	cr.erase(cr.begin(), cr.end());//                       ||
	cr.clear();//全删                                       ||
	cr.remove(2);//删除容器中所有与2匹配的元素(独有!!!)||

	list<int> cq(10, 100);                  //||
	//cout << cq[1];不支持!!!!          //||
	//cout << cq.at(1);不支持!!!         //||---->数据存取
	cout << "访问第一个元素" << cq.front(); //||
	cout << "访问最后一个元素" << cq.back();//||

	list<int> ff;//                           ||
	ff.reverse();//反转链表                   ||
	//这里因为list迭代器不支持随机,所以不能用||---->反转与排序
	//sort(ff.begin(),ff.end());!!!!!!!!!!!!||
	ff.sort();//链表排序(升序)                ||

}
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
#include<string>//字符类型
void text02()
{
	string s1;                  //创建一个空字符串                   ||
	const char* str = "hello";  //                                   ||
	string s2(str);             //使用字符串str初始化                ||---->均为构造函数 
	string s3(s2);              //用一个string去初始化另一个string   ||
	string s4(10, 'a');         //使用10个字符‘a’初始化            ||
	
	s1 = "hello";               //char*类型字符串赋值                ||   
	s1 = s2;                    //吧同为string类型的s2赋值给s1       ||
	s1 = 'a';                   //单字符赋值                         ||
	s1.assign(str);             //char*类型字符串赋值                ||---->赋值操作
	s1.assign("hello",2);       //赋值前2个                          ||
	s1.assign(s2);              //                                   ||
	s1.assign(10, 'a');         //                                   ||
	
	string str1 = "我";         //                                   ||
	str1 += "爱玩游戏";         //字符串的拼接                       ||
	str1 += ':';                //再追加一个:                       ||
	string str2 = "LOL";        //                                   ||
	str1 += str2;               //把一个string拼接到另一个string后   ||
	string str3 = "I";          //                                   ||---->字符串拼接
	str3.append("love");        //利用append拼接                     ||
	str3.append("you to", 3);   //拼接前三个                         ||
	str3.append(str2);          //                                   ||
	str3.append(str2, 0, 3);    //从第0个位置截取3个                 ||

	string cr = "hello";        //                                   ||
	cr.insert(1, "111");        //结果为h111ello                     ||---->插入和删除
	cr.erase(1, 3);             //从第一个位置起,删除3个            ||

	string c1 = "abcdefg";    //↓0是从第0位开始查找,可不写             ||
	int pos = c1.find("de",0);//返回查找到的字符串头的下标,没有返回-1   ||
	int por = c1.rfind("de"); //是从右往左查找                           ||---->查找
	c1.replace(1, 3, "1111");//从1号位置起3个字符替换为"1111"            ||

	//字符比较:=返回0  >返回1  <返回-1   ||
	string b1 = "abcd";//                 ||
	string b2 = "abcd";//                 ||
	if (b1.compare(b2) == 0)//            ||---->字符比较
	{   cout << "b1=b2" << endl;   }//    ||
	//比较是按照ASII码值逐个比较的        ||

	string cc = "hello";                //||
	for (int i = 0; i < cc.size(); i++) //||
	{                                   //||
		cout << cc[i]<<endl;            //||---->字符访问(vector也可用)
		cout << cc.at(i) << endl;       //||
	} //注意,也可以这样进行访问修改    //||
	
	//srting求子串                                                     ||
	string zc = "abcdefgh";                                          //||
	string zc1 = zc.substr(1, 3);//从下表为1处开始截取3个为新的字符串//||
	cout << zc1 << endl; //结果为bcd                                 //||

}
/*
std::vector 和 std::string 是 C++ 标准库中的两个不同的容器类型,它们分别用于处理动态数组和字符串。以下是它们的主要区别:
1.元素类型:
  std::vector:存储任意类型的元素,可以是基本数据类型、自定义类型等。
  std::string:专门用于存储字符的容器,其元素类型是 char。
2.用途:
  std::vector:主要用于存储和管理动态数组,提供动态大小的、连续的内存存储。
  std::string:专门用于处理字符串,提供了很多与字符串相关的成员函数,如拼接、截取、查找等。
3.操作和成员函数:
  std::vector:提供了数组操作的功能,比如随机访问、插入、删除等。不包含字符串处理的专用函数。
  std::string:提供了很多字符串操作的成员函数,如拼接(+ 操作符、append 函数)、截取(substr 函数)、查找(find 函数)等。
4.底层实现:
  std::vector:使用动态数组作为底层实现,保证了元素的内存是连续存储的。
  std::string:底层实现可以是动态数组,也可以是其他方式,但一般都会保证字符串的字符是连续存储的。
5.长度表示:
  std::vector:使用 size() 成员函数获取元素个数。
  std::string:使用 length() 或 size() 成员函数获取字符串的长度。
*/
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
#include<stack>//栈,先进后出
void text04()
{
	//stack为栈,可以判断容器是否为空,可以返回元素个数,不可遍历
	//符合先进后出的数据结构
	stack<int> s;
	s.push(10);
	s.push(20);//向栈顶添加元素
	s.push(30);
	cout << "栈的大小为=" << s.size() << endl;
	//只要栈不为空,则查看栈顶并出栈
	while (!s.empty())//如果不为空
	{
		cout << "栈顶元素=" << s.top() << endl;//查看栈顶元素
		s.pop();//出栈一个元素
	}
	cout << "栈的大小为=" << s.size() << endl;
		
	
}
//
#include<queue>//队列,先进先出
void text05()
{
	//队尾只能进,队头只能出(队列的数据元素)
	//只有队头队尾可以被外界访问到,不允许遍历
	queue<int> gz;
	gz.push(1);
	gz.push(2);//入队
	while (!gz.empty())
	{
		cout << "队头元素" << gz.front() << endl;
		cout << "队尾元素" << gz.back() << endl;
		gz.pop();//出队操作
	}
	cout << "队列大小" << gz.size();
}
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
#include<set>//二叉树
void text07()
{//set和multiset为关联式容器,在插入时会自动排序//底层为二叉树,可用iteroter
 //set不允许容器中有重复元素,插入时会返回插入结果            
 //multiset允许有重复元素,不会返回结果
	set<int> s1;         //||
	set<int> s2(s1);     //||
	multiset<int> m1;    //||---->构造he赋值
	multiset<int> m2(m1);//||
	s2 = s1;             //||

	set<int> s3;      //||
	set<int> s4;      //||
	s3.empty();//判空 //||---->判断大小
	s3.size();//大小  //||
	s3.swap(s4);//交换//||
	              
	set<int> s5;                   //||
	s5.insert(10);//插入10           ||
	s5.erase(s5.begin());//删除10    ||
	s5.erase(10);//删除10            ||---->插入和删除
	s5.erase(s5.begin(), s5.end());//||
	s5.clear();                    //||

	set<int> s6;                                                    //||
	s6.insert(10);                                                  //||
	s6.insert(20);                                                  //||---->查找和统计
	s6.find(20);//查找20是否存在,存在返回迭代器,不存在返回s6.end()  ||
	s6.count(20);//统计20的个数,对于multiset结果才可能会大于1        ||

	set<int> s7;                                       //||
	pair<set<int>::iterator, bool> ret = s7.insert(10);//||
	if (ret.second)//.second指的是查看第二个bool         ||
	{ cout << "插入成功" << endl; }                    //||---->插入判断
	                                                   //||
	pair<string, int> f("Tom", 12);//队组的创建 1        ||
	pair<string, int> g = make_pair("Tom", 12);//创建 2  ||
	cout << f.first << " " << f.second << endl;//访问队组||

	set<int,fang> s8;//利用仿函数实现从大到小排序
	//对于自定义数据类型,一般都要利用仿函数重定义排序规则
	

}
//
#include<map>//二叉树//所有元素都是以pair的形式进行存储的,都包含了键&值
void text08()
{//pair中的第一个元素为key(键值),第二个为value(实值)//可用iterator!!!!
 //所有元素都会根据key来自动排序
 //map和multimap属于关联式容器,底层为二叉树
 //map不允许有重复的key值,mu···可以
	map<int, int> m;//默认构造    //||
	map<int, int> m2(m);//拷贝构造//||
	multimap<int, int> m3;        //||---->构造函数
	multimap<int, int> m4(m3);    //||

	map<int, int> m5;             //||
	m5.size();//返回容器中元素数目//||
	m5.empty();//判空             //||---->大小和交换
	m5.swap(m);//交换容器         //||

	map<int, int> m6;                                        //||
	m6.insert(pair<int, int>(1, 10));//插入一个10            //||
	m6.insert(make_pair(2, 20));//插入一个20                 //||
	m6.insert(map< int, int>::value_type(3, 30));//了解即可  //||
	m6[4] = 40;//不建议用来插入,但是可以用来访问!          //||---->插入和删除
	m6.erase(m6.begin());//删除第一个                        //||
	m6.erase(2);//按key来删除                                //||
	m6.erase(m6.begin(), m6.end());                          //||
	m6.clear();//清空                                        //||

	map<int, int> m7;
	m7.find(2);//查找key,找到返回迭代器位置,没有找到返回m7.end
	map<int, int>::iterator pos = m7.find(2);//⬅⬅列子
	int a = m7.count(2);//统计有几个key为2的

	//map可以像set一样来利用仿函数来改变排序规则
	map<int, int, fang> m8;//此为从大到小排序!

}
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
//









void text09()
{





}










int main()
{
	//text01();//vector容器调用
	//text02();//string容器调用
	//text03();//deque容器调用
	//text04();//stack容器调用
	//text05();//queue容器调用
	//text06();//list容器调用
	//text07();//set容器调用
	//text08();//map容器调用
	
	//text09();//算法
	return 0;
}

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
侯捷的《STL源码剖析》是一本关于STL(标准模板库)的学习笔记。这本书深入解析了STL的实现原理和设计思路,对于理解STL的内部机制和使用方法非常有帮助。这些学习笔记记录了作者在学习侯捷的《STL标准库和泛型编程》课程时的心得和总结,对于理解STL源码和进行泛型编程都具有指导意义。 这本书涉及了STL的各个模块,包括容器、迭代器、算法等,并解释了它们的实现原理和使用方法。通过学习这本书,你可以更好地理解STL的底层实现和使用技巧。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [STLSourceAnalysis:stl原始码剖析(侯捷)的学习笔记](https://download.csdn.net/download/weixin_42175776/16069622)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [候捷老师STL源码剖析视频课程笔记](https://blog.csdn.net/weixin_46065476/article/details/125547869)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [侯捷——STL源码剖析 笔记](https://blog.csdn.net/weixin_45067603/article/details/122770539)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值