C++-STL容器

string容器

一些基础的就不说了

  1. string();创建一个长度为0的string对象(默认构造函数)。
  2. sring(const char *s);将string对象初始化为s指向的 NBTS(转换函数)。
  3. string(const string &str);将string对象初始化为str(拷贝构造函数)。
  4. string(const void *s,size_t n);将string对象初始化为s指向的地址后n字节的内容。
  5. string(const string &str,size_t pos=0,size_t n=npos);将sring对象初始开始到结尾的字符,或从位置pos 开始的n个字符。
  6. template<class T> string(T begin,T end);将string对象初始化为区间[begin,end]内的字符,其中 begin和end的行为就像指针,用于指定位置,范围包括begin在内,但不包括end。
#define _CRT_SECUER_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

int main() {
	struct st_girl {//超女结构体
		int bh;
		char name[30];
		bool yz;
		double weight;
		string memo;
	}girl;
	cout << "超女结构体的大小" << sizeof(struct st_girl) << endl;
	string buffer;//创建一个空的string容器buffer
	///生成10名超女的信息,存入buffer中
	for (int ii = 1;ii <= 10;ii++) {
		//对超女结构体成员赋值
		memset(&girl, 0, sizeof(struct st_girl));
		girl.bh = ii;
		sprintf(girl.name, "西施%02d", ii);
		girl.yz = true;
		girl.weight = 48.5 + ii;
		girl.memo = "中国历史第一美女.";
		//把超女类追加到buffer中
		buffer.append((char*)&girl, sizeof(struct st_girl));

		cout << (void*)&girl << endl;
	}
	cout << "buffer.capacity()=" << buffer.capacity() << endl;//显示容量
	cout << "buffer.size()=" << buffer.size() << endl;//显示实际大小
	//用一个循环,把buffer容器中全部的数据取出
	for (int ii = 0;ii < buffer.size() / sizeof(struct st_girl);ii++) {
		memset(&girl, 0, sizeof(struct st_girl));//初始化超女结构体
		//把容器中的数据复制到超女结构体
		memcpy(&girl, buffer.data() + ii * sizeof(struct st_girl), sizeof(struct st_girl));
		//buffer.copy((char*)&girl,sizeof(struct st_girl),ii*sizeof(struct st_girl));

		//显示超女结构体成员的值
		cout << "bh=" << girl.bh << ",name=" << girl.name << ",yz=" << girl.yz << ",weigh="
			<< girl.weight << ",memo=" << girl.memo << endl;
	}
}

vector容器

创建一个空的vector

vector<int> v;

创建一个大小为n的数组

vector<int>v(n);

想容器v中尾部追加一个元素a

v.push_back(a);

迭代器

迭代器是访问容器中元素的通用方法。
如果使用迭代器,不同的容器,访问元素的方法是相同的。
迭代器支持的基本操作:赋值(=)、解引用(*)、比较(==和!=)、从左向右遍历(++)
一般情况下,迭代器是指针和移动指针的方法。

迭代器有五种:

  1. 正向迭代器
    只能使用++运算符来遍历容器,每次沿容器向右移动一个元素。
    容器名<元素类型>:.iterator 迭代器名;//正向迭代器。 
    容器名<元素类型>::const_iterator迭代器名;//常正向迭代器。
    
    相关函数:
    iterator begin();
    const_iterator begin();
    const_iterator cbegin();//配合auto使用。
    iterator end();
    const_iterator end();
    const_iterator cend();
    
    例如:
    #define _CRT_SECUER_NO_WARNINGS
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    using namespace std;
    
    int main() {
    	vector<int>vv = { 1,2,3,4,5 };
    	vector<int>::iterator it1 = vv.begin();
    	*it1 = 8;//将修改容器中第0个元素
    	it1++;//迭代器后移一个元素
    	*it1 = 7;//将修改容器中第一个元素
    	for (auto it2 = vv.cbegin();it2 != vv.end();it2++) {
    		cout << *it2 << endl;
    	}
    	cout << endl;
    	for (auto x : vv) {
    		cout << x << endl;
    	}
    }
    
  2. 双向迭代器
    具备正向迭代器的功能,还可以反向(从右到左)遍历容器(也是用++),不管是正向还是反向遍历,都可以用--让迭代器后退一个元素。
    容器名<元素类型>::reverse_iterator 迭代器名;//反向迭代器。
    容器名<元素类型>::const_reverse_iterator 迭代器名;//常反向迭代器。
    
    在这里插入图片描述
  3. 随机访问迭代器
    具备双向迭代器的功能,还支持以下操作:
    • 用于比较两个迭代器相对位置的关系运算(<、<=、>、>=)。
    • 迭代器和一个整数值的加减法运算(+、+=、-、-=)。
    • 支持下标运算(iter[n])。
      数组的指针是纯天然的随机访问迭代器.

我们来看vector中那些操作需要迭代器:

  1. 构造函数
    #define _CRT_SECUER_NO_WARNINGS
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    using namespace std;
    
    int main() {
    	vector<int> v1 = { 1,2,3,4,5,6,7,8,9,10 };
    	vector<int> v2(v1.cbegin() + 2, v1.cend() - 3);
    
    	for (auto x : v2) {
    		cout << x << endl;
    	}
    }
    
  2. 插入函数v.insert(iterator pos,const T& value);
    #define _CRT_SECUER_NO_WARNINGS
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    using namespace std;
    
    int main() {
    	vector<int> v = { 1,2,3,4,5,6,7,8,9,10 };
    	auto iter = v.insert(v.begin() + 5, 13);
    	cout << "新插入的元素是:" << *iter << endl;
    
    	for (auto x : v) {
    		cout << x << endl;
    	}
    }
    

基于范围的for循环

对于一个有范围的集合来说,在程序代码中指定循环的范围有时候是多余的,还可能犯错误。C++11中引入了基于范围的for循环。
语法:

for(迭代的变量: 迭代的范围)
{
	//循环体
}
#define _CRT_SECUER_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;

int main() {
	vector<int> vv = { 1,2,3,4,5,6,7,8,9,10 };
	for (auto it = vv.begin();it != vv.end();it++) {
		cout << *it << " ";
	}
	cout << endl;
	for (int x : vv) {
		cout << x << " " ;
	}
	cout << endl;
}

注意:

  1. 迭代的范围可以是数组名、容器名、初始化列表或者可迭代的对象(支持begin()、 end()、++、==) 。
  2. 数组名传入函数后,已退化成指针,不能作为容器名。
  3. 如果容器中的元素是结构体和类,迭代器变量应该申明为引用,加const约束表示只读。
  4. 注意迭代器失效的问题。
#define _CRT_SECUER_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;

class AA {
public:
	string m_name;
	AA() { cout << "默认构造函数AA()\n"; }
	AA(const string& name) : m_name(name) { cout << "构造函数,name=" << m_name << "。\n" ;}
	AA(const AA& a) : m_name(a.m_name) { cout<<"拷贝构造函数,name = " <<m_name << "。\n ";}
	AA& operator=(const AA& a) {m_name = a.m_name; cout << "赋值函数,n_name=" << m_name << ".\n";}
	~AA() { cout << "析构函数,name=" << m_name << "。\n";}

};
int main() {
	vector<AA>v;
	v.emplace_back("西施");
	v.emplace_back("冰冰");
	v.emplace_back("幂幂");
	for (const auto &a : v) {
		cout << a.m_name << endl;
	}
	cout << endl;
}

list容器

list容器封装了双链表。
包含头文件: #include<list>
list类模板的声明:

template<class T, class Alloc = allocator<T> >
class list{
private:
	iterator head;
	iterator tail;
	.....
}

list的构造函数有很多:

  1. list();//创建一个空的list容器。
  2. list(initializer_list<T> il);//使用统一初始化列表。
  3. list(const list<T>& v);//拷贝构造函数。
  4. list(Iterator first, Iterator last);//用迭代器创建list容器。
  5. list(list<T>&& v);//移动构造函数(C++11标准)。
#define _CRT_SECUER_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<list>
using namespace std;
int main() {
	//1)list()//创建一个空的list容器
	list<int>l1;
	cout << "li.size()=" << l1.size() << endl;
	
	
	// 2)list(initializer_list<T> il);//使用统一初始化列表。
	list<int> l2({1,2,3,4,5,6,7,8,9,10 });
	//list<int> 12={1,2,3,4,5,6,7,8,9,10 };
	//list<int> l2{ 1,2,3,4,5,6,7,8,9,10 };
	for (int value : l2)//用基于范围的for循环遍历容器。
		cout << value << " ";
	cout << endl;

	//3)list(const list<T>& v);//拷贝构造函数。
	//list<int> l3(12);
	list<int> l3 = l2;
	for (int value : l3)
		cout << value << " ";
	
	cout << endl;

	//4)list(Iterator first, Iterator last);//用迭代器创建list容器。
	list<int> l4(l2.begin() , l2.end() );//用list容器的迭代器。
	for (int value : l4)
		cout << value << " ";
		
	cout << endl;

	vector < int> v1 = { 1,2,3,4,5,6,7,8,9,10 };//创建vector容器。
	list<int> l5(v1.begin() + 2, v1.end() - 3); //用vector容器的迭代器创建list容器。
	
	for (int value : l5)
		cout << value << " ";
	
	cout << endl;

	int a1[] = {1,2,3,4,5,6,7,8,9,10};//创建数组。
	list<int> l6(a1 + 2, a1 + 10 - 3); // 用数组的指针作为迭代器创建list容器。
	for(int value : l6)
		cout << value << " ";
	
	cout << endl;

}

list的元素操作

T &front();//第一个元素。
const T &front);// 第一个元素,只读。
const T &back();//最后一个元素,只读。
T &back();//最后一个元素。

list的交换,反转,排序,归并

void swap(list<T> &l);//把当前的容器于I交换,交换的是链表节点的地址
void reverse();//反转链表
void sort();//升序排序
void sort(_Pr2_Pred);//排序方法由Pred决定
void merge(list<T> &l)//合并两个已排序的list,

#define _CRT_SECUER_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<list>
using namespace std;
int main() {
	list<int> la = { 8,2,6,4,5 };
	for (auto& val : la) {
		cout << val << " ";
	}
	cout << endl;
	la.reverse();//反转
	for (auto& val : la) {
		cout << val << " ";
	}
	cout << endl;
	la.sort();//排序
	
	list<int>lb = { 3,7,9,10,1 };
	lb.sort();
	la.merge(lb);
	
	for (auto& val : la) {
		cout << val << " ";
	}
	cout << endl;

}

插入和删除操作

  1. void push_back(const T& value);//在链表的尾部追加一个元素。
  2. void emplace_back(...);//在链表的尾部追加一个元素,…用于构造元素。
  3. iterator insert(iterator pos, const T& value);//在指定位置插入一个元素,返回指向插入元素的迭代器。
  4. iterator emplace (iterator pos,....);//在指定位置插入一个元素,…用于构造元素,返回指向插入元素的迭代器。
  5. iterator insert(iterator pos, iterator first, iterator last);//在指定位置插入一个区间的元素,返回指向第一个插入元素的迭代器。
  6. void pop_back();//从链表尾部删除一个元素。
  7. iterator erase(iterator pos);//删除指定位置的元素,返回下一个有效的迭代器。
  8. iterator erase(iterator first, iterator last);//删除指定区间的元素,返回下一个有效的迭代器。
  9. push_front(const T& value);//在链表的头部插入一个元素。
  10. emplace_front(...);//在链表的头部插入一个元素,.….用于构造元素。
  11. splice(iterator pos,const vector<T> &l);//把另一个链表连接到当前链表。
  12. splice(iterator pos, const vector<T>&l, iterator first, iterator last);//把另一个链表指定的区间连接到当前链表。
  13. splice(iterator pos, const vector<T> & l, iterator first);//把另一个链表从first开始的结点连接到当前链表。
  14. void remove(value);//删除链表中所有等于value的元素。
  15. void remove_if(_Pr1 _Pred);//删除链表中满足条件的元素,参数_Pred是一元函数。
  16. void unique();//删除链表中相邻的重复元素,只保留一个。

pair键值对

pair是类模板,一般用于表示 key/value数据,其实现是结构体。pair结构模板的定义如下:

template <class T1, class T2>
struct pair
{
	T1 first;//第一个成员,一般表示 key。 
	T2 second;//第二个成员,一般表value。
	pair();//默认构造函数。	
	pair(const T1 &val1,const T2 &val2);//有两个参数的构造函数。
	pair(const pair<T1,T2> &p);//拷贝构造函数。
	void swap(pair<T1,T2> &p);//交换两个pair。
}
#define _CRT_SECUER_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<list>
using namespace std;
int main() {
	pair<int, string>p0;
	cout << "p0 first=" << p0.first << ",second=" << p0.second << endl;

	pair<int, string>p1(1,"西施");
	cout << "p1 first=" << p1.first << ",second=" << p1.second << endl;
	
	struct st_girl {
		string name;
		int age;
		double height;
	};
	pair<int, st_girl>p = { 3,{"西施",23,48.6} };
	cout << "p first=" << p.first << endl;
	cout << "p second.name=" << p.second.name << endl;cout << "p second.age=" << p.second.age << endl;
	cout << "p second.height=" << p.second.height << endl;


}

make_pair函数模板的定义如下:

map容器

map容器封装了红黑树(平衡二叉排序树),用于查找。
包含头文件: #include<map>
map容器的元素是pair 键值对。
map类模板的声明:

template <class K, class V, class P = less<K>, class _Alloc = allocator<pair<const K,V >>>
class map : public _Tree<_Tmap_traits<K, V,P,_Alloc, false> > 
{
	....
}



第一个模板参数K: key的数据类型(pair.first)。
第二个模板参数V: value的数据类型(pair.second)。
第三个模板参数Р:排序方法,缺省按key升序。
第四个模板参数_Alloc:分配器,缺省用new和delete。
map提供了双向迭代器。
二叉链表:

struct BTNode
{
	pair<K,V> p;//键值对。
	BTNode *parent;//父节点。
	BTNode *Ichirld;//左子树。
	BTNode *rchild;//右子树。
};
  1. 构造函数
    map(); //创建一个空的map容器。
    map(initializer_list<pair<K,V> > il); //使用统一初始化列表。
    map(const map<K,V>& m);//拷贝构造函数。
    map(Iterator first, Iterator last);//用迭代器创建map容器。
    map(map<K,V>&& m);!/移动构造函数(C++11标准)。
    
    注意对map容器正向遍历一定会得到一个有序的数列.因为红黑树是二叉排序树.
    #define _CRT_SECUER_NO_WARNINGS
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<list>
    #include<map>
    using namespace std;
    int main() {
    	//1)map();//创建一个空的map
    	map<int, string>m1;
    
    	// 2) map(initializer_list<pair<K, V>> il);//使用统一初始化列表。
    	map<int, string> m2({ {8,"冰冰"},{ 3,"西施"},{1,"幂幂"},{7,"金莲"},{5, "西瓜"} });
    	//map<int, string> m2 = { {8,"冰冰"},{ 3,"西施" },{ 1,"幂幂" },{7, "金莲" },{5,"西瓜"} };
    	//map<int, string> m2{ {8,"冰冰" },{ 3,"西施" },{1,"幂幂" },{7, "金莲" },{5,"西瓜" } };
    	for (auto& val : m2) {
    		cout << val.first << "," << val.second << "  ";
    	}
    	cout << endl;
    
    	// 3) map(const map<K, V>&m);//拷贝构造函数。
    	map<int, string> m3 = m2;
    	for (auto& val : m3)
    		cout << val.first << "," << val.second << " ";
    	
    	cout << endl;
    
    
    	//4) map(Iterator first, Iterator last);//用迭代器创建map容器。
    	auto first = m3.begin(); first++;
    	auto last = m3.end(); last--;
    	map<int, string> m4(first, last);
    	for (auto& val : m4)
    		cout << val.first << "," << val.second << " ";
    	
    	cout << endl;
    
    
    }
    
  2. 插入操作
    #define _CRT_SECUER_NO_WARNINGS
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<list>
    #include<map>
    using namespace std;
    int main() {
    	map<int, string>m;
    	m.insert({ {8,"冰冰"}, {3,"西施"} });
    	m.insert({ pair<int,string>(1,"幂幂"),make_pair<int,string>(7,"金莲"),{5,"西瓜"} });
    	m.insert({ {18,"冰冰"},{3,"西施"} });
    	 
    	for (auto& val : m)
    		cout << val.first << "," << val.second << " ";
    	
    	cout << endl;
    
    
    
    }
    

哈希表

unordered_map容器

queue

queue容器的逻辑结构是队列,物理结构可以是数组或链表,主要用于多线程之间的数据共享。
包含头文件: #include<queue>
queue类模板的声明:

template <class T, class _Container = deque<T>> class queue{
	....
}

第一个模板参数T:元素的数据类型。
第二个模板参数_Container:底层容器,缺省是std::deque。
queue容器不支持迭代器。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值