C++提高编程-STL(容器)
STL初识
容器算法迭代器初识
vector存放内置数据类型
#include<vector>
#include<algorithm>
void myPrint(int x)
{
cout << x << ' ';
}
void test01()
{
//创建vector容器
vector<int>v;
//向容器中插入数据
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
//通过迭代器访问数据
for (vector<int>::iterator it = v.begin(); it < v.end(); it++)
{
cout << *it << endl;
}
//通过算法访问
for_each(v.begin(), v.end(), myPrint);
}
vector存放自定义的数据类型
//vector存放自定义类型
class Person
{
public:
Person(string name, int age)
{
this->m_Age = age;
this->m_Name = name;
}
void showPerson()
{
cout << this->m_Name << ' ' << this->m_Age << endl;
}
string m_Name;
int m_Age;
};
void myPrint(Person x)
{
x.showPerson();
}
void test01()
{
//创建vector容器
vector<Person>v;
//创建对象
Person p1("aaa", 10);
Person p2("bbb", 20);
Person p3("ccc", 30);
Person p4("ddd", 40);
Person p5("eee", 50);
//向容器中插入数据
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
v.push_back(p5);
//通过迭代器访问数据
for (vector<Person>::iterator it = v.begin(); it < v.end(); it++)
{
it->showPerson();
}
//通过算法访问
for_each(v.begin(), v.end(), myPrint);
}
string容器
string的构造函数
示例代码
//1.默认构造
string s1;
//2.利用c语言的字符串初始化
const char* str = "hello,word";
string s2(str);
cout << s2 << endl;
//3.拷贝构造
string s3(s2);
cout << s3 << endl;
//4.字符重复,初始化字符串
string s4(10, 'a');
cout << s4 << endl;
string的赋值操作
void test01()
{
const char* ch = "hello world";
//1.将c语言的字符串给string,以下两者等价
string st1;
st1 = "hello world";
st1 = ch;
//2.把字符串赋值
string st2;
st2 = st1;
cout << st2 << endl;
//3.将单个字符赋值
string st3;
st3 = 'a';
cout << st3 << endl;
//4.通过assign赋常量
string st4;
st4.assign("hello,C++");
cout << st4 << endl;
//4.通过assign,把前n个字符赋值
string st5;
st5.assign("hello C++", 6);
cout << st5 << endl;
//5.通过assign把字符串对象给
string st6;
st6 = st5;
cout << st6 << endl;
//6.通过assign把n个相同字符赋个string
string st7;
st7.assign(10, 'a');
cout << st7 << endl;
}
string的拼接操作
void test01()
{
const char* ch = "hello world,";
string st;
//1.重载+=符号,后面可以跟常量字符串/字符数组,字符,以及字符串
st += ch;
st += " I am ";
st += 'a'; st += ' ';
string st2 = "Chinese";
st += st2;
cout << st << endl;
//2.采用append函数,可以跟常量字符串/字符数组,数组的前n个字符,字符串以及从特定位置的n个字符开始拼接
string s;
s.append(ch);
s.append(" I am ");
s.append("abcde", 1);
string s2 = "I am a Chinese";
s.append(s2,6,8);
cout << s << endl;
}
string查找和替换
//字符串的查找和替换
//1.替换
void test01()
{
string str1 = "adecde";
//默认从0开始查找
int pos = str1.find("de");
cout << "pos = " << pos << endl;
//没有的话返回-1
pos = str1.find("ef");
cout << "pos = " << pos << endl;
//rfind 和 find 的区别:
//rfind从右向左查找,find从左向右查找
pos = str1.rfind("de");
cout << "pos = " << pos << endl;
}
//2.替换
void test02()
{
string str1 = "abcdefg";
//从1开始的3个字符替换成1111
str1.replace(1,3,"1111");
cout << str1 << endl;
}
string字符串比较
//字符串的比较
//大返回1,相等返回0,小返回-1
void test01()
{
string str1 = "hello";
string str2 = "hello";
if (str1.compare(str2) == 0)
{
cout << "str1 == str2" << endl;
}
str2 = "hellox";
if (str1.compare(str2) == -1)
{
cout << "str1 < str2 " << endl;
}
str2 = "x";
if (str1.compare(str2) == -1)
{
cout << "str1 < str2 " << endl;
}
}
字符存取
//字符串存取的操作
void test01()
{
string str1 = "hello";
//1.通过[]访问单个字符
for (int i = 0; i < str1.length(); i++)
{
cout << str1[i] << ' ';
}
cout << endl;
//2.通过at方法
for (int i = 0; i < str1.length(); i++)
{
cout << str1.at(i) << ' ';
}
cout << endl;
//修改字符
str1[0] = 'x';
cout << str1 << endl;
str1.at(1) = 'x';
cout << str1 << endl;
}
string插入和删除
//字符串插入和删除
void test01()
{
string str1 = "hello";
//在第i个字符前方插入
str1.insert(5," world!");
cout << str1 << endl;
//删除
str1.erase(1,3);
cout << str1 << endl;
}
string子串
//字符串子串
void test01()
{
string str1 = "Hello World!";
string str2 = str1.substr(0,3);
cout << str2 << endl;
//实用价值比较高,配合find可以截取字符串中的内容
string email = "zhangsan@singa.com";
int pos = email.find("@");
string name = email.substr(0,pos);
cout << name << endl;
}
vector容器
vector初始
vector构造函数
void printVector(vector<int>&v)
{
for (vector<int>::iterator it = v.begin(); it < v.end(); it++)
{
cout << *it << endl;
}
}
//vector容器的构造
void test01()
{
//默认构造
vector<int>v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
printVector(v1);
//通过区间方式进行构造
vector<int>v2(v1.begin(), v1.end());
printVector(v2);
//通过n个elem方式构造
vector<int>v3(10, 100);
printVector(v3);
//拷贝构造
vector<int>v4(v3);
printVector(v4);
}
vector赋值操作
//vector容器的构造
void test01()
{
//默认构造
vector<int>v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
printVector(v1);
//直接=赋值
vector<int>v2;
v2 = v1;
printVector(v2);
//assign区间赋值
vector<int>v3;
v3.assign(v1.begin(), v1.end());
printVector(v3);
//assign,n个elem赋值
vector<int>v4;
v4.assign(10, 100);
printVector(v4);
}
vector容量和大小
//vector容量和大小
void test01()
{
vector<int>v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
//为真,代表容器为空
if (v1.empty())
{
cout << "v1为空" << endl;
}
else
{
cout << "v1不为空" << endl;
cout << "v1的容量为:" << v1.capacity() << endl;
cout << "v1的大小为:" << v1.size() << endl;
}
//重新指定大小
v1.resize(15, 100);
printVector(v1);//如果重新指定的过长,默认用0填充新的位置,可以添加参数修改默认填充值
cout << "v1的容量为:" << v1.capacity() << endl;
v1.resize(5);
printVector(v1);//如果重新指定的比原来的短了,则超出部分删除掉
cout << "v1的容量为:" << v1.capacity() << endl;
}
vector插入和删除
//vector插入和删除
void test01()
{
vector<int>v1;
//尾插法
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
v1.push_back(40);
v1.push_back(50);
printVector(v1);
//尾删
v1.pop_back();
printVector(v1);
//插入,第一个时迭代器,第二个是插入的值
v1.insert(v1.begin(), 100);
printVector(v1);
//插入,同样可以插入多个值,第一个是值,第二个是次数
v1.insert(v1.begin(), 2, 1000);
printVector(v1);
//删除
v1.erase(v1.begin());
printVector(v1);
//删除可以提供区间
v1.erase(v1.begin() , v1.end());
printVector(v1);
//成员函数clear清空
v1.clear();
}
vector数据存取
//vector数据存取
void test01()
{
vector<int>v1;
//尾插法
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
v1.push_back(40);
v1.push_back(50);
for (int i = 0; i < v1.size(); i++)
{
cout << v1[i] << ' ';
}
cout << endl;
for (int i = 0; i < v1.size(); i++)
{
cout << v1.at(i) << ' ';
}
cout << endl;
cout << "v1的第一个元素为:" << v1.front() << endl;
cout << "v2的最后一个元素为:" << v1.back() << endl;
}
vector容器互换
//vector容器互换
void test01()
{
vector<int>v1;
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
v1.push_back(40);
v1.push_back(50);
cout << "交换前" << endl;
printVector(v1);
vector<int>v2;
for (int i = 0; i < 10; i++)
{
v2.push_back(i);
}
printVector(v2);
cout << "交换后" << endl;
v1.swap(v2);
printVector(v1);
printVector(v2);
}
vector预留空间
//vector预留空间
void test01()
{
vector<int>v1;
//给内存预留空间,但不初始化,无法访问,和resize的区别,为resize的空间直接可访问
v1.reserve(10312);
cout << "v1的容量为:" << v1.capacity() << endl;
cout << "v1的大小为:" << v1.size() << endl;
}
deque容器
deque基本概念
deque构造函数
//deque构造函数
void test01()
{
//1.默认构造
deque<int>d1;
for (int i = 0; i < 10; i++)
{
d1.push_back(i);
}
printDeque(d1);
//2.区间方式
deque<int>d2(d1.begin(), d1.end());
printDeque(d2);
//3.n个elem的方式
deque<int>d3(5, 100);
printDeque(d3);
//4.拷贝构造
deque<int>d4(d3);
printDeque(d4);
}
deque赋值操作
//deque赋值操作
void test01()
{
deque<int>d1;
for (int i = 0; i < 10; i++)
{
d1.push_back(i);
}
printDeque(d1);
//1.重载 =
deque<int>d2;
d2 = d1;
printDeque(d2);
//2.利用重载将区间赋值,或者n个elem
deque<int>d3;
d3.assign(d1.begin(),d1.end()-1);
printDeque(d3);
deque<int>d4;
d4.assign(5, 100);
printDeque(d4);
}
deque大小操作
//deque大小操作
void test01()
{
deque<int>d1;
for (int i = 0; i < 10; i++)
{
d1.push_back(i);
}
printDeque(d1);
//1.判断容器是否为空
if (d1.empty())
{
cout << "d1容器为空" << endl;
}
else
{
cout << "d1容器不为空" << endl;
}
//2.resize操作,第二个参数不写,默认为0,写了若扩充则为默认参数。
d1.resize(20);
cout << "d1的大小为:" << d1.size() << endl;
printDeque(d1);
d1.resize(30, 100);
cout << "d1的大小为:" << d1.size() << endl;
printDeque(d1);
}
deque的插入和删除
//deque插入和删除
void test01()
{
deque<int>d1;
for (int i = 0; i < 10; i++)
{
d1.push_back(i);
}
printDeque(d1);
//1.两端操作后插后删,前插前删
d1.push_back(101);
d1.push_back(102);
d1.pop_back();
d1.push_front(201);
d1.push_front(202);
d1.pop_front();
printDeque(d1);
//2.insert插入和删除
//1.普通插入
d1.insert(d1.begin() + 1, 1000);
printDeque(d1);
//2.插入n个elem
d1.insert(d1.begin() + 2, 2, 2000);
printDeque(d1);
//3.插入区间
d1.insert(d1.begin() + 4, d1.begin(), d1.end());
printDeque(d1);
//3.删除
//1.删除单个数
d1.erase(d1.begin()+1);
printDeque(d1);
//2.删除区间
d1.erase(d1.begin(), d1.end()-1);
printDeque(d1);
//4.清空
d1.clear();
}
deque数据存取
//deque数据存取
void test01()
{
deque<int>d1;
for (int i = 0; i < 10; i++)
{
d1.push_back(i);
}
printDeque(d1);
//1.通过[]随机访问
for (int i = 0; i < d1.size(); i++)
{
cout << d1[i] << ' ';
}
cout << endl;
//2.通过at访问
for (int i = 0; i < d1.size(); i++)
{
cout << d1.at(i) << ' ';
}
cout << endl;
//3.front() 和back()
cout << "第一个元素为:" << d1.front() << endl;
cout << "最后一个元素为:" << d1.back() << endl;
}
deque排序
//deque,sort排序
void test01()
{
deque<int>d1;
for (int i = 0; i < 10; i++)
{
d1.push_back(10-i);
}
printDeque(d1);
sort(d1.begin(), d1.end());
printDeque(d1);
}
stack容器
stack基本概念
stack基本接口
queue容器
queue常用接口
list容器
list基本概念
list构造函数
发现大部分的STL构造函数都是4个,默认无参构造,拷贝构造,区间构造,n个elem构造。
//list构造函数
void test01()
{
//1.默认构造
list<int>L1;
L1.push_back(1);
L1.push_back(2);
L1.push_back(3);
printList(L1);
//2.拷贝构造
list<int>L2(L1);
printList(L2);
//3.区间构造
list<int>L3(L1.begin(), L1.end());
printList(L3);
//4.n个elem构造
list<int>L4(5, 100);
printList(L4);
}
list赋值与交换
发现大部分STL都有assign函数支持区间赋值和那个elem,以及重载了=。
//list赋值和交换
void test01()
{
//1.assign n个elem
list<int>L1;
L1.assign(5, 100);
printList(L1);
//2.assign 区间赋值
list<int>L2;
L2.assign(L1.begin(), L1.end());
printList(L2);
//3.重载=
list<int>L3;
L3 = L2;
printList(L3);
//4.交换
list<int>L4;
L4.push_back(1);
L4.push_back(2);
L4.push_back(3);
cout << "交换前:" << endl;
printList(L3);
printList(L4);
//交换操作
L4.swap(L3);
cout << "交换后:" << endl;
printList(L3);
printList(L4);
}
list大小操作
//list大小操作
void test01()
{
list<int>L1;
L1.push_back(1);
L1.push_back(2);
L1.push_back(3);
L1.push_back(4);
L1.push_back(5);
cout << "L1的大小为:" << L1.size() << endl;
printList(L1);
//1.resize规定的小于当前的,截断末尾的数字
L1.resize(3);
cout << "L1的大小为:" << L1.size() << endl;
printList(L1);
//2.resize规定的大于当前大小,以默认值填充,默认值默认为0
L1.resize(4, 0);
cout << "L1的大小为:" << L1.size() << endl;
printList(L1);
L1.resize(5, 100);
cout << "L1的大小为:" << L1.size() << endl;
printList(L1);
}
list插入和删除
大部分的容器的插入insert大差不差,容器特性引起会引起前后端插入和修改不同。
//list插入和删除
void test01()
{
//尾插
list<int>L;
L.push_back(10);
L.push_back(20);
L.push_back(30);
//头插
L.push_front(100);
L.push_front(200);
L.push_front(300);
printList(L);
//尾删
L.pop_back();
//头删
L.pop_front();
printList(L);
//insert插入
list<int>::iterator it = L.begin();
L.insert(++it, 1000);
printList(L);
//erase删除
L.erase(L.begin());
printList(L);
//remove,移除所有这个值的元素
L.push_back(10000);
L.push_back(10000);
L.push_back(10000);
printList(L);
L.remove(10000);
printList(L);
}
list数据存取
list本质是链表,不支持迭代器随机访问。
list反转和排序
//list反转和排序
//所有不支持随机访问的迭代器的容器,不可以用标准算法。
//但是这些容器内部,都会提供成员函数实现这些算法。
void test01()
{
list<int>L;
L.push_back(10);
L.push_back(20);
L.push_back(30);
L.push_front(100);
L.push_front(200);
L.push_front(300);
//翻转
cout << "翻转前:" << endl;
printList(L);
L.reverse();
cout << "翻转后:" << endl;
printList(L);
//排序
cout << "排序前:" << endl;
printList(L);
L.sort();
cout << "排序后:" << endl;
printList(L);
}
set/multiset
set基本概念
set构造和赋值
set大小
set插入和删除
set查找和统计
//set的查找和统计
void test01()
{
set<int>s;
s.insert(10);
s.insert(20);
s.insert(30);
set<int>::iterator it = s.find(20);
if (it != s.end())
{
s.erase(it);
}
printSet(s);
cout << "set中10的数量为:" << s.count(10) << endl;
}
set和multiset的区别
对组的创建方式
set排序
内置数据类型排序:
//仿函数,里面重载(),内容为想要排序的内容。
class MyCompare
{
public:
bool operator()(int v1, int v2) const
{
return v1 > v2;
}
};
//set的排序
void test01()
{
//内置类型的排序规则修改
//MyPair为仿函数
set<int, MyCompare>s;
s.insert(10);
s.insert(20);
s.insert(30);
for (set<int, MyCompare>::iterator it = s.begin(); it != s.end(); it++)
{
cout << *it << ' ';
}
cout << endl;
}
自定义数据类型排序:
class Person
{
public:
Person(string name, int age)
{
this->m_Name = name;
this->m_Age = age;
}
string m_Name;
int m_Age;
};
//全局函数重载类的<
bool operator< (const Person& p1, const Person& p2)
{
return p1.m_Age < p2.m_Age;
}
//仿函数,里面重载(),内容为想要排序的内容。
class MyCompare
{
public:
bool operator()(const Person &p1, const Person &p2) const
{
return p1.m_Age < p2.m_Age;
}
};
//set的排序
void test01()
{
//自定义数据类型类型的排序规则修改
//1.全局函数上,重载类的<号
set<Person>s;
s.insert(Person("张三", 18));
s.insert(Person("李四", 20));
s.insert(Person("王五", 19));
for (set<Person>::iterator it = s.begin(); it != s.end(); it++)
{
cout << it->m_Name << ' ' << it->m_Age << endl;
}
cout << endl;
//2.利用仿函数
set<Person,MyCompare>s2;
s2.insert(Person("张三", 18));
s2.insert(Person("李四", 20));
s2.insert(Person("王五", 19));
for (set<Person,MyCompare>::iterator it = s2.begin(); it != s2.end(); it++)
{
cout << it->m_Name << ' ' << it->m_Age << endl;
}
cout << endl;
}
map和multimap容器
map的基本概念
map的构造和赋值
比较常规的构造和赋值。
map的大小和交换
map的插入和删除
//map的插入和删除
void test01()
{
//insert插入
map<string, int>mp;
mp.insert(pair<string, int>("张三", 3));
mp.insert(pair<string, int>("李四", 4));
mp.insert(pair<string, int>("王五", 5));
printMap(mp);
//erase删除
mp.erase(mp.begin());
mp.erase("李四");
printMap(mp);
//清空
mp.clear();
}
map查找和统计
map重载排序规则
class myCompare
{
public:
bool operator()(const int& a, const int& b) const
{
return a > b;
}
};
void printMap(map<int, int, myCompare>& mp)
{
for (map<int, int, myCompare>::iterator it = mp.begin(); it != mp.end(); it++)
{
cout << it->first << ' ' << it->second << endl;
}
}
//利用仿函数的技术重载map的排序规则
void test01()
{
//insert插入
map<int, int, myCompare>mp;
mp.insert(pair<int, int>(1, 3));
mp.insert(pair<int, int>(2, 4));
mp.insert(pair<int, int>(3, 5));
printMap(mp);
}