C++STL之容器

news2024/11/29 22:47:11

STL的概述

STL(Standard Template Library,标准模板库)
STL的6大组件:容器、算法、迭代器、适配器、仿函数、空间配置
容器:存放数据
算法:操作数据
迭代器:算法 通过迭代器 操作 容器
适配器:为算法 提供更多的接口
仿函数:为算法 提供策略
空间配置:为算法、容器提供动态空间
算法分类:质变算法、非质变算法
质变算法:会更改容器的值( 拷贝,替换,删除等等 )
非质变算法:是指运算过程中不会更改区间内的元素内容,例如查找、计数、遍历、寻
找极值等等

什么是迭代器?

迭代器:算法和容器的桥梁,每一个容

器有着与之对应的迭代器

string容器

1、构造函数以及赋值

、构造函数以及赋值
1 3.1.2.1 string 构造函数
2 string();//创建一个空的字符串 例如: string str;    
3 string(const string& str);//使用一个string对象初始化另一个string对象
4 string(const char* s);//使用字符串s初始化
5 string(int n, char c);//使用n个字符c初始化 v
6 3.1.2.2 string基本赋值操作
7 string& operator=(const char* s);//char*类型字符串 赋值给当前的字符串
8 string& operator=(const string &s);//把字符串s赋给当前的字符串
9 string& operator=(char c);//字符赋值给当前的字符串
10 string& assign(const char *s);//把字符串s赋给当前的字符串
11 string& assign(const char *s, int n);//把字符串s的前n个字符赋给当前的字符串
12 string& assign(const string &s);//把字符串s赋给当前字符串
13 string& assign(int n, char c);//用n个字符c赋给当前字符串
14 string& assign(const string &s, int start, int n);//将s从start开始n个字符
赋值给字符串

代码演示

1 void test01()
2 {
3  string str1("hello world");
4  cout<<str1<<endl;    //hello world
5  string str2(5,'A');
6  cout<<str2<<endl;    //AAAAA
7  string str3 = str2;
8  cout<<str3<<endl;    //AAAAA
9
10  string str4;
11  str4 = "hello world";
12  cout<<str4<<endl;    //hello world
13  str4 = 'W';
14  cout<<str4<<endl;    //W
15
16  str4.assign("hello world", 5);
17  cout<<str4<<endl;    //hello
18  str4.assign(str1, 2, 3); //区间读取,地址,起点,区间
19  cout<<str4<<endl;    //llo
20 }

小结:assign是赋值的意思,常见 

2、string存取字符操作

1 char& operator[ ](int n);//通过[ ]方式取字符
2 char& at(int n);//通过at方法获取字符

1 void test02()
2 {
3  string str1="hello world";
4  cout<<str1[1]<<" "<<str1.at(1)<<endl;
5  str1[1]='E';
6  str1.at(6)='H';
7  cout<<str1<<endl;
8
9  //[] 越界不会抛出异常 at越界会抛出异常
10  try
11  {
12  //str1[1000]='A';
13  str1.at(1000)='A';
14  }
15  catch(exception &e)
16  {
17  cout<<"捕获到异常:"<<e.what()<<endl;
18  }
19 }

3、string拼接操作

1 3.1.2.4
2 string& operator+=(const string& str);//重载+=操作符
3 string& operator+=(const char* str);//重载+=操作符
4 string& operator+=(const char c);//重载+=操作符
5 string& append(const char *s);//把字符串s连接到当前字符串结尾
6 string& append(const char *s, int n);//把字符串s的前n个字符连接到当前字符串
结尾
7 string& append(const string &s);//同operator+=()
8 string& append(const string &s, int pos, int n);//把字符串s中从pos开始的n个
字符连接到当前字符串结尾
9 string& append(int n, char c);//在当前字符串结尾添加n个字符c
1 void test03()
2 {
3  string str1="hello";
4  str1 += "world";
5  cout<<str1<<endl;
6
7  string str2="hehe";
8  str1 += str2;
9  cout<<str1<<endl;
10
11  string str3="hello";
12  string str4="world";
13  cout<<str3+str4<<endl;
14
15  string str5="hello";
16  string str6="world";
17  str5.append(str6, 2, 3);
18  cout<<str5<<endl;
19  str5.append("world", 3);
20  cout<<str5<<endl;
21 }

4、string查找和替换

1int find(const string& str, int pos = 0) const; //查找str第一次出现位置,从p
os开始查找
2 int find(const char* s, int pos = 0) const;  //查找s第一次出现位置,从pos开
始查找
3 int find(const char* s, int pos, int n) const;  //从pos位置查找s的前n个字符
第一次位置
4 int find(const char c, int pos = 0) const;  //查找字符c第一次出现位置
5 int rfind(const string& str, int pos = npos) const;//查找str最后一次位置,从
pos开始查找
6 int rfind(const char* s, int pos = npos) const;//查找s最后一次出现位置,从po
s开始查找
7 int rfind(const char* s, int pos, int n) const;//从pos查找s的前n个字符最后
一次位置
8 int rfind(const char c, int pos = 0) const; //查找字符c最后一次出现位置
9 string& replace(int pos, int n, const string& str); //替换从pos开始n个字符
为字符串str
10 string& replace(int pos, int n, const char* s); //替换从pos开始的n个字符为
字符串s

5、string比较操作

1  > < == != 运算符 可用
2 /*
3 compare函数在>时返回 1,<时返回 ‐1,==时返回 0。
4 比较区分大小写,比较时参考字典顺序,排越前面的越小。
5 大写的A比小写的a小。
6 */
7 int compare(const string &s) const;//与字符串s比较
8 int compare(const char *s) const;//与字符串s比较

6、提取string子串

1 string substr(int pos = 0, int n = npos) const;//返回由pos开始的n个字符组成
的字符串

1 void test06()
2 {
3  string str1="hehehe:hahaha:xixixi:lalala";
4  int pos = 0;
5  while(1)
6  {
7  int ret = str1.find(":", pos);
8  if(ret < 0)
9  {
10  string tmp = str1.substr(pos, str1.size()‐pos);
11  cout<<tmp<<endl;
12  break;
13  }
14
15  string tmp = str1.substr(pos, ret‐pos);
16  cout<<tmp<<endl;
17
18  pos = ret+1;
19  }
20 }

7、string插入和删除操作

1 string& insert(int pos, const char* s); //插入字符串
2 string& insert(int pos, const string& str); //插入字符串
3 string& insert(int pos, int n, char c);//在指定位置插入n个字符c
4 string& erase(int pos, int n = npos);//删除从Pos开始的n个字符

8、 string和c-style字符串转换

vector容器

1、vector的概述

vector容器:单端动态数组容器

push_back尾部插入元素、pop_back尾部删除元素
front()头元素、back()尾元素
begin()得到的是  容器的 起始迭代器(首元素的位置)
end() 得到的是 结束迭代器(尾元素的下一个元素位置)
必须包含头文件:#include<vector>

1 #include <iostream>
2 #include <vector>
3 using namespace std;
4 void test01()
5 {
6  vector<int> v1;
7  v1.push_back(10);
8  v1.push_back(30);
9  v1.push_back(50);
10  v1.push_back(20);
11  v1.push_back(40);
12
13  //遍历容器
14  //定义一个迭代器iterator 保存是元素的位置
15  vector<int>::iterator it=v1.begin();
16  for(;it!=v1.end(); it++)
17  {
18  //*it == int
19  cout<<*it<<" ";
20  }
21  cout<<endl;
22 }
23
24 int main(int argc, char *argv[])
25 {
26  test01();
27  return 0;
28 }

vector的未雨绸缪机制:

1 void test01()
2 {
3  vector<int> v1;
4  cout<<"容量:"<<v1.capacity()<<" 大小:"<<v1.size()<<endl;
5  vector<int>::iterator it;
6  int i=0;
7  int count = 0;
8  for(i=1;i<=1000;i++)
9  {
10  v1.push_back(1);
11  if(it != v1.begin())
12  {
13  count++;
14  cout<<"第"<<count<<"次开辟空间,容量为:"<<v1.capacity()<<endl;
15  it=v1.begin();
16  }
17  }
18 }

2、vector API

1 3.2.4.1 vector构造函数
2 vector<T> v; //采用模板实现类实现,默认构造函数
3 vector(v.begin(), v.end());//将v[begin(), end())区间中的元素拷贝给本身。
4 vector(n, elem);//构造函数将n个elem拷贝给本身。
5 vector(const vector &vec);//拷贝构造函数。
6
7 //例子 使用第二个构造函数 我们可以...
8 int arr[] = {2,3,4,1,9};
9 vector<int> v1(arr, arr + sizeof(arr) / sizeof(int));
10 3.2.4.2 vector常用赋值操作
11 assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
12 assign(n, elem);//将n个elem拷贝赋值给本身。
13 vector& operator=(const vector  &vec);//重载等号操作符
14 swap(vec);// 将vec与本身的元素互换。
15 3.2.4.3 vector大小操作
16 size();//返回容器中元素的个数
17 empty();//判断容器是否为空
18 resize(int num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。
如果容器变短,则末尾超出容器长度的元素被删除。
19 resize(int num, elem);//重新指定容器的长度为num,若容器变长,则以elem值填充新
位置。如果容器变短,则末尾超出容器长>度的元素被删除。
20 capacity();//容器的容量
21 reserve(int len);//容器预留len个元素长度,预留位置不初始化,元素不可访问。
22 3.2.4.4 vector数据存取操作
23 at(int idx); //返回索引idx所指的数据,如果idx越界,抛出out_of_range异常。
24 operator[];//返回索引idx所指的数据,越界时,运行直接报错
25 front();//返回容器中第一个数据元素
26 back();//返回容器中最后一个数据元素
27 3.2.4.5 vector插入和删除操作
28 insert(const_iterator pos, int count,ele);//迭代器指向位置pos插入count个元
素ele.
29 push_back(ele); //尾部插入元素ele
30 pop_back();//删除最后一个元素
31 erase(const_iterator start, const_iterator end);//删除迭代器从start到end之
间的元素
32 erase(const_iterator pos);//删除迭代器指向的元素
33 clear();
1 #include <iostream>
2 #include <vector>
3 using namespace std;
4 void test01()
5 {
6  vector<int> v1;
7  v1.reserve(1000);//预留空间
8
9  cout<<"容量:"<<v1.capacity()<<" 大小:"<<v1.size()<<endl;
10  vector<int>::iterator it;
11  int i=0;
12  int count = 0;
13  for(i=1;i<=1000;i++)
14  {
15  v1.push_back(1);
16  if(it != v1.begin())
17  {
18  count++;
19  cout<<"第"<<count<<"次开辟空间,容量为:"<<v1.capacity()<<endl;
20  it=v1.begin();
21  }
22  }
23 }
24 void printVectorInt(vector<int> &v)
25 {
26  vector<int>::iterator it;
27  for(it=v.begin(); it!=v.end();it++)
28  {
29  cout<<*it<<" ";
30  }
31  cout<<endl;
32 }
33
34 void test02()
35 {
36  vector<int> v1(5,100);
37  printVectorInt(v1);
38
39  vector<int> v2 = v1;
40  printVectorInt(v2);
41
42  vector<int> v3(v1.begin(), v1.end());
43  printVectorInt(v3);
44
45  vector<int> v4;
46 // v4 = v3;
47  v4.assign(10,10);
48  printVectorInt(v4);
49
50  //交换
51  v3.swap(v4);
52  printVectorInt(v3);
53  printVectorInt(v4);
54
55  cout<<"大小:"<<v4.size()<<" 容量:"<<v4.capacity()<<endl;
56  //容器是否为空
57  vector<int> v5;
58  if(v5.empty())
59  {
60  cout<<"空"<<endl;
61  }
62  else
63  {
64  cout<<"非空"<<endl;
65  }
66
67  vector<int> v6(10, 30);
68  cout<<"大小:"<<v6.size()<<" 容量:"<<v6.capacity()<<endl;
69  printVectorInt(v6);
70  //v6.resize(20);//过大补0
71  //v6.resize(20, 50);//过大补50
72  v6.resize(32);
73  cout<<"大小:"<<v6.size()<<" 容量:"<<v6.capacity()<<endl;
74  printVectorInt(v6);
75 }
76
77 int main(int argc, char *argv[])
78 {
79  test01();
80  return 0;
81 }
1 void test03()
2 {
3  vector<int> v1;
4  v1.push_back(10);
5  v1.push_back(20);
6  v1.push_back(30);
7  v1.push_back(40);
8  v1.push_back(50);
9
10  cout<<"头元素:"<<v1.front()<<" 尾元素:"<<v1.back()<<endl;
11  //at越界抛出异常 【】越界不会抛出异常
12  cout<<v1.at(1)<<" "<<v1[1]<<endl;
13  v1.at(1)=200;
14  v1[3]=300;
15  printVectorInt(v1);//10 200 30 300 50
16
17  v1.pop_back();//尾删
18  printVectorInt(v1);//10 200 30 300
19  v1.insert( v1.begin()+2, 3, 500 );
20  printVectorInt(v1);//10 200 500 500 500 30 300
21  v1.erase(v1.begin()+2, v1.begin()+5 );
22  printVectorInt(v1);//10 200 30 300
23  v1.clear();
24  cout<<"大小:"<<v1.size()<<" 容量:"<<v1.capacity()<<endl;
25 }

3、巧用swap收缩空间

1 void test04()
2 {
3  vector<int> v1;
4  v1.reserve(1000);
5  v1.assign(5,100);
6  cout<<"大小:"<<v1.size()<<" 容量:"<<v1.capacity()<<endl;
7  //v1.resize(3);
8  vector<int>(v1).swap(v1);
9  cout<<"大小:"<<v1.size()<<" 容量:"<<v1.capacity()<<endl;
10 }

4、vector容器 嵌套 容器

1 void test05()
2 {
3  vector<int> v1(5,10);
4  vector<int> v2(5,100);
5  vector<int> v3(5,1000);
6
7  //需求:定义一个容器 存放v1 v2 v3
8  vector< vector<int> > v;
9  v.push_back(v1);
10  v.push_back(v2);
11  v.push_back(v3);
12
13  //遍历
14  vector< vector<int> >::iterator it;
15  for(it=v.begin(); it!=v.end(); it++)
16  {
17  //*it == vector<int>
18  vector<int>::iterator mit;
19  for(mit=(*it).begin();mit!=(*it).end();mit++ )
20  {
21  //*mit == int
22  cout<<*mit<<" ";
23  }
24  cout<<endl;
25  }
26 }

5、使用算法 对 vector容器排序

1 #include<algorithm>//算法头文件
2 bool myCompare(int value1, int value2)
3 {
4  return value1<value2;
5 }
6 void test06()
7 {
8  vector<int> v1;
9  v1.push_back(20);
10  v1.push_back(60);
11  v1.push_back(30);
12  v1.push_back(50);
13  v1.push_back(40);
14  v1.push_back(10);
15  printVectorInt(v1);
16
17  //sort算法排序
18  sort(v1.begin(), v1.end());
19  //sort(v1.begin(), v1.end(), greater<int>());
20  //sort(v1.begin(), v1.end(), myCompare);
21  printVectorInt(v1);
22 }

6、vector存放自定义数据类型

1 class Person
2 {
3  friend void printVectorPerson(vector<Person> &v);
4  friend bool myComparePerson(const Person &ob1, const Person &ob2);
5 private:
6  int num;
7  string name;
8  float score;
9 public:
10  Person(){}
11  Person(int num, string name, float score)
12  {
13  this‐>num = num;
14  this‐>name = name;
15  this‐>score = score;
16  }
17 #if 0
18  //方法2:重载自定义数据的<运算符
19  bool operator<(const Person &ob)
20  {
21  return this‐>num < ob.num;
22  }
23 #endif
24 };
25 void printVectorPerson(vector<Person> &v)
26 {
27  vector<Person>::iterator it;
28  for(it=v.begin(); it!=v.end(); it++)
29  {
30  //*it == Person
31  cout<<(*it).num<<" "<<(*it).name<<" "<<(*it).score<<endl;
32  }
33 }
34 //方法1:对于自定义容器排序 必须实现 排序规则
35 bool myComparePerson(const Person &ob1, const Person &ob2)
36 {
37  if(ob1.num == ob2.num)
38  return ob1.score<ob2.score;
39  return ob1.num > ob2.num;
40 }
41
42 void test07()
43 {
44  vector<Person> v;
45
46  v.push_back(Person(100, "lucy", 88.8f));
47  v.push_back(Person(103, "bob", 99.8f));
48  v.push_back(Person(103, "tom", 77.8f));
49  v.push_back(Person(103, "德玛", 88.8f));
50  v.push_back(Person(101, "小法", 66.8f));
51
52  printVectorPerson(v);
53  //方法1:对于自定义容器排序 必须实现 排序规则
54  sort(v.begin(), v.end(), myComparePerson);
55  //方法2:重载自定义数据的<运算符
56  //sort(v.begin(), v.end());
57  cout<<"‐‐‐‐‐‐‐‐‐‐‐‐‐‐"<<endl;
58  printVectorPerson(v);
59 }

deque容器

1、deque概述

deque:双端动态数组

Deque容器和vector容器最大的差异,
一在于deque允许使用常数项时间对头端进行元素的插入和删除操作。
二在于deque没有容量的概念。

2、deque的API

引入,什么是随机访问迭代器

如果迭代器能+1 那么该迭代器 为随机访问迭代器

1 3.3.3.1 deque构造函数
2 deque<T> deqT;//默认构造形式
3 deque(beg, end);//构造函数将[beg, end)区间中的元素拷贝给本身。
4 deque(n, elem);//构造函数将n个elem拷贝给本身。
5 deque(const deque &deq);//拷贝构造函数。
6 3.3.3.2 deque赋值操作
7 assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
8 assign(n, elem);//将n个elem拷贝赋值给本身。
9 deque& operator=(const deque &deq); //重载等号操作符
10 swap(deq);// 将deq与本身的元素互换
11 3.3.3.3 deque大小操作
12 deque.size();//返回容器中元素的个数
13 deque.empty();//判断容器是否为空
14 deque.resize(num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位
置。如果容器变短,则末尾超出容器长度的元素被删除。
15 deque.resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填
充新位置,如果容器变短,则末尾超出容器长度的元素被删除。
16 3.3.3.4 deque双端插入和删除操作
17 push_back(elem);//在容器尾部添加一个数据
18 push_front(elem);//在容器头部插入一个数据
19 pop_back();//删除容器最后一个数据
20 pop_front();//删除容器第一个数据
21 3.3.3.5 deque数据存取
22 at(idx);//返回索引idx所指的数据,如果idx越界,抛出out_of_range。
23 operator[];//返回索引idx所指的数据,如果idx越界,不抛出异常,直接出错。
24 front();//返回第一个数据。
25 back();//返回最后一个数据
26 3.3.3.6 deque插入操作
27 insert(pos,elem);//在pos位置插入一个elem元素的拷贝,返回新数据的位置。
28 insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值。
29 insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值。
30 3.3.3.7 deque删除操作
31 clear();//移除容器的所有数据
32 erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
33 erase(pos);//删除pos位置的数据,返回下一个数据的位置

案例

1 #include <iostream>
2 #include <deque>
3 using namespace std;
4 void printfDequeInt(deque<int> &d)
5 {
6  deque<int>::iterator it;
7  for(it=d.begin(); it!=d.end();it++)
8  {
9  cout<<*it<<" ";
10  }
11  cout<<endl;
12 }
13
14 void test01()
15 {
16  deque<int> d1;
17  d1.push_back(1);
18  d1.push_back(2);
19  d1.push_back(3);
20  d1.push_front(4);
21  d1.push_front(5);
22  d1.push_front(6);
23  printfDequeInt(d1);//6 5 4 1 2 3
24
25  cout<<"大小:"<<d1.size()<<endl;
26  d1.pop_front();
27  printfDequeInt(d1);//5 4 1 2 3
28  d1.pop_back();
29  printfDequeInt(d1);//5 4 1 2
30  d1.insert(d1.begin()+1,3, 100);
31  printfDequeInt(d1);//5 100 100 100 4 1 2
32 }
33
34 int main(int argc, char *argv[])
35 {
36  test01();
37  return 0;
38 }

3、deque容器的案例

vector存放的数据 没有多大的规律  只是纪录数据。
deque容器:用于类似竞技的数据
    有5名选手:选手ABCDE,10个评委分别对每一名选手打分,去除最高分,去除评委中
最低分,取平均分。
    1. 创建五名选手,放到vector中
    2. 遍历vector容器,取出来每一个选手,执行for循环,可以把10个评分打分存到deque
容器中
    3. sort算法对deque容器中分数排序,pop_back pop_front去除最高和最低分
    4. deque容器遍历一遍,累加分数,累加分数/d.size()
    5. person.score = 平均分

1 #include<vector>
2 class Player
3 {
4 public:
5  string name;
6  float score;
7 public:
8  Player(){}
9  Player(string name,float score=0.0f)
10  {
11  this‐>name = name;
12  this‐>score=score;
13  }
14 };
15 void createPlayer(vector<Player> &v)
16 {
17  string seedName = "ABCDE";
18  int i=0;
19  for(i=0;i<5;i++)
20  {
21  string tmpName = "选手";
22  tmpName+=seedName[i];
23
24  v.push_back(Player(tmpName));
25  }
26 }
27 #include<stdlib.h>
28 #include<time.h>
29 #include<algorithm>
30 void playGame(vector<Player> &v)
31 {
32  //设置随机数 种子
33  srand(time(NULL));
34  //每名选手都要参加
35  vector<Player>::iterator it;
36  for(it=v.begin(); it!=v.end();it++)
37  {
38  //10个评委打分
39  deque<float> d;
40  int i=0;
41  for(i=0;i<10;i++)
42  {
43  d.push_back(rand()%41+60);
44  }
45
46  // 对d容器排序
47  sort(d.begin(),d.end());
48
49  //去掉最高分
50  d.pop_back();
51  //去掉最低分
52  d.pop_front();
53
54  //求总分数
55  (*it).score = accumulate(d.begin(),d.end(), 0)/d.size();
56  }
57 }
58 void showScore(vector<Player> &v)
59 {
60  vector<Player>::iterator it;
61  for(it=v.begin(); it!=v.end();it++)
62  {
63  cout<<(*it).name<<"所得分数:"<<(*it).score<<endl;
64  }
65 }
66 void test02()
67 {
68  //创建5名选手 放入vector容器中
69  vector<Player> v;
70  createPlayer(v);
71
72  //开始比赛
73  playGame(v);
74
75  //公布成绩
76  showScore(v);
77 }

小结,存放Person类的时候,常用Vector来存,然后Person之间的关系(隶属于那个部门)再用Deque或者Map来存

stack栈容器

stack是一种先进后出(First In Last Out,FILO)的数据结构。

操作数据的一端 叫栈顶。
top永远指向栈顶元素。
栈容器没有迭代器。不支持遍历行为。

1 3.4.3.1 stack构造函数
2 stack<T> stkT;//stack采用模板类实现, stack对象的默认构造形式:
3 stack(const stack &stk);//拷贝构造函数
4 3.4.3.2 stack赋值操作
5 stack& operator=(const stack &stk);//重载等号操作符
6 3.4.3.3 stack数据存取操作
7 push(elem);//向栈顶添加元素
8 pop();//从栈顶移除第一个元素
9 top();//返回栈顶元素
10 3.4.3.4 stack大小操作
11 empty();//判断堆栈是否为空
12 size();//返回堆栈的大小

queue队列容器

Queue是一种先进先出(First In First Out,FIFO)的数据结构

出数据的一方叫队头,入数据的一方叫队尾。
queue容器没有迭代器 不支持遍历行为。

1 queue<T> queT;//queue采用模板类实现,queue对象的默认构造形式:
2 queue(const queue &que);//拷贝构造函数
3 3.5.3.2 queue存取、插入和删除操作
4 push(elem);//往队尾添加元素
5 pop();//从队头移除第一个元素
6 back();//返回最后一个元素
7 front();//返回第一个元素
8 3.5.3.3 queue赋值操作
9 queue& operator=(const queue &que);//重载等号操作符
10 3.5.3.4 queue大小操作
11 empty();//判断队列是否为空
12 size();//返回队列的大小

list链表容器

list是双向循环链表

list容器的迭代器是 双向迭代器。

1 3.6.4.1 list构造函数
2 list<T> lstT;//list采用采用模板类实现,对象的默认构造形式:
3 list(beg,end);//构造函数将[beg, end)区间中的元素拷贝给本身。
4 list(n,elem);//构造函数将n个elem拷贝给本身。
5 list(const list &lst);//拷贝构造函数。
6 3.6.4.2 list数据元素插入和删除操作
7 push_back(elem);//在容器尾部加入一个元素
8 pop_back();//删除容器中最后一个元素
9 push_front(elem);//在容器开头插入一个元素
10 pop_front();//从容器开头移除第一个元素
11 insert(pos,elem);//在pos位置插elem元素的拷贝,返回新数据的位置。
12 insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值。
13 insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值。
14 clear();//移除容器的所有数据
15 erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
16 erase(pos);//删除pos位置的数据,返回下一个数据的位置。
17 remove(elem);//删除容器中所有与elem值匹配的元素。
18 3.6.4.3 list大小操作
19 size();//返回容器中元素的个数
20 empty();//判断容器是否为空
21 resize(num);//重新指定容器的长度为num,
22 若容器变长,则以默认值填充新位置。
23 如果容器变短,则末尾超出容器长度的元素被删除。
24 resize(num, elem);//重新指定容器的长度为num,
25 若容器变长,则以elem值填充新位置。
26 如果容器变短,则末尾超出容器长度的元素被删除。
27 3.6.4.4 list赋值操作
28 assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
29 assign(n, elem);//将n个elem拷贝赋值给本身。
30 list& operator=(const list &lst);//重载等号操作符
31 swap(lst);//将lst与本身的元素互换。
32 3.6.4.5 list数据的存取
33 front();//返回第一个元素。
34 back();//返回最后一个元素。
35 3.6.4.6 list反转排序
36 reverse();//反转链表,比如lst包含1,3,5元素,运行此方法后,lst就包含5,3,1元
素。
37 sort(); //list排序
1 #include <iostream>
2 #include <list>
3 #include <algorithm>
4 using namespace std;
5 void printListInt(list<int> &l)
6 {
7  list<int>::iterator it;
8  for(it=l.begin(); it!=l.end();it++)
9  {
10  cout<<*it<<" ";
11  }
12  cout<<endl;
13 }
14
15 void test01()
16 {
17  list<int> l1;
18  l1.push_back(10);
19  l1.push_back(20);
20  l1.push_back(30);
21  l1.push_front(40);
22  l1.push_front(50);
23  l1.push_front(60);
24
25  printListInt(l1);//60 50 40 10 20 30
26  //list容器 是双向迭代器 不支持+2 支持++
27  list<int>::iterator it=l1.begin();
28  it++;
29  it++;
30  l1.insert(it, 3, 100);
31  printListInt(l1);//60 50 100 100 100 40 10 20 30
32
33  //删除所有100
34  l1.remove(100);
35  printListInt(l1);//60 50 40 10 20 30
36
37  //对链表排序
38  //STL提供的算法 只支持 随机访问迭代器,而list是双向迭代器 所以sort不支持list
39 // l1.sort(greater<int>());
40  l1.sort();
41  printListInt(l1);//10 20 30 40 50 60
42 }
43
44 int main(int argc, char *argv[])
45 {
46  test01();
47  return 0;
48 }

set容器

1、set容器概述

但是set容器 只有键值,在插入数据的时候 自动根据 键值 排序。不允许有相同的键值。不
能修改set容器的元素值,会破坏set的数据结构。set容器的迭代器是只读迭代器( const_iterator )。

1 3.7.2.1 set构造函数
2 set<T> st;//set默认构造函数:
3 mulitset<T> mst; //multiset默认构造函数:
4 set(const set &st);//拷贝构造函数
5 3.7.2.2 set赋值操作
6 set& operator=(const set &st);//重载等号操作符
7 swap(st);//交换两个集合容器
8 3.7.2.3 set大小操作
9 size();//返回容器中元素的数目
10 empty();//判断容器是否为空
11 3.7.2.4 set插入和删除操作
12 insert(elem);//在容器中插入元素。
13 clear();//清除所有元素
14 erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
15 erase(beg, end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
16 erase(elem);//删除容器中值为elem的元素。
17 3.7.2.5 set查找操作
18 find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回se
t.end();
19 count(key);//查找键key的元素个数
20 lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
21 upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
22 equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器
1 #include <iostream>
2 #include<set>
3 using namespace std;
4 void printSetInt(set<int> &s)
5 {
6  set<int>::iterator it;
7  for(it=s.begin(); it!=s.end();it++)
8  {
9  cout<<*it<<" ";
10  }
11  cout<<endl;
12 }
13
14 void test01()
15 {
16  set<int> s1;
17  s1.insert(30);
18  s1.insert(10);
19  s1.insert(20);
20  s1.insert(20);
21  s1.insert(40);
22  printSetInt(s1);
23 }
24
25 int main(int argc, char *argv[])
26 {
27  test01();
28  return 0;
29 }

2、更改set容器的排序规则(定义set容器时 修改)

set<int,排序规则类> s1;

一般都是通过 “仿函数” 修改set容器的排序规则。

1 #include <iostream>
2 #include<set>
3 using namespace std;
4 //仿函数
5 class MyCompare
6 {
7 public:
8  bool operator()(int v1, int v2)
9  {
10  return v1>v2;
11  }
12 };
13 void printSetInt(set<int> &s)
14 {
15  set<int>::iterator it;
16  for(it=s.begin(); it!=s.end();it++)
17  {
18  cout<<*it<<" ";
19  }
20  cout<<endl;
21 }
22
23 void printSetInt(set<int,MyCompare> &s)
24 {
25  set<int,MyCompare>::iterator it;
26  for(it=s.begin(); it!=s.end();it++)
27  {
28  cout<<*it<<" ";
29  }
30  cout<<endl;
31 }
32
33
34 void test01()
35 {
36  set<int,MyCompare> s1;
37  s1.insert(30);
38  s1.insert(10);
39  s1.insert(20);
40  s1.insert(20);
41  s1.insert(40);
42  printSetInt(s1);
43 }
44
45 int main(int argc, char *argv[])
46 {
47  test01();
48  return 0;
49 }

3、set的API

1 void test03()
2 {
3  set<int> s1;
4  s1.insert(10);
5  s1.insert(30);
6  s1.insert(50);
7  s1.insert(70);
8  s1.insert(90);
9  printSetInt(s1);
10
11  set<int>::const_iterator ret;
12  ret = s1.find(50);
13  if(ret != s1.end())
14  {
15  cout<<"找到的结果:"<<*ret<<endl;
16  }
17
18  //count(key);//查找键key的元素个数 set容器的结果只能是0或1
19  cout<<s1.count(50)<<endl;
20 }

4、查找元素的上下限

1 void test04()
2 {
3  set<int> s1;
4  s1.insert(10);
5  s1.insert(30);
6  s1.insert(50);
7  s1.insert(70);
8  s1.insert(90);
9  printSetInt(s1);
10
11  set<int>::const_iterator ret;
12  //lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。(下限)
13  ret = s1.lower_bound(50);
14  if(ret !=s1.end())
15  {
16  cout<<"下限为:"<<*ret<<endl;
17  }
18  //upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器(上限)
19  ret = s1.upper_bound(50);
20  if(ret !=s1.end())
21  {
22  cout<<"上限为:"<<*ret<<endl;
23  }
24  //equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器
25  //返回值类型为pair 对组
26  pair< set<int>::const_iterator, set<int>::const_iterator> p;
27  p = s1.equal_range(50);
28  if(p.first != s1.end())
29  {
30  cout<<"下限为:"<<*(p.first)<<endl;
31  }
32  if(p.second != s1.end())
33  {
34  cout<<"上限为:"<<*(p.second)<<endl;
35  }
36 }

multiset容器

set容器:键值不允许重复
multiset容器:键值可以重复

pair对组

对组(pair)将一对值组合成一个值,这一对值可以具有不同的数据类型,两个值
可以分别用pair的两个公有属性first和second访问

map容器

map容器:每个元素都是 键值-实值 成对存储,自动根据键值排序, 键值不能重复,不能
修改。

1  map构造函数
2 map<T1, T2> mapTT;//map默认构造函数:
3 map(const map &mp);//拷贝构造函数
4 3.8.2.2 map赋值操作
5 map& operator=(const map &mp);//重载等号操作符
6 swap(mp);//交换两个集合容器
7 3.8.2.3 map大小操作
8 size();//返回容器中元素的数目
9 empty();//判断容器是否为空
10 3.8.2.4 map插入数据元素操作
11 map.insert(...); //往容器插入元素,返回pair<iterator,bool>
12 map<int, string> mapStu;
13 // 第一种 通过pair的方式插入对象
14 mapStu.insert(pair<int, string>(3, "小张"));
15 // 第二种 通过pair的方式插入对象
16 mapStu.inset(make_pair(‐1, "校长"));
17 // 第三种 通过value_type的方式插入对象
18 mapStu.insert(map<int, string>::value_type(1, "小李"));
19 // 第四种 通过数组的方式插入值
20 mapStu[3] = "小刘";
21 mapStu[5] = "小王";
22 3.8.2.5 map删除操作
23 clear();//删除所有元素
24 erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
25 erase(beg,end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
26 erase(keyElem);//删除容器中key为keyElem的对组。
27 3.8.2.6 map查找操作
28 find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;/若不存在,返回m
ap.end();
29 count(keyElem);//返回容器中key为keyElem的对组个数。对map来说,要么是0,要么是
1。对multimap来说,值可能大于1。
30 lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
31 upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
32 equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器

案例1:键值的map容器设计

1 #include <iostream>
2 #include <map>
3 using namespace std;
4 class Person
5 {
6  friend void test01();
7  friend void printMapAll(map<int, Person> &m);
8 private:
9  int num;
10  string name;
11  float score;
12 public:
13  Person(){}
14  Person(int num,string name, float score);
15 };
16 void printMapAll(map<int, Person> &m)
17 {
18  map<int, Person>::const_iterator it;
19  for(it=m.begin(); it!=m.end();it++)
20  {
21  //(*it) ==pair<int, Person>
22  cout<<"学号:"<<(*it).first<<" 姓名:"<<(*it).second.name<<" \
23 分数:"<<(*it).second.score<<endl;
24  }
25 }
26
27 void test01()
28 {
29  map<int, Person> m;
30  //方式1:
31  m.insert(pair<int,Person>(103, Person(103,"lucy", 88.8f)));
32  //方式2:推荐
33  m.insert(make_pair(101,Person(101,"bob", 77.7f)));
34  //方式3:
35  m.insert( map<int, Person>::value_type( 102 , Person(102,"tom",
66.6f)));
36  //方式4:
37  m[104] = Person(104,"德玛", 99.9f);
38
39  printMapAll(m);
40
41  //假如key值存在 m[key]代表对应的实值
42  cout<< m[107].num<<" "<<m[107].name<<" "<<m[107].score<<endl;
43
44  cout<<"‐‐‐‐‐‐‐‐‐‐"<<endl;
45  printMapAll(m);
46
47  m.erase(104);
48  cout<<"‐‐‐‐‐‐‐‐‐‐"<<endl;
49  printMapAll(m);
50
51  //查找key为103的数据
52  map<int, Person>::const_iterator ret;
53  ret = m.find(103);
54  if(ret != m.end())
55  {
56  //*ret == pair<int,Person>
57  cout<<(*ret).first<<" "<<(*ret).second.name<<" "
<<(*ret).second.score<<endl;
58  }
59 }
60
61 int main(int argc, char *argv[])
62 {
63  test01();
64  return 0;
65 }
66
67 Person::Person(int num, string name, float score)
68 {
69  this‐>num = num;
70  this‐>name = name;
71  this‐>score = score;
72 }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1432228.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电脑/机顶盒/ps3/4/连接老电视(只有AV、S-Video接口)解决方案之HDMI转AV/S-Video转换器HAV

HDMI转AV/S-Video转换器功能 01、将HDMI高清信号经过视频处理转换成AV、S-VIDEO(PAL/NTSC)的视频信号输出 02、将HDMI数字音频&#xff0c;经过DAC数模芯片处理转成模拟立体声输出 03、采用先进的视频处理技术&#xff0c;对图像的亮度&#xff0c;对比度及色彩进行增强处理 04…

AI重构千行百业!超声波俱乐部大湾区内部分享会圆满落幕

1月27日、28日&#xff0c;超声波俱乐部内部分享会第十六期、第十七期分别在深圳、广州召开&#xff0c;创梦天地、元气森林、新浪智库、百准、A2空间对活动进行了特别支持&#xff0c;六十余名AI领域的创始人和行业嘉宾出席分享会。 出席活动的嘉宾有&#xff1a; 超声波创始…

使用java -jar命令运行jar包提示“错误:找不到或无法加载主类“的问题分析

用maven把普通java项目打包成可运行的jar后&#xff0c;打开cmd用java -jar运行此jar包时报错&#xff1a; 用idea运行该项目则没有问题 。 其实原因很简单&#xff0c;我们忽略了2个细节。 java指令默认在寻找class文件的地址是通过CLASSPATH环境变量中指定的目录中寻找的。我…

数据中心机房建设的痛点:投资与运维之间的博弈

在数字化浪潮的推动下&#xff0c;数据中心机房建设成为企业发展不可或缺的一环。然而&#xff0c;这一过程中存在一系列的痛点&#xff0c;其中投资与运维之间的博弈成为机房建设的重要议题。本文将深入探讨机房系统建设中的投资及运行维护痛点&#xff0c;并提出相关观点和建…

Vulnhub靶机:hacksudo2 (HackDudo)

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.15&#xff09; 靶机&#xff1a;hacksudo2 (HackDudo)&#xff08;10.0.2.44&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://download.vulnh…

最新酒桌小游戏喝酒骰子小程序源码/带流量主

2023最新酒桌小游戏喝酒小程序源码-带流量主&#xff0c;喝酒神器3.6修改增加了广告位&#xff0c;直接上传源码到开发者端即&#xff0c;可通过后改广告代码&#xff0c;然后关闭广告展示提交&#xff0c;通过后打开即可。 流量主ID替换插屏广告位 adunit-29629a7b54a41a8b视频…

假期day3,三种进程间通信代码实现(2024/2/4)

消息队列 #include<myhead.h> struct msgbuf{long mstype;char text[1024]; };#define SIZE (sizeof(struct msgbuf)-sizeof(long))int main(int argc, const char *argv[]) {int pid;//创建key值key_t keyftok("/",a);if(key -1){perror("creat key&quo…

033 三种初始化及内存分析

三种初始化 内存分析 创建数组后存储解析

租号平台源码 支持单独租用或合租使用

(购买本专栏可免费下载栏目内所有资源不受限制,持续发布中,需要注意的是,本专栏为批量下载专用,并无法保证某款源码或者插件绝对可用,介意不要购买) 这是一款租号平台源码,采用常见的租号模式。目前网络上还很少见到此类类型的源码。 平台的主要功能如下: 支持单独…

CTFshow 5——23

借鉴博客 misc5 下载完后&#xff0c;用winhex打开 在最后就可以找到flag misc6 和misc5一样 &#xff08;推测&#xff1a;可能是jpg这种看得见的图片&#xff0c;用winhex&#xff09; misc7 misc8 前置工具安装 这里可以看看见两个png 然后我们在我们的文件夹里面有个…

幻兽帕鲁服务器搭建:专用服务器设置全攻略

玩转幻兽帕鲁服务器&#xff0c;阿里云推出新手0基础一键部署幻兽帕鲁服务器教程&#xff0c;傻瓜式一键部署&#xff0c;3分钟即可成功创建一台Palworld专属服务器&#xff0c;成本仅需26元&#xff0c;阿里云服务器网aliyunfuwuqi.com分享2024年新版基于阿里云搭建幻兽帕鲁服…

使用Java编写HTTP客户端和服务器框架:一场“请求与响应”的舞蹈

在这个网络发达的时代&#xff0c;HTTP协议成为了我们与世界沟通的桥梁。而Java&#xff0c;这个强大的编程语言&#xff0c;给了我们工具去编写自己的HTTP客户端和服务器框架。这就像给了我们一套乐高积木&#xff0c;让我们自由地创造自己的城堡。 首先&#xff0c;我们来谈…

openlayers常用示例

简单说一下吧&#xff0c;最近做了十来天的的openlayers&#xff0c;然后稍微研究了一下&#xff0c;这里总结并做了一些示例给大家分享一下&#xff0c;应该是相对常用的一部分吧&#xff0c;由于做的时间比较短&#xff0c;这里写了十来个示例了&#xff0c;有实际项目用到的…

2024 springboot Mybatis-flex 打包出错

Mybatis-flex官网&#xff1a;快速开始 - MyBatis-Flex 官方网站 从 Mybatis-flex官网获取模板后&#xff0c;加入自己的项目内容想打包确保错&#xff0c;先试试一下方法 这里改成skip的默认是true改成false&#xff0c;再次打包就可以了

leetcode206反转链表|详细算法讲解学习

题目 https://leetcode.cn/problems/reverse-linked-list/ 这道题对于刚开始学习数据结构和算法的人来说有点难&#xff0c;是入门的重要典型题目&#xff1b;但等数据结构入门之后&#xff0c;这就会是一道非常简单的题目了。 算法一&#xff08;算法正确但超出时间限制&am…

C++算法学习心得七.贪心算法(3)

1.根据身高重建队列&#xff08;406题&#xff09; 题目描述&#xff1a; 假设有打乱顺序的一群人站成一个队列&#xff0c;数组 people 表示队列中一些人的属性&#xff08;不一定按顺序&#xff09;。每个 people[i] [hi, ki] 表示第 i 个人的身高为 hi &#xff0c;前面 …

day42_jdbc

今日内容 0 复习昨日 1 JDBC概述 2 JDBC开发步骤 3 完成增删改操作 4 ResultSet 5 登录案例 0 复习昨日 1 写出JQuery,通过获得id获得dom,并给input输入框赋值的语句 $(“#id”).val(“值”) 2 mysql内连接和外连接的区别 内连接只会保留完全符合关联条件的数据 外连接会保留表…

20240203-平常心

我一直强调自己要保持一颗平常心&#xff0c;耐住性子&#xff0c;过好每一刻&#xff0c;做好每一件事情&#xff0c;不断的向自己的目标去推进。就像图中的橙子一样&#xff0c;从刚收到这棵柠檬树的时候&#xff0c;我就在期待结果。 但是柠檬树的哗哗落叶、蔫啦吧唧&#x…

【GAMES101】Lecture 16 蒙特卡洛积分

为了后面要讲的路径追踪&#xff0c;需要讲一下这个蒙特卡洛积分&#xff0c;同时需要回顾一下高等数学中的微积分和概率论与统计学的知识 目录 微积分 概念论与统计 蒙特卡洛积分 微积分 定积分是微积分中的一种重要概念&#xff0c;用于计算函数在一个区间上的总体积、…

性能测试+Jmeter介绍

文章目录 什么是性能测试?性能测试的目的性能测试分类一般性能测试负载测试压力测试大数据量测试配置测试稳定性测试 性能测试术语虚拟用户并发及并发用户数响应时间每秒事务数吞吐量、吞吐率点击率性能计数器资源利用率 性能测试流程测试计划阶段测试设计阶段测试开发阶段测试…