本质:
- string是C++风格的字符串,而string本质上是一个类
string和char 的区别:*
- char* 是一个指针
- string是一个类,类内部封装了char* ,管理这个字符串,是一个char*型的容器
特点:
string类内部封装了很多成员方法
例如:查找find,拷贝copy,删除delete替换replace,插入insert
string管理char*所分配的内存,不用担心复制越界和取值越界等,由类内部进行负责
构造函数原型:
- string(); //创建一个空的字符串 例如:string str;
- string(const char* s); //使用字符串s初始化
- string (const string& str); //使用一个string对象初始化另一个string对象
- string(int n, char c); //使用n个字符c初始化字符串
功能描述:
- 字符串之间的比较
比较方式:
- 字符串比较是按照字符的ASCII码进行对比
如果字符串相同 返回 0
如果第一个字符串大于第二个字符串 返回 1
如果第一个字符串小于第二个字符串 返回 -1
函数原型:
- int compare(const string &s) const;//与字符串s比较
- int compare(const string &s) const;//与字符串s比较
string中单个字符存取方式有两种
- char& operator[](int n) //通过[ ]方式取字符
- char& at(int n) //通过at方法取字符
功能:
- STL中的vector容器的数据结构和数组非常相似,类似于栈,所以称为单端数组
vector与普通数组的区别:
- 不同之处在于数组是静态空间,而vector可以动态扩展
动态扩展:
- 并不是在原空间后再续接新的空间,而是重写开辟出更大的内存空间,然后将原有的数据拷贝到新的空间,同时释放原空间
vector容器中的迭代器是支持随机访问的迭代器
2.2.2 vector构造函数功能描述:创建vector容器
函数原型:
- vector
v; //采用模板实现类实现,默认构造函数 - vector(v.begin(), v.end()) //将v[ begin(), end() )区间中的元素拷贝给对象本身(区间前闭后开)
- vector(n, elem) //构造函数,将n个elem拷贝给本身
- vector(const vector &vec) //拷贝构造函数
注:resize()方法只会改变size不会改变capacity
2.2.5 vector插入和删除 2.2.6 vector数据存取 2.2.7 vector互换容器功能描述:
- 实现两个容器内元素进行互换
函数原型:
- swap(vec); //将vec与本身的元素进行互换
注:互换指的是所有的内容进行互换,包括容器大小和容量
应用:swap收缩内存
#include#include #include #include using namespace std; int main() { //定义一个容器v大小为1000 vector v; for (int i = 0; i < 1000; i++) { v.push_back(i); } cout << "v容器的原大小和容量:"< (v).swap(v); //创建一个匿名对象,利用拷贝构造把容器v赋给匿名对象,然后匿名对象调用swap方法与容器v进行互换 cout << "v的容量为:" << v.capacity() << endl; cout << "v的大小为:" << v.size() << endl; return 0 ; } //输出结果: v容器的原大小和容量: v的容量为:1066 v的大小为:1000 v容器resize后的大小和容量: v的容量为:1066 v的大小为:10 v容器收缩后的大小和容量: v的容量为:10 v的大小为:10
2.2.8 vector预留空间
功能描述:
- 减少vector在动态扩展容量时的扩展次数
获取扩展次数:
#include#include #include #include using namespace std; int main() { vector v; int num = 0; int* p = NULL; //定义一个int*空指针 for (int i = 0; i < 100000; i++) { v.push_back(i); if (p != &v[0]) //如果p的指向不是首元素则说明v又开辟了新的内存 { p = &v[0]; //使p指向首元素 num++; //次数递增 } } cout << num << endl; return 0 ; } //输出结果: 30
函数原型:
- reserve(int len) //容器预留len个元素长度,预留位置不初始化,元素不可访问
功能描述:
- 双端数组,可以对头尾进行插入删除操作
deque与vector区别:
1、vector对于头部的插入删除效率低,数据量越大,效率越低.
2、deque相对而言,对头部的插入删除速度回比vector快
3、vector访问元素时的速度会比deque快,这和两者内部实现有关
2.3.2 deque构造函数 2.3.3 deque赋值操作 2.3.4 deque大小操作与vector的区别是deque在中控器中可增加缓冲区,所有没有容器限制
2.3.5 deque插入删除操作 2.3.6 deque数据存取 2.3.7 deque数据排序默认的排序方式为升序
#include2.4 stack容器 2.4.1 stack基本概念#include #include #include #include #include using namespace std; class Player { public: string name; int score; Player(string name) { this->name = name; } }; int main() { srand((unsigned int)time(NULL)); Player p1("A"); Player p2("B"); Player p3("C"); Player p4("D"); vector player; player.push_back(p1); player.push_back(p2); player.push_back(p3); player.push_back(p4); for (vector ::iterator it = player.begin(); it != player.end(); it++) { deque d; for (int j = 0; j < 10; j++) { int num = rand() % 10; d.push_back(num); } sort(d.begin(), d.end()); d.pop_back(); d.pop_front(); int sum = 0; for (deque ::iterator id = d.begin(); id != d.end(); id++) { sum += *id; } it->score = sum / 8; } for (int i = 0; i < player.size(); i++) { cout << player[i].score << endl; } return 0; }
概念:stack是一种先进后出(FILO)的数据结构,它只有一个出口
2.4.2 stack常用接口 2.5 queue容器 2.5.1 queue基本概念 2.5.2 queue 常用接口 2.6 list容器 2.6.1 list基本概念**功能:**将数据进行链式存储
**链表(list)**是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的
由于链表的存储方式并不是连续的内存空间,因此链表list中的迭代器只支持前移和后移,属于双向迭代器
list的优点:
采用动态存储分配,不会造成内存浪费和溢出
链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素
list的缺点:
链表灵活,但是空间(指针域)和时间(遍历)额外耗费较大
List有一个重要的性质,插入操作和删除操作都不会造成原有list迭代器的失效,这在vector是不成立的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bEseHaqE-1652080025700)(https://gitee.com/a-lice/typora/raw/master/image-20210814165814178.png)]
2.6.4 list大小操作 2.6.5 list插入和删除 2.6.6 list数据存取 2.6.7 list反转和排序因为list的迭代器不支持随机访问,所以不可以使用标准算法algorithm,需要使用自身的排序方法,默认也为升序
如果想要降序操作,需要在sort中传入一个函数名
函数具体实现如下:
bool compare(int a, int b)
{
return a > b;
}
多条件排序案例:
#include2.7 set / multiset 容器 2.7.1 set基本概念#include #include #include #include #include #include #include
using namespace std; class Person { public: string name; int age; int height; Person(string name, int age, int height) { this->name = name; this->age = age; this->height = height; } }; void creat(list & lp) { Person p1("张三", 18, 162); Person p2("里斯", 19, 188); Person p3("王五", 12, 124); Person p4("赵六", 24, 175); Person p5("李四", 19, 169); lp.push_back(p1); lp.push_back(p2); lp.push_back(p3); lp.push_back(p4); lp.push_back(p5); } bool real(Person &p1, Person &p2) { if (p1.age == p2.age) { return p1.height > p2.height; } else { return p1.age < p2.age; } } int main() { list l; creat(l); for (list ::const_iterator it = l.begin(); it != l.end(); it++) { cout << it->name << "t" << it->age << "t" << it->height << endl; } cout << "排序后:" << endl; l.sort(real); for (list ::const_iterator it = l.begin(); it != l.end(); it++) { cout << it->name << "t" << it->age << "t" << it->height << endl; } return 0; }
作用:
- 所有元素都会在插入时自动被排序
本质:
- set/multiset属于关联式容器,底层结构式用二叉树实现的
set与multiset区别:
- set不允许容器中出现重复的元素
- multiset允许容器中出现重复的元素
set只有insert写入数据的方法
2.7.5 set的查找和统计 2.7.6 set和multiset的区别 2.7.7 pair对组的创建 2.7.8 set容器排序set容器默认的排序规则为从小到大,但可以利用仿函数,改变原有的排序规则
1、对于内置数据类型
#include#include #include #include #include #include #include #include
#include using namespace std; class MyCompare { public: bool operator()(int v1, int v2)const //定义仿函数 { return v1 > v2; } }; void test01() { set s1; s1.insert(50); s1.insert(20); s1.insert(30); s1.insert(40); s1.insert(10); for (set ::iterator it = s1.begin(); it != s1.end(); it++) { cout << *it << " "; } cout << endl; cout << "更改排序规则后:" << endl; set s2; s2.insert(50); s2.insert(20); s2.insert(30); s2.insert(40); s2.insert(10); for (set ::iterator it = s2.begin(); it != s2.end(); it++) { cout << *it << " "; } } int main() { test01(); return 0; } //输出结果: 10 20 30 40 50 更改排序规则后: 50 40 30 20 10
2、对于自定义数据类型
#include2.8 map/ multimap容器 2.8.1 map的基本概念#include #include #include #include #include #include #include
#include using namespace std; class Person { public: string name; int age; Person(string name, int age) { this->name = name; this->age = age; } }; class comparePerson { public: bool operator()(Person p1, Person p2)const //定义仿函数 { return p1.age > p2.age; } }; void test01() { Person p1("张三", 18); Person p2("李四", 28); Person p3("王五", 21); Person p4("里斯", 16); Person p5("赵六", 25); set s; s.insert(p1); s.insert(p2); s.insert(p3); s.insert(p4); s.insert(p5); for (set ::iterator it = s.begin(); it !=s.end(); it++) { cout << it->name << "t" << it->age << endl; } } int main() { test01(); return 0; } //输出结果: 李四 28 赵六 25 王五 21 张三 18 里斯 16
简介:
- map中所有的元素都是pair类型
- pair中的第一个元素为key(键值),起到索引的作用,第二个元素为value(实值)
- 所有的元素都会根据元素的键值自动排序
本质:
- map/ multimap属于关联式容器,底层结构是用二叉树实现的
优点:
- 可以根据key值快速查找到value值
map与multimap的区别:
- map不允许容器中有重复的key值元素
- multimap允许容器中有重复的key元素
map容器默认排序的规则为:按照key值进行从小到大排序
利用仿函数,可以改变排序顺序
**示例:**实现key降序
#include2.9 STL常用容器案例#include #include #include #include #include #include #include
#include #include
案例描述:
实现:
#include#include #include #include #include
num = m.count(1);
for (int i = 0; i < num; pos1++, i++)
{
cout << "员工:" << pos1->second.name << "t" << "资薪:" << pos1->second.money << "t" << pos1->second.sector << endl;
}
cout << "部门2:" << endl;
multimap::iterator pos2 = m.find(2);
num = m.count(2);
for (int i = 0; i < num; pos2++, i++)
{
cout << "员工:"<second.name << "t" << "资薪:" << pos2->second.money << "t" << pos2->second.sector << endl;
}
}
int main()
{
srand((unsigned int)time(NULL));
vectorv;
createWorker(v);
multimapm;
setGroup(v, m);
showWorker(m);
return 0;
}
//输出结果:
部门0:
员工:C 资薪:19159
员工:G 资薪:11855
员工:I 资薪:13154
部门1:
员工:E 资薪:10069
员工:F 资薪:19858
部门2:
员工:A 资薪:15470
员工:B 资薪:12027
员工:D 资薪:11091
员工:H 资薪:10823
员工:J 资薪:15222



