C++中STL标准模板库学习记录
文章目录:
- 1.vector
- 1.1 遍历方式
- 1.2 构造函数
- 1.3 容量大小问题
- 1.4 插入和删除
- 1.5 存取值
- 1.6 交换两个vectot的元素
- 1.7 预定义存储空间
- 2.string
- 3. deque
- 4. stack
- 4.1 常用函数
- 5. queue
- 5.1 特点
- 5.2 方法
- 6. list
- 6.1 优点
- 6.2 缺点
- 6.3 构造函数
- 6.4 交换
- 6.5 大小
- 6.6 插入和删除
- 6.7 排序和反转
- 7. set
- 7.1 方法
- 7.2 pair 对数创建
- 7.3 排序
- 8. map
- 8.1 插入元素,大小与交换
- 8.2 查找与统计
- 8.3 排序
1.vector
1.1 遍历方式
for_each(v.begin(),v.end(),myPrint)// myPrint为自定义vector输出函数
1.2 构造函数
vector v2(v1.begin(),v1.end());
vector v2(10,1000);// 存储10个1000
vector v2(v1);// 将v1赋给v1
vector v2;
v2.assign(10,1000);// 存储10个1000
1.3 容量大小问题
capacity和size的区别
capacity是系统开辟的空间,这个空间可能大于定义的大小,作为备用存储空间
size是开辟的空间大小
一般capacity=size,没有备用空间。
在尾部添加push_back时,系统会找一个足够大的空间,并将原来的数组复制过去,
但一般会额外多开辟新备用空间,防止反复移动整个数组,而导致运行效率降低的问题
1.4 插入和删除
pop_back()删除最后一个元素
insert(v.begin(),100)在开始位置插入100
insert(v.begin(),2,1000)在开始位置插入2个1000
erase(v1.begin())移除第一元素值
erase(v1.begin(),v1.end())// 删除所有元素,不会清除开辟的空间(size)
clear()会清空vetor中的所有元素,包括开辟的空间(size),但是capacity会保留,这时不可以用下标的形式赋值,只能通过push_back函数。
1.5 存取值
可通过[]下标的形式和at()函数
front()返回第一个元素值
back()返回最后一个元素值
1.6 交换两个vectot的元素
v1.swap(v2)交换v1和v2的元素值
1.7 预定义存储空间
reserve(10000) 开辟预留空间,防止vector多次赋值导致的效率降低
#include<iostream>
#include<algorithm>
#include<vector>using namespace std;class Person {public:
string myname;
int myage;
Person(string name, int age) {
myname = name;
myage = age;
}
};
void myPrint(int val) {
cout << val << endl;
}void test() {
vector<int> v;// 定义存储int整形的向量
v.push_back(10);// 向向量中传值
v.push_back(20);
v.push_back(30);
v.push_back(40);vector<int>::iterator pBegin = v.begin();// 定义迭代器,迭代器指向第一个元素
vector<int>::iterator pEnd = v.end();// 定义迭代器,迭代器指向最后一个元素// 遍历vector
while (pBegin != pEnd) {
cout << *pBegin << endl;
pBegin++;
}
// 遍历vector
for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
cout << *it << endl;
}
// 遍历vector,加强型循环
for_each(v.begin(), v.end(), myPrint);}
// 存放自定义数据类型
void test01() {
vector<Person> v;
Person p1("aaa", 10);// 实例化对象
Person p2("bbb", 20);
Person p3("ccc", 30);
Person p4("ddd", 40);v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);for (vector<Person>::iterator it = v.begin(); it != v.end(); it++) {
cout << "name:" << (*it).myname << " age:" << (*it).myage << endl;
}
}
// 定义存储自定义对象地址
void test02() {
vector<Person*> v;
Person p1("aaa", 10);
Person p2("aaa", 20);
Person p3("aaa", 30);
Person p4("aaa", 40);v.push_back(&p1);
v.push_back(&p2);
v.push_back(&p3);
v.push_back(&p4);for (vector<Person*>::iterator it = v.begin(); it != v.end(); it++) {
Person *p = (*it);
cout << "name: " << p->myname << " age: " << p->myage << endl;
}}
// 嵌套存储vector的vector
void test03() {
vector<vector<int>> v;
vector<int> a1;
vector<int> a2;
vector<int> a3;
vector<int> a4;a1.push_back(10);
a1.push_back(20);
a1.push_back(30);
a1.push_back(40);v.push_back(a1);
v.push_back(a2);
v.push_back(a3);
v.push_back(a4);// 需要用到两个for循环,第一个返回的是vector,第二个是遍历返回的vector
for (vector<vector<int>>::iterator it = v.begin(); it != v.end(); it++) {
for (vector<int>::iterator vit = (*it).begin(); vit != (*it).end(); vit++) {
cout << *vit << endl;
}
}
}// vector赋值
void printVector(vector<int>& v) {
for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
cout << *it << " ";}
cout << endl;
}
// vectot构造函数
void test04() {
vector<int> v1;
for (int i = 0; i < 4; i++) {
v1.push_back(i);
}
printVector(v1);vector<int> v2(v1.begin(), v1.end());
printVector(v2);vector<int> v3(10, 100);
printVector(v3);vector<int> v4(v3);
printVector(v4);}
// vecotr赋值
void test05() {
vector<int> v1;
for (int i = 0; i < 4; i++) {
v1.push_back(i);
}
printVector(v1);vector<int> v2 = v1;
printVector(v2);vector<int> v3;
v3.assign(v1.begin(), v1.end());
printVector(v3);vector<int> v4;
v4.assign(10, 100);// 10个100进行赋值
printVector(v4);
}//vector大小操作
/* TODO capacity和size的区别capacity是系统开辟的空间,这个空间可能大于定义的大小,作为备用存储空间
size是开辟的空间大小
一般capacity=size,没有备用空间。
在尾部添加push_back时,系统会找一个足够大的空间,并将原来的数组复制过去,
但一般会额外多开辟新备用空间,防止反复移动整个数组,而导致运行效率降低的问题
*/void test06() {
vector<int> v1;
for (int i = 0; i < 4; i++) {
v1.push_back(i);
}
printVector(v1);
if (v1.empty()) {
cout << "v1为空" << endl;
}
else {
cout << "v1不为空" << endl;
cout << "v1的容量" << v1.capacity() << endl;
cout << "v1的大小" << v1.size() << endl;
}v1.resize(15, 10);// 指定大,默认用0填充,这里用用10填充
printVector(v1);v1.resize(5);// 指定小,超过部分将被删除
printVector(v1);
}// 插入和删除
void test07() {
vector<int> v1;
for (int i = 0; i < 4; i++) {
v1.push_back(i);
}
printVector(v1);v1.pop_back();// 删除最后一个元素
printVector(v1);v1.insert(v1.begin(), 100);// 在开始位置插入100
printVector(v1);v1.insert(v1.begin(), 2, 1000);// 在开始位置插入两个1000
printVector(v1);v1.erase(v1.begin());// 移除第一个元素值
printVector(v1);v1.erase(v1.begin(), v1.end());// 移除所有元素值
printVector(v1);
v1.clear();// 清空vector
printVector(v1);}//vector存取
void test08() {
vector<int> v1;
// 向v1中存值
for (int i = 0; i < 5; i++) {
v1.push_back(i);
}
// 通过数组下标的形式取值
for (int i = 0; i < 5; i++) {
cout << v1[i] << " ";
}
cout << endl;
// 通过at()函数进行取值
for (int i = 0; i < v1.size(); i++) {
cout << v1.at(i) << " ";
}
cout << endl;
// 取出第一个值和最后一个值
cout << "v1的第一元素为:" << v1.front() << endl;
cout << "v1的最后一个元素:" << v1.back() << endl;
}
// 交换两个vector的值
void test09() {
vector<int> v1;
for (int i = 0; i < 5; i++) {
v1.push_back(i);
}
printVector(v1);vector<int> v2;
for (int i = 10; i > 0; i--) {
v2.push_back(i);
}
printVector(v2);v1.swap(v2);// 交换vector的值
printVector(v1);
printVector(v2);
}void test10() {
vector<int> v1;
v1.reserve(10000);// 数据量比较大,开始使用reserve()预留空间
int num = 0;
int *p = NULL;
for (int i = 0; i < 10000; i++) {
v1.push_back(i);
if (p != &v1[0]) {
p = &v1[0];
num++;
}
}
cout << "num=" << num << endl;
}
int main()
{test01();
test02();
test03();
test04();
test05();
test06();
test07();
test08();
test09();
test10();system("pause");
return 0;
}
2.string
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;void test01()
{
string s1;// 创建空的字符串,调用无参数构造函数
cout << s1 << endl;const char* str = "hello world";
string s2(str);// 将字符指针调用
cout << s2 << endl;string s3(s2);// 用str初始化string
cout << s3 << endl;string s4(10, 'a');// 使用10个a字符初始化字符s4
cout << s4 << endl;
}// 给string赋值
void test02()
{
string str1;
str1 = "hello world!";
cout << str1 << endl;string str2;
str2 = str1;
cout << str2 << endl;string str3;
str3 = 'a';
cout << str3 << endl;string str4;
str4.assign("hello c++");
cout << str4 << endl;string str5;
str5.assign("hello c++", 5);// 存取前5个字符
cout << str5 << endl;
cout << str5 << endl;string str6;
str6.assign(str5, 2);// 传入的是string对象是去掉前2个字符
cout << str6 << endl;string str7;
str7.assign(5, 'x');
cout << str7 << endl;
}// string拼接
void test03() {
string str1 = "我";
str1 += "爱玩游戏";
cout << "str1 = " << str1 << endl;str1 += ":";
cout << "str1=" << str1 << endl;string str2 = "LOL DNF";
str1 += str2;
cout << "str1=" << str1 << endl;string str3 = "I";
str3.append(" love ");
str3.append("game abcd", 4);// 取前4个字符赋值
cout << "str3=" << str3 << endl;
str3.append(str2, 4, 2);// 取第4个位置开始的2个元素赋值
cout << "str3=" << str3 << endl;
}// 查找
void test04() {
string str1 = "abcdedefg";
int pos = str1.find("de");// 开始从起始位置查找第一次出现的下标
if (pos == -1) {
cout << "未找到" << endl;
}
else {
cout << "pos=" << pos << endl;
}pos = str1.rfind("de");// 查找最后一次出现的下标
cout << "pos=" << pos << endl;}//string 存取
void test05() {
string str = "hello world";
for (int i = 0; i < str.size(); i++) {
cout << str[i];
}
cout << endl;
for (int i = 0; i < str.size(); i++) {
cout << str.at(i);
}
cout << endl;
}// 插入和删除
void test06() {
string str = "hello";
str.insert(1, "111");
cout << str << endl;str.erase(1, 3);// 删除从下标1开始的3个元素
cout << str << endl;
}// 子串
void test07() {
string str = "abcdefg";
string substr = str.substr(1, 3);
cout << "substr=" << substr << endl;string email = "hello world@sina.com";
int pos = email.find("@");
string username = email.substr(0, pos);
cout << "username:" << username << endl;
}
int main()
{
//test01();
//test02();
//test03();
//test04();
//test05();
//test06();
test07();
system("pause");
return 0;
}
3. deque
双端数组
#include<iostream>
#include<algorithm>
#include<deque>using namespace std;/*
deque容器,双端数组,可以对头端进行插入和删除操作
deque和vector区别
vector对于头部的删除插入效率底,deque相对较快
vector对元素的访问速度比deque快
deque容器的迭代器支持随机访问
*/
void printDeque(const deque<int>& d) {
for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
// 构造函数
void test01(){
deque<int> d1;
for (int i = 0; i < 5; i++) {
d1.push_back(i);
}printDeque(d1);deque<int> d2(d1.begin(), d1.end());
printDeque(d2);deque<int> d3(10, 100);
printDeque(d3);deque<int> d4 = d3;
printDeque(d4);deque<int> d5;
d5.assign(10, 100);// 在开始的位置赋值10个100
printDeque(d5);deque<int> d6;
d6.assign(d5.begin(), d5.end());
}// 容量大小
void test02() {
deque<int> d1;
for (int i = 0; i < 5; i++) {
d1.push_back(i);
}
printDeque(d1);// 判断元素时候是否为空
if (d1.empty()) {
cout << "d1为空!" << endl;
}
else {
cout << "d1的大小为:" << d1.size() << endl;
}
d1.resize(15, 1);// 重新设定大小,超过元素使用1填充
printDeque(d1);d1.resize(5);// 重设大小,超过部分将被删除
printDeque(d1);}
// 插入和删除
void test03() {
deque<int> d;
d.push_back(10);// 尾插
d.push_back(20);d.push_front(100);// 头插
d.push_front(200);printDeque(d);d.pop_back();// 返回最后一个元素
d.pop_front();// 返回第一个元素
printDeque(d);d.insert(d.begin(), 1000);// 在开始的位置插入1000
printDeque(d);
d.insert(d.begin(), 2, 10000);// 在开始的位置插入2个1000
printDeque(d);deque<int> d2;
d2.push_back(1);
d2.push_back(2);
d2.push_back(3);
d.insert(d.begin(), d2.begin(), d2.end());// 向d中插入d2的所有值
printDeque(d);d.erase(d.begin());// 删除最开始的元素,返回下一个元素的位置d.clear();// 清空d,包括删除size
}// 存取值
void test04() {
deque<int> d;
d.push_back(10);
d.push_back(20);
d.push_back(30);
for (int i = 0; i < d.size(); i++) {
cout << d[i] << " ";
}
cout << endl;
for (int i = 0; i < d.size(); i++) {
cout << d.at(i) << " ";
}
cout << endl;cout << "front=" << d.front() << endl;
cout << "back=" << d.back() << endl;
}// 排序,升序
void test05() {
deque<int> d;
d.push_back(10);
d.push_back(20);
d.push_back(19);
d.push_back(15);
d.push_back(9);
printDeque(d);sort(d.begin(), d.end());
printDeque(d);}
int main()
{//test01();
//test02();
//test03();
//test04();
test05();
system("pause");
return 0;
}
4. stack
4.1 常用函数
push()// 入栈
pop()// 出栈
top()// 返回栈顶元素
empty()// 判断栈顶是否为空
size()// 栈中元素
#include<iostream>
#include<algorithm>
#include<stack>using namespace std;void test01() {
stack<int> s;s.push(10); // 进栈
s.push(20);
s.push(30);while (!s.empty()) { // 判断栈是否为空
cout << "栈顶元素:" << s.top() << endl;
s.pop();// 输出栈顶元素
}
cout << "栈的大小:" << s.size() << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
5. queue
5.1 特点
一端新增元素,一端移除元素
只有队头和队尾可以被外界使用,队列不允许有遍历行为
5.2 方法
push() // 往队尾添加元素
pop()// 从队头移除第一个元素
back()// 返回最后一个元素
front()// 返回第一个元素
empty()// 判断是否为空
size()// 返回栈的大小
#include<iostream>
#include<algorithm>
#include<string>
#include<queue>using namespace std;/*
队列:先进先出,允许一端新增元素,一端移除元素
队列中只有队头和队尾被外界使用,队列不存在遍历行为*/
class Person {
public:
Person(string name, int age) {// 构造函数
this->mName = name;
this->mAge = age;
}
string mName;
int mAge;
};void test01() {
queue<Person> q;Person p1("唐僧", 30);
Person p2("孙悟空", 40);
Person p3("猪八戒", 50);
Person p4("沙僧", 60);q.push(p1);
q.push(p2);
q.push(p3);
q.push(p4);while (!q.empty()) {
// 输出队头元素
cout << "姓名:" << q.front().mName <<
" 年龄:" << q.front().mAge << endl;// 输出队尾元素
cout << "姓名:" << q.back().mName <<
" 年龄:" << q.back().mAge << endl;
cout << endl;
q.pop();
}
cout << "队列大小为:"<<q.size() << endl;}int main()
{
test01();
system("pause");
return 0;
}
6. list
链表是一个双向循环链表
6.1 优点
采用动态存储分配,不会造成内存浪费和溢出,插入和删除操作方便
6.2 缺点
遍历效率低下
6.3 构造函数
list L2(L1.begin(),L1.end())// 将L1链表中的值赋给L1
list L3(10,1000)//存放10个1000
list L4()
L4.assign()//存放10个1000
6.4 交换
swap()//交换两个list中的值
6.5 大小
empty()//判断是否为空
size()//输出大小,元素个数
resize()//设置大小,超过原有数组用0填充,未达到,则后面的将被删除
6.6 插入和删除
push_back()// 尾插入
push_front()// 头插入
pop_back()// 尾删除
pop_front()// 头删除
insert(++it)// it是一个指针
erase(++it)// it是一个指针
remove(1000)// 移除list中所有的1000
6.7 排序和反转
reverse()// 反转数组
sort()// 排序数组
在自定义对象(例如Person)存储到list中,需要指定排序的顺序
#include<iostream>
#include<algorithm>
#include<string>
#include<list>using namespace std;
/*
STL中的链表是一个双向循环链表
优点:
采用动态存储分配,不会造成内存浪费和溢出
插入和删除操作十分方便
缺点:
遍历效率低下
*/void printList(const list<int> &L) {
for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
cout << *it << " ";
}
cout << endl;
}// 构造
void test01() {list<int> L1;
L1.push_back(10);
L1.push_back(20);
L1.push_back(30);
L1.push_back(40);printList(L1);list<int>L2(L1.begin(), L1.end());// 构造函数,定义的是否进行赋值
printList(L2);list<int> L3(10, 1000);// 存放10个1000
printList(L3);
}
// 赋值
void test02() {
list<int> L1;
L1.push_back(10);
L1.push_back(20);
L1.push_back(30);
L1.push_back(40);
printList(L1);list<int>L2;
L2 = L1;
printList(L2);list<int>L3;
L3.assign(L2.begin(), L2.end());
printList(L3);list<int>L4;
L4.assign(10, 1000);
printList(L4);
}
// 交换
void test03() {
list<int>L1;
L1.push_back(10);
L1.push_back(20);
L1.push_back(30);
L1.push_back(40);
printList(L1);list<int>L2;
L2.assign(10, 1000);
printList(L2);L2.swap(L1);// 交换printList(L1);
printList(L2);}
// 大小操作
void test04() {list<int> L1;
L1.push_back(10);
L1.push_back(20);
L1.push_back(30);
L1.push_back(40);
printList(L1);if (L1.empty()) {
cout << "不为空" << endl;
}
else {
cout << "L1的大小" << L1.size() << endl;
}// 重新指定大小
L1.resize(10);// 设置大小,超过的用0填充
printList(L1);
L1.resize(2);// 除掉后面超过的长度
printList(L1);}// 插入和删除
void test05() {
list<int> L1;
// 尾插
L1.push_back(10);
L1.push_back(20);
L1.push_back(30);
L1.push_back(40);// 头插
L1.push_front(1);
L1.push_front(2);
L1.push_front(3);
L1.push_front(4);
printList(L1);// 尾删
L1.pop_back();
printList(L1);// 头删
L1.pop_front();
printList(L1);// 插入
list<int>::iterator it = L1.begin();
L1.insert(++it, 100);
printList(L1);
// 删除
it = L1.begin();
L1.erase(++it);
printList(L1);// 移除
L1.push_back(1000);
L1.push_back(1000);
L1.push_back(1000);
printList(L1);
L1.remove(1000);
printList(L1);// 清空
L1.clear();
printList(L1);}
// 数据存储
void test06() {
list<int> L1;
L1.push_back(10);
L1.push_back(20);
L1.push_back(30);
L1.push_back(40);cout << "第一个元素:" << L1.front() << endl;
cout << "最后一个元素:" << L1.back() << endl;// list中的迭代器是双向迭代器,不支持随机访问
// it = it + 1;是错的}// list反转和排序
void test07() {
list<int> L1;
L1.push_back(10);
L1.push_back(20);
L1.push_back(4);
L1.push_back(2);
L1.push_back(1);
L1.push_back(30);
L1.push_back(40);
printList(L1);L1.reverse();// 反转链表
printList(L1);L1.sort();// 排序,按升序进行
printList(L1);
}// 实例
class Person{
public:
Person(string name, int age, int height) {
m_name = name;
m_age = age;
m_height = height;
}
public:
string m_name;
int m_age;
int m_height;
};
// 指定排序规则
bool comparePerson(Person &p1, Person &p2) {
if (p1.m_age == p2.m_age) {
return p1.m_height > p2.m_height;
}
else {
return p1.m_age < p2.m_age;
}
}void test08() {
list<Person>L1;
Person p1("刘备", 24, 175);
Person p2("关羽", 23, 185);
Person p3("关羽", 22, 185);
Person p4("关羽", 21, 185);
Person p5("张飞", 21, 170);
Person p6("曹操", 19, 165);
Person p7("典韦", 23, 190);L1.push_back(p1);
L1.push_back(p2);
L1.push_back(p3);
L1.push_back(p4);
L1.push_back(p5);
L1.push_back(p6);
L1.push_back(p7);for (list<Person>::iterator it = L1.begin(); it != L1.end(); it++) {
cout << "姓名:" << it->m_name << " 年龄:" << it->m_age <<
" 身高:" << it->m_height << endl;
}
cout << "----------------------------------------" << endl;
L1.sort(comparePerson);
for (list<Person>::iterator it = L1.begin(); it != L1.end(); it++) {
cout << "姓名:" << it->m_name << " 年龄:" << it->m_age <<
" 身高:" << it->m_height << endl;
}
}
int main()
{
//test01();
//test02();
//test03();
test04();
//test05 ();
//test06();
//test07();
//test08();
system("pause");
return 0;
}
7. set
7.1 方法
inser() // 排除重复元素
empty()// 判断是否为空
size()// 大小
swap()// 交换两个set的元素
erase(s.begin())// 移除最开始的元素
erase(10)// 移除set集合中的10
clear()// 清空set,此时size()为0
set::iterator pos = s.find(1);// 在元素中进行查找,成功后返回位置
s.count(10)// 统计10出现的次数
7.2 pair 对数创建
void test07() {
pair<string, int> p(string(“Tom”), 20);
cout << "姓名: " << p.first << " 年龄: " << p.second << endl;
pair<string, int> p2 = make_pair(“Jerry”, 10);
cout << "姓名: " << p2.first << " 年龄: " << p2.second << endl;
}
7.3 排序
sort()// 默认升序排序
可以根据自己定义的规则进行排序,定义一个类
#include<iostream>
#include<algorithm>
#include<set>
#include<string>
using namespace std;
/*
set:
所有元素都会插入时,进行自动排序,属于关联式容器,底层使用二叉树实现
set不允许容器中有重复元素,multiset容器允许有重复元素
*/void printSet(set<int> &s) {
for (set<int>::iterator it = s.begin(); it != s.end(); it++) {
cout << *it << " ";
}
cout << endl;
}// 赋值和构造函数
void test01() {
set<int> s1;
s1.insert(10);
s1.insert(30);
s1.insert(20);
s1.insert(50);
s1.insert(40);
s1.insert(60);
s1.insert(60);
s1.insert(60);
printSet(s1);//赋值
set<int> s2;
s2 = s1;
printSet(s2);// 构造函数
set<int> s3(s2);
printSet(s3);}// 大小
void test02() {
set<int> s1;
s1.insert(120);
s1.insert(10);
s1.insert(20);
s1.insert(40);
s1.insert(720);if (s1.empty()) {
cout << "s1为空" << endl;
}
else {
cout << "s1的大小为:" << s1.size() << endl;
}}
// 交换
void test03() {
set<int> s1;
s1.insert(12);
s1.insert(2);
s1.insert(10);
s1.insert(23);
s1.insert(1);set<int> s2;
s2.insert(5);
s2.insert(4);
s2.insert(3);
s2.insert(2);
s2.insert(1);cout << "交换前" << endl;
printSet(s1);
printSet(s2);
cout << "交换后" << endl;
s1.swap(s2);
printSet(s1);
printSet(s2);}
// 插入和删除
void test04() {set<int> s1;
s1.insert(12);
s1.insert(2);
s1.insert(29);
s1.insert(22);
s1.insert(19);
printSet(s1);// 删除
s1.erase(s1.begin());// 删除第一个元素
printSet(s1);s1.erase(19);// 移除素值为19的元素
printSet(s1);// 清空
s1.clear();
printSet(s1);
}// 查找与统计
void test05() {
set<int> s;
s.insert(12);
s.insert(9);
s.insert(11);
s.insert(2);
s.insert(1);set<int>::iterator pos = s.find(1);
if (pos != s.end()) {
cout << "找到了元素" << *pos << endl;
}
else {
cout << "未找到元素" << endl;
}
int num = s.count(9);
cout << "num=" << num << endl;
}
void test06() {
set<int> s;
pair<set<int>::iterator, bool> ret = s.insert(12);
if (ret.second) {
cout << "第一次插入成功!" << endl;
}
else {
cout << "第一次插入失败!" << endl;
}ret = s.insert(12);
if (ret.second) {
cout << "第二次插入成功!" << endl;
}
else {
cout << "第二次插入失败!" << endl;
}cout << "----------------------------------------" << endl;
// multiset
multiset<int> ms;
ms.insert(10);
ms.insert(10);
for (multiset<int>::iterator it = ms.begin(); it != ms.end(); it++) {
cout << *it << endl;
}
cout << endl;
}// pair对数创建
void test07() {
pair<string, int> p(string("Tom"), 20);cout << "姓名: " << p.first << " 年龄: " << p.second << endl;pair<string, int> p2 = make_pair("Jerry", 10);
cout << "姓名: " << p2.first << " 年龄: " << p2.second << endl;}
// 排序
class MyCompare {
public:
bool operator()(int v1, int v2) {
return v1 > v2;
}
};
void test08() {
set<int> s1;
s1.insert(10);
s1.insert(40);
s1.insert(20);
s1.insert(12);
s1.insert(19);
printSet(s1);set<int, MyCompare> s2;// 降序排序
s2.insert(10);
s2.insert(14);
s2.insert(1);
s2.insert(100);
s2.insert(23);
s2.insert(45);
for (set<int, MyCompare>::iterator it = s2.begin(); it != s2.end(); it++) {
cout << *it << " ";
}
cout << endl;}// set存放自定义数据类型
class Person {
public:string m_name;
int m_age;
Person(string name, int age) {
this->m_name = name;
this->m_age = age;
}};class comparePerson {
public:
bool operator()(const Person& p1, const Person & p2) {
// 按照年龄进行降序
return p1.m_age > p2.m_age;
}
};void test09() {
set<Person, comparePerson> s;// 指定了set中的排序方式
Person p1("刘备", 23);
Person p2("曹操", 22);
Person p3("张飞", 21);
Person p4("关羽", 21);s.insert(p1);
s.insert(p2);
s.insert(p3);
s.insert(p4);for ( set<Person, comparePerson>::iterator it = s.begin(); it != s.end(); it++){
cout << "姓名:" << it->m_name << "年龄:" << it->m_age << endl;
}
}
int main()
{
//test01();
//test02();
//test03();
//test04();
//test05();
//test06();
//test07();
//test08();
test09();
system("pause");
return 0;
}
8. map
map中所有元素为pair,第一个键,第二个为值
所有元素根据元素的键值自动排序
属于关联式容器,底层由二叉树实现
map不允许容器中所有重复key值
multimap允许容器中重复key值
8.1 插入元素,大小与交换
insert(pair<int,int>(1,10))// 插入键值对
empty()判断是否为空
size()拥有多少键值对
swap()交换两个map中的键值对
8.2 查找与统计
map<int,int>::iterator pos = m.find(3)// 查找map中键为3的键的位置
count(3)// 统计键为3的键值对个数
8.3 排序
按照key值进行从小到大的排序
利用仿函数,能够改变排序的规则
#include<iostream>
#include<algorithm>
#include<map>
#include<string>
using namespace std;
/*
map中所有元素为pair,第一个元素为键,第二个为元素
所有元素根据元素的键值自动排序
属于关联式容器,底层由二叉树实现map不允许容器中有重复key值
multimap允许容器中重复key值
*/
void printMap(map<int, int> &m) {
for (map<int, int>::iterator it = m.begin(); it != m.end(); it++) {
cout << "key=" << it->first << " value=" << it->second << endl;
}
cout << endl;
}
void test01() {map<int, int> m;// 默认构建
m.insert(pair<int, int>(1, 10));
m.insert(pair<int, int>(2, 20));
m.insert(pair<int, int>(3, 30));
m.insert(pair<int, int>(4, 40));
printMap(m);map<int, int> m2(m);// 拷贝函数
printMap(m2);map<int, int> m3;
m3 = m2;// 赋值
printMap(m3);}// 大小与交换
void test02() {
map<int, int> m;
m.insert(pair<int, int>(1, 10));
m.insert(pair<int, int>(2, 20));
m.insert(pair<int, int>(3, 30));
m.insert(pair<int, int>(4, 40));
if (m.empty()) {
cout << "m为空" << endl;
}
else {
cout << "m不为空" << endl;
cout << "m的大小为" << m.size() << endl;
}map<int, int> m1;
m1.insert(pair<int, int>(10, 100));
m1.insert(pair<int, int>(20, 200));
m1.insert(pair<int, int>(30, 300));
m1.insert(pair<int, int>(40, 400));
cout << "交换前:" << endl;
printMap(m);
printMap(m1);
cout << "-----------------------------------" << endl;
cout << "交换后:" << endl;
m.swap(m1);
printMap(m);
printMap(m1);
}// 插入和删除
void test03() {
map<int, int> m;
//第一种插入
m.insert(pair<int, int>(1, 10));
//第二种插入
m.insert(make_pair(2, 20));
//第三种插入
m.insert(map<int, int>::value_type(3, 30));
//第四种插入
m[4] = 40;printMap(m);m.erase(m.begin());// 删除最开始的元素
m.erase(3);// 删除键值为3的对数
printMap(m);// 清空
m.erase(m.begin(), m.end());
printMap(m);}//查找与统计
void test04() {
map<int, int> m;
m.insert(pair<int, int>(1, 10));
m.insert(pair<int, int>(2, 20));
m.insert(pair<int, int>(3, 30));
m.insert(pair<int, int>(4, 40));// 查找
map<int, int>::iterator pos = m.find(3);
if (pos != m.end()) {
cout << "找到了元素 key=" << (*pos).first << " value=" << (*pos).second << endl;
}
else {
cout << "未找到元素" << endl;
}
// 统计
int num = m.count(3);
cout << "num=" << num << endl;// 统计键值为3出现的次数
}// 排序
// 按照key值进行从小到大的排序
// 利用仿函数,能够改变排序的规则
class MyCompare {
public:
bool operator()(int v1, int v2) {
return v1 > v2;
}
};void test05() {
map<int, int, MyCompare> m;// 在这里会作降序排序
m.insert(make_pair(1, 10));
m.insert(make_pair(3, 30));
m.insert(make_pair(2, 20));
m.insert(make_pair(6, 60));
m.insert(make_pair(5, 50));for (map<int, int, MyCompare>::iterator it = m.begin(); it != m.end(); it++) {
cout << "key:" << it->first << " value:" << it->second << endl;
}
}
int main()
{
//test01();
//test02();
//test03();
//test04();
test05();
system("pause");
return 0;
}
相关文章:
C++中STL标准模板库学习记录
文章目录:1.vector1.1 遍历方式1.2 构造函数1.3 容量大小问题1.4 插入和删除1.5 存取值1.6 交换两个vectot的元素1.7 预定义存储空间2.string3. deque4. stack4.1 常用函数5. queue5.1 特点5.2 方法6. list6.1 优点6.2 缺点6.3 构造函数6.4 交换6.5 大小6.6 插入和删…...

《数据库系统概论》学习笔记——第六章 关系数据理论
教材为数据库系统概论第五版(王珊) 这一章重点在于各种范式的概念和将低级范式转为高级范式。一定要看多值依赖和4NF(因为这个概念很绕又烦,但是期中期末都考了)。最后计算题就是一定要会:算闭包࿰…...

Odoo | Webserivce | 5分钟学会【JSONRPC】接口开发
文章目录Odoo - JsonRPC1. Odoo内方法结构(接收端)2. POST接口请求结构(发送端)3. 实例测试Odoo - JsonRPC 1. Odoo内方法结构(接收端) # -*- coding: utf-8 -*- import odoo import logging import trac…...

搜广推 NeuralCF - 改进协同过滤+矩阵分解的思想
😄 NeuralCF:2017新加坡国立大学提出。【后文简称NCF】 😄 PNN:2016年上海交通大学提出。 文章目录 NeuralCF动机原理general NCFNCF终极版(GMF+MLP的结合)缺点优点ReferenceNeuralCF 动机 前面学了MF,可知MF在用户-物品评分矩阵的基础上做矩阵分解(用户矩阵Q和物品…...

dbever连接kerberos认证的hive
文章目录一、本地安装kerberos客户端二、本地kerberos客户端登录三、dbever连接hive一、本地安装kerberos客户端 下载地址:https://web.mit.edu/kerberos/dist/index.html 安装:下一步或者自定义安装即可 安装后会自动生成配置文件:C:\Pro…...

pom依赖产生的各种问题
文章目录问题一(org.apache.ibatis.session.Configuration)解决方法问题二(ERROR StatusLogger No log4j2)解决方法问题三(com.google.common.util.concurrent)解决方法问题四(start bean documentationPluginsBootstrapper)解决方法问题五(Unable to infer base url. )解决办法…...

RPC编程:RPC框架设计目标
一:前导知识 Http是超文本传输协议,跨平台性非常好。Http可以传输文本,更多的时候传输的是文本,我们也是可以传输二进制的,我们基于Http进行下载的时候,就是走的Http协议。 Tcp协议,处理的时候…...

RBAC 权限模型介绍
RBAC 权限: 一、关系: 这基于角色的访问控制的结构就叫RBAC结构。 二、RBAC 重要对象: 用户(Employee):角色施加的主体;用户通过拥有某个或多个角色以得到对应的权限。角色(Role&…...

西电面向对象程序设计核心考点汇总(期末真题)
文章目录前言一、往年真题与答案1.1 改错题1.2 读程题1.3 面向对象程序设计二、易错知识点2.1 构造函数2.2 静态成员变量和静态成员函数2.3 权限2.4 继承2.5 多态总结前言 主要针对西安电子科技大学《面向对象程序设计》的核心考点进行汇总,包含总共8章的核心简答。…...

判断一个用字符串表达的数字是否可以被整除
一.问题引出 当一个数字很大的时候,我们常用字符串进行表达,(超过了int和long等数据类型可以存储的最大范围),但是这个时候我们该如何判断他是否可以被另一个数整除呢? 这个时候我们不妨这样来考虑问题,每次将前边求模之后的数保存下来,然后乘以10和这一位的数字进行相加的操…...

这是一款值得开发人员认真研究的软件,数据库优化,应用服务器安全优化...
1.查询数据库死锁相关信息2.查看数据库的链接情况3.当前实例上的所有用户4.创建数据库独立密码5.查看数据库使用的端口号6.当前数据库设置的最大连接数7.当前数据库最大的理论可连接数8.当前数据库实例的连接数9.当前数据库连接数10.当前数据库连接超时设置11.当前sqlserver 超…...

栈与队列小结
一、理论基础1.队列是先进先出,栈是先进后出2.栈和队列是STL(C标准库)里面的两个数据结构。栈提供push和pop等等接口,所有元素必须符合先进后出规则,所以栈不提供走访功能,也不提供迭代器。3.栈是以底层容器…...

SpringBoot整合(五)HikariCP、Druid数据库连接池—多数据源配置
在项目中,数据库连接池基本是必不可少的组件。在目前数据库连接池的选型中,主要是 Druid ,为监控而生的数据库连接池。HikariCP ,号称性能最好的数据库连接池。 在Spring Boot 2.X 版本,默认采用 HikariCP 连接池。而…...

ShardingSphere水平、垂直分库、分表和公共表
目录一、ShardingSphere简介二、ShardingSphere-分库分表1、垂直拆分(1)垂直分库(2)垂直分表2、水平拆分(1)水平分库(2)水平分表三、水平分库操作1、创建数据库和表2、配置分片的规则…...

《分布式技术原理与算法解析》学习笔记Day24
分布式缓存 在计算机领域,缓存是一个非常重要的、用来提升性能的技术。 什么是分布式缓存? 缓存技术是指用一个更快的存储设备存储一些经常用到的数据,供用户快速访问。 分布式缓存是指在分布式环境或者系统下,把一些热门数据…...

强化学习RL 02: Value-based Reinforcement Learning
DQN和TD更新算法。 目录 Review 1. Deep Q-Network(DQN) 1.1 Approximate the Q*(s,a) Function 1.2 Apply DQN to Play Game 1.3 Temporal Difference(TD) Learning 1.4 TD Learning for DQN 1.4.1 TD使用条件 condition 1.4.2 Train DQN using TD learning 1.5 summ…...

08_MySQL聚合函数
1. 聚合函数介绍什么是聚合函数聚合函数作用于一组数据,并对一组数据返回一个值。聚合函数类型AVG()SUM()MAX()MIN()COUNT()注意:聚合函数不能嵌套调用。比如不能出现类似“AVG(SUM(字段名称))”形式的调用。1.1 AVG和SUM函数可以对数值型数据使用AVG 和…...

「TCG 规范解读」词汇表
可信计算组织(Ttrusted Computing Group,TCG)是一个非盈利的工业标准组织,它的宗旨是加强在相异计算机平台上的计算环境的安全性。TCG于2003年春成立,并采纳了由可信计算平台联盟(the Trusted Computing Platform Alli…...

第三阶段-03MyBatis 中使用XML映射文件详解
MyBatis 中使用XML映射文件 什么是XML映射 使用注解的映射SQL的问题: 长SQL需要折行,不方便维护动态SQL查询拼接复杂源代码中的SQL,不方便与DBA协作 MyBatis建议使用XML文件映射SQL才能最大化发挥MySQL的功能 统一管理SQL, 方…...

从0开始学python -41
Python3 命名空间和作用域 命名空间 先看看官方文档的一段话: A namespace is a mapping from names to objects.Most namespaces are currently implemented as Python dictionaries。 命名空间(Namespace)是从名称到对象的映射,大部分的命名空间都是…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...