本质:string是C++风格的字符串,而string本质上是一个类
string和char *的区别:
- char *是一个指针
- string是一个类,类内部封装了char *,管理这个字符串,是一个char *型的容器
特点:
string内部封装了很多成员
例如:查找find,拷贝copy,删除delete替换replace,插入insert
string管理char *所分配的内存,不用担心复制越界和取值越界等,由类内部进行负责
1.2 string构造函数构造函数原型:
string(); //创建一个空的字符串,例如:string str; string(const char* s); //使用字符串初始化 string(const string& str); //使用一个string对象初始化另一个string对象 string(int n,char c); //使用n个字符初始化
#include#include using namespace std; void test01() { //string是一个类 //我们前期用的一直都是string类的默认构造,也就是下面的方式 //默认构造初始化 string str1; //使用字符串初始化 const char* str = "hello,world"; string s2(str); //有参构造进行初始化 cout << s2 << endl; string s3(s2); //拷贝构造进行初始化 cout << s3 << endl; string s4(5, 'a'); //使用n个字符初始化 cout << s4 << endl; } int main() { test01(); system("pause"); return 0; }
1.3 string赋值操作
功能描述:给string字符串进行赋值
赋值函数的原型:
string& operator=(const char* s) //char*类型字符串赋值给当前字符串 string& operator=(const string &s) //把字符串s赋值给当前字符串 string& operator=(const c) //字符赋值给当前字符串 string& assign(const char* s) //把字符串s赋值给当前字符串 string& assign(const char* s,int n) //把字符串s的前n个字符赋值给字符串 string& assign(const string &s) //把字符串s赋值给当前字符串 string& assign(int n,char c) //用n个字符c赋值给字符串
#include#include using namespace std; void test01() { string str1; str1 = "hello world"; cout << str1 < 1.4 string字符串拼接 功能描述:实现字符串末尾拼接字符串
函数原型:
string& operator+=(const char* str) //重载+=操作符 string& operator+=(const char c) //重载+=操作符 string& operator+=(const string& str) //重载+=操作符 string& append(const char* s) //把字符串s连接到当前字符串结尾 string& append(const char* s,int n) //把字符串s的前n个字符连接到当前字符串结尾 string& append(const string& s) //同operator+=(const string& str) string& append(const string& s,int pos,int n) //把字符串s从pos开始的n个字符连接到字符串尾部#include1.5 string查找和替换#include using namespace std; //字符串拼接 void test01() { string str1 = "我"; str1 += "爱玩游戏"; cout << str1 << endl; str1 += ":"; cout << str1 << endl; string str2 = "LOL DNF"; str1 += str2; cout << str1 << endl; string str3 = "I"; str3.append("Love"); cout << str3 << endl; str3.append("Game 666",4); cout << str3 << endl; str3.append(str2); cout << str3 << endl; str3.append(str2, 0, 3); //只截取LOL cout << str3 << endl; str3.append(str2, 4, 3); //只截取LOL cout << str3 << endl; } int main() { test01(); system("pause"); return 0; } 功能描述:【查找:查找指定字符串是否存在】【替换:在指定的位置替换字符串】
函数原型:
int find(const string& str,int pos = 0) const; //查找str第一次出现位置,从pos开始查找 int find(const char* s,int pos = 0) const; //查找s第一次出现位置,从pos开始查找 int find(const char* s,int pos = 0,int n) const; //从pos位置查找s的前n个字符第一次位置 int find(const char c,int pos = 0) const; //查找字符c第一次出现位置 int rfind(const string& str,int pos = npos) const; //查找str最后一次出现位置,从pos开始查找 int rfind(const char* s,int pos = npos) const; //查找s最后一次出现位置,从pos开始查找 int rfind(const char* s,int pos ,int n) const; //从pos查找s的前n个字符最后一次位置 int rfind(const char c,int pos = 0) const; //查找字符c最后一次出现位置 string& replace(int pos,int n ,const string& str) //替换从pos开始n个字符为字符串str string& replace(int pos,int n,const char* s) //替换从pos开始的n个字符为字符串s#include#include using namespace std; //查找 void test01() { string str = "abcdefgde"; int pos = str.find("de"); if (pos == -1) { cout << "未查到字符串:" << pos << endl; } else { cout << "查到字符串:" << pos << endl; } //rfind和find的区别,find从左到右查,rfind从右向左查(从右查到的第一个,就是从左到右的最后一个) pos = str.rfind("de"); if (pos == -1) { cout << "未查到字符串:" << pos << endl; } else { cout << "查到字符串:" << pos << endl; } } //替换 void test02() { string str = "abcdefg"; str.replace(1, 3, "1111"); cout << str << endl; } int main() { test01(); test02(); system("pause"); return 0; } 总结:
1.6 string字符串比较
- find查找是从往右,rfind是从右往左
- find找到字符串后返回查找的第一个字符位置,找不到返回-1
- replace在替换时,要指定从那个位置起,多少个字符,替换成什么样的字符串
功能描述:字符串之间比较
比较方式:字符串比较是按字符的ASCII码进行对比
= 返回 0
> 返回 1
< 返回 -1
函数原型:
int compare(const string &s) const; //与字符串s比较 int compare(const char *s) const; //与字符串s比较#include1.7 string字符存取#include using namespace std; //查找 void test01() { string str1 = "hello"; //string str2 = "hello"; const char* str2 = "hello"; if (str1.compare(str2) == 0) { cout << "str1等于ste2" << endl; } else if (str1.compare(str2) > 0) { cout << "str1大于ste2" << endl; } else { cout << "str1小于ste2" << endl; } } int main() { test01(); system("pause"); return 0; } string中单个字符存取方式有两种
char& operator[](int n) //通过[]方式取字符 char& at(int n) //通过at方式取字符#include1.8 string插入和删除#include using namespace std; //查找 void test01() { string str1 = "hello"; cout << "str1 = " << str1 << endl; //1,通过[]获取单个字符 for (int i = 0; i < str1.size(); i++) { cout << str1[i] << " "; } cout << endl; //1,通过at获取单个字符 for (int i = 0; i < str1.size(); i++) { cout << str1.at(i) << " "; } cout << endl; //修改单个字符 str1[0] = 'x'; cout << "str1 = " << str1 << endl; str1.at(1) = 'x'; cout << "str1 = " << str1 << endl; } int main() { test01(); system("pause"); return 0; } 功能描述:对string字符串进行插入和删除字符操作
函数原型:
string& insert(int pos,const char* s); //插入字符串 string& insert(int pos,const string& str); //插入字符串 string& insert(int pos,int n,char c); //在指定位置插入n个字符c string& erase(int pos,int n = npos); //删除从pos开始的n个字符#include#include using namespace std; //查找 void test01() { string str1 = "hello"; //字符串插入 str1.insert(1, "111"); cout << str1 << endl; //字符串删除 str1.erase(1, 3); cout << str1 << endl; } int main() { test01(); system("pause"); return 0; } 总结:插入和和删除的起始下标都是从0开始
1.9 string子串
功能描述:从字符串获取想要的子串
函数原型
string& substr(int pos = 0,int n = npos) const; //返回由pos开始的n个字符组成的字符串#include2 vector容器 2.1 vector基本概念#include using namespace std; void test01() { //string子串 string str = "abcdef"; string subStr = str.substr(1, 3); cout << subStr << endl; } //实用操作 void test02() { string str = "jackie@qq.com"; //从邮箱名中截取用户名 标志性@前面就是名字 int pos = str.find("@"); string subStr = str.substr(0, pos); cout << subStr << endl; } int main() { test01(); test02(); system("pause"); return 0; } 功能:vector数据结构和数组非常相似,也称为单端数组
vector与普通数组的区别:不同之处在于数组是静态空间,而vector可以动态扩展
动态扩展:并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝到新空间,释放原空间
2.2 vector构造函数功能描述:创建vector容器并初始化
函数原型:
vectorv; //采用模板实现类实现,默认构造函数 vector(v.begin(),v.end()); //将v[begin(),end()]区间的元素拷贝给自身 vector(n, elem) //构造函数将n个elem拷贝给自身 vector(const vector &vec) //拷贝构造函数 #include2.3 vector赋值操作#include #include using namespace std; //打印接口 void printVector(vector & v1) { for (vector ::iterator it = v1.begin(); it != v1.end(); it++) { cout << *it << " "; } cout << endl; } void test01() { vector v1; //默认构造 for (int i = 1; i < 10;i++) { v1.push_back(i); //插入数据 } printVector(v1); vector v2(v1.begin(), v1.end()); //将v1区间的元素拷贝给v2 printVector(v2); vector v3(10,100); //将10个100拷贝给v3 printVector(v3); vector v4(v3); //拷贝构造 printVector(v4); } int main() { test01(); system("pause"); return 0; } 功能描述:给vector容器进行赋值
函数原型:
vector& operator=(const vector &vec) //重载等号操作符 assign(beg,end); //将[beg,end]区间中的数据拷贝赋值给本身 assign(n,elem); //将n个elem拷贝赋值给本身#include2.4 vector容量和大小#include #include using namespace std; //打印接口 void printVector(vector & v1) { for (vector ::iterator it = v1.begin(); it != v1.end(); it++) { cout << *it << " "; } cout << endl; } void test01() { vector v1; for (int i = 1; i < 10;i++) { v1.push_back(i); } printVector(v1); //赋值操作 operator= vector v2; v2 = v1; printVector(v2); //区间赋值 vector v3; v3.assign(v2.begin(),v2.end()); printVector(v3); //将n个elem赋值给容器 vector v4; v4.assign(10, 100); printVector(v4); } int main() { test01(); system("pause"); return 0; } 功能描述:对vector容器的容量和大小操作
函数原型:
empty(); //判断函数是否为空 capacity(); //容器的容量 size(); //返回容器中元素的个数 resize(int num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置 //如果容器变短,则末尾超出容器长度的元素被删除 resize(int num,elem) //重新指定容器的长度为num,若容器变长,则以elem值填充新位置 //如果容器变短,则末尾超出容器长度的元素被删除#include2.5 vector插入与删除#include #include using namespace std; //打印接口 void printVector(vector & v1) { for (vector ::iterator it = v1.begin(); it != v1.end(); it++) { cout << *it << " "; } cout << endl; } void test01() { vector v1; for (int i = 1; i < 10;i++) { v1.push_back(i); } printVector(v1); if (v1.empty() == true) { cout << "v1为空" << endl; } else { cout << "v1不为空" << endl; cout << "v1的容量:" << v1.capacity() << endl; cout << "v1的大小:" << v1.size() << endl; } //增加容器的大小 v1.resize(11, 100); //利用重载版本,可以指定默认的填充值,参数2 printVector(v1); //如果比原来长了,那么默认的填充值为0 //减小容器的大小 v1.resize(5); //如果比原来短了,那么会舍弃后面的值,size变小,但是capacity不变 printVector(v1); } int main() { test01(); system("pause"); return 0; } 功能描述:对vector容器进行插入,删除操作
函数原型:
push_back(ele); //尾部插入元素ele pop_back(); //删除最后一个元素 insert(const_iterator pos,ele); //迭代器指向位置pos插入元素ele insert(const_iterator pos,int count,ele); //迭代器指向位置pos插入count个元素ele erase(const_iterator pos); //删除迭代器指向的元素 erase(const_iterator start,const_iterator end); //删除迭代器从start到end之间元素 clear(); //删除容器中所有的元素#include#include #include using namespace std; //打印接口 void printVector(vector & v1) { for (vector ::iterator it = v1.begin(); it != v1.end(); it++) { cout << *it << " "; } cout << endl; } void test01() { vector v1; //尾插 v1.push_back(10); v1.push_back(20); v1.push_back(30); printVector(v1); //尾删 v1.pop_back(); printVector(v1); //插入指定位置的元素 第一个参数迭代器 v1.insert(v1.begin()+1,100); printVector(v1); //插入多个 v1.insert(v1.begin() + 1,2,1000); printVector(v1); //删除指定位置的元素 v1.erase(v1.begin() + 3); printVector(v1); //清空 //v1.erase(v1.begin(),v1.end()); v1.clear(); printVector(v1); } int main() { test01(); system("pause"); return 0; } 总结:
2.6 vector数据存取
- 尾插 --- push_back
- 尾删 --- pop_back
- 插入 --- insert (位置迭代器)
- 删除 --- erase (位置迭代器)
- 清空 --- clear
功能描述:对vector中的数据存取操作
函数原型:
at(int idx); //返回索引id所指的数据 operator[]; //返回索引idx所指的数据 front(); //返回容器中第一个数据元素 back(); //返回容器中最后一个数据元素#include2.7 vector互换容器#include #include using namespace std; void test01() { vector v1; //尾插 v1.push_back(10); v1.push_back(20); v1.push_back(30); //1,利用迭代器访问容器里面的元素 for (vector ::iterator it = v1.begin(); it != v1.end(); it++) { cout << *it << " "; } cout << endl; //2,利用[]访问容器里面的元素 for (int i = 0; i < v1.size(); i++) { cout << v1[i] << " "; } cout << endl; //3,利用at函数访问容器中的元素 for (int j = 0; j < v1.size(); j++) { cout << v1.at(j) << " "; } cout << endl; //获取容器中的第一个元素 cout << "第一个元素为:" << v1.front() << endl; //获取容器中的最后一个元素 cout << "最后一个元素为:" << v1.back() << endl; } int main() { test01(); system("pause"); return 0; } 功能描述:实现两个容器内元素进行互换
函数原型:
swap(vec); //将vec与本身的元素互换#include2.8 vector预留空间#include #include using namespace std; //打印接口 void printVector(vector & v1) { for (vector ::iterator it = v1.begin(); it != v1.end(); it++) { cout << *it << " "; } cout << endl; } //普通操作 void test01() { cout << "交换前" << endl; vector v1; for (int i = 0; i < 10; i++) { v1.push_back(i); } printVector(v1); vector v2; for (int j = 10; j > 0; j--) { v2.push_back(j); } printVector(v2); cout << "交换后" << endl; v1.swap(v2); printVector(v1); printVector(v2); } //实际操作 --- 收缩容器 void test02() { vector v; for (int i = 0; i < 10000; i++) { v.push_back(i); } v.resize(3); //只保留前三个值 cout << "v的容量为:" << v.capacity() << endl; //容量很大 cout << "v的容量为:" << v.size() << endl; //大小为3,这样就说明开辟的空间有点多了 //vector (v)--匿名对象 //这里是拷贝构造利用v初始化一个匿名对象,空间大小为3 vector (v).swap(v); cout << "v的容量为:" << v.capacity() << endl; cout << "v的容量为:" << v.size() << endl; } int main() { //test01(); test02(); system("pause"); return 0; } 功能描述:减少vector在动态扩展容量时的扩展次数
函数原理:
reserve(int len) //容量预留len个元素长度,预留位置不初始化,元素不可访问#include#include #include using namespace std; void test01() { vector v1; //计算开辟空间次数 int num = 0; int* p = NULL; v1.reserve(100000); //提前预留100000空间大小,下面就会值开辟一次空间 for (int i = 0; i < 100000; i++) { v1.push_back(i); if (p != &v1[0]) { p = &v1[0]; //每次开辟新空间,地址就会发生改变 num++; } } cout << "num= "< 3 deque容器 3.1 deque容器基本概念 功能:双端数组。可以对头端进行插入删除操作
deque和vector的区别:
- vector对头部的插入删除效率低,数据量越大,效率越低
- deque相对而言,对头部的插入删除速度比vector快
- vector访问元素时的速度会比deque快,这和两者内部实现有关
deque的内部工作原理:
deque内部有个中控器,维护没断缓冲区中的内容,缓冲区存放真实数据,中控器维护的每个缓冲区的地址,使得使用deque时像一片连续的内存空间。deque容器的迭代器支持随机访问的
3.2 deque构造函数功能描述:deque容器构造
函数原型:
dequedeqT; //默认构造形式 deque(beg, end); //构造函数将[beg,end]区间的元素拷贝给自身 deque(n,elem); //构造函数将n个elem拷贝给自身 deque(const deque &deq) //拷贝构造函数 #include3.3 deque赋值操作#include #include using namespace std; //当使用const修饰变量的时候,也就是只读状态,迭代器就需要换成const_iterator void printDeque(const deque & d) { for (deque ::const_iterator it = d.begin(); it != d.end(); it++) { //*it = 100; 因为是只读状态,所以这里就不能修改了 cout << *it << " "; } cout << endl; } void test01() { deque d1; for (int i = 0; i < 10; i++) { d1.push_back(i); } printDeque(d1); deque d2(d1.begin(), d1.end()); printDeque(d2); deque d3(10, 100); printDeque(d3); deque d4(d3); printDeque(d4); } int main() { test01(); system("pause"); return 0; } 功能描述:给deque容器进行赋值
函数原型:
deque& operator=(const deque &deq); //重载等号操作符 assign(beg, end); //将[beg, end]区间中的数据拷贝赋值给本身 assign(n, elem); //将n个elem拷贝赋值给本身#include3.4 deque大小操作#include #include using namespace std; //当使用const修饰变量的时候,也就是只读状态,迭代器就需要换成const_iterator void printDeque(const deque & d) { for (deque ::const_iterator it = d.begin(); it != d.end(); it++) { //*it = 100; 因为是只读状态,所以这里就不能修改了 cout << *it << " "; } cout << endl; } void test01() { deque d1; for (int i = 0; i < 10; i++) { d1.push_back(i); } printDeque(d1); //operator= 赋值 deque d2; d2 = d1; printDeque(d2); //assign函数赋值 deque d3; d3.assign(d2.begin(), d2.end()); printDeque(d3); deque d4; d4.assign(10, 100); printDeque(d4); } int main() { test01(); system("pause"); return 0; } 功能描述:对deque容器的大小进行操作
函数原型:
deque.empty(); //判断容器是否为空 deque.size(); //返回容器中元素的个数 deque.resize(num); //重新指定容器的长度为num,容容器变长,则以默认值哦填充新位置 //如果容器变短,则末尾超出容器长度的元素删除 deque.resize(nnu, elem) //重新指定容器的长度为num,若容器变长,则以elem值填充新位置 //如果容器变短,则末尾超出容器长度的元素被删除#include3.5 deque插入和删除数据#include #include using namespace std; //当使用const修饰变量的时候,也就是只读状态,迭代器就需要换成const_iterator void printDeque(const deque & d) { for (deque ::const_iterator it = d.begin(); it != d.end(); it++) { //*it = 100; 因为是只读状态,所以这里就不能修改了 cout << *it << " "; } cout << endl; } void test01() { deque d1; for (int i = 0; i < 10; i++) { d1.push_back(i); } printDeque(d1); if (d1.empty() == true) { cout << "deque容器为空" << endl; } else { cout << "deque容器不为空" << endl; cout << "deque容器的大小" << d1.size() << endl; //deque容器没有容量的概念 } //重新指定大小 d1.resize(15); d1.resize(15, 1); //只有比原来大的时候才会填充1 printDeque(d1); } int main() { test01(); system("pause"); return 0; } 功能描述:向deque容器中插入和删除数据
函数原型:
两端插入操作:
push_back(elem); //在容器末尾插入elem push_front(elem); //在容器头部插入一个elem pop_back(); //删除容器的最后一个数据 pop_front(); //删除容器的第一个数据指定位置操作:
insert(pos,elem); //在pos位置插入一个elem元素的拷贝,返回新数据的位置 insert(pos,n,elem); //在pos位置插入n个elem数据,无返回值 insert(pos,beg,end); //在pos位置插入[beg,end]区间的数据,无返回值 clear(); //清空容器中的所有数据 erase(beg,end); //删除[beg,end]区间的数据,返回下一个数据的位置 erase(pos); //删除pos位置的数据,返回下一个数据的位置#include#include #include using namespace std; //当使用const修饰变量的时候,也就是只读状态,迭代器就需要换成const_iterator void printDeque(const deque & d) { for (deque ::const_iterator it = d.begin(); it != d.end(); it++) { //*it = 100; 因为是只读状态,所以这里就不能修改了 cout << *it << " "; } cout << endl; } //两端操作 void test01() { deque d1; //尾插 d1.push_back(1); //头插 d1.push_front(2); printDeque(d1); //尾删 d1.pop_back(); printDeque(d1); //头删 d1.pop_front(); printDeque(d1); } //指定位置操作 void test02() { deque d2; d2.push_back(1); d2.push_front(2); //insert插入 d2.insert(d2.begin(),3); printDeque(d2); d2.insert(d2.end(), 2, 0); printDeque(d2); //指定位置删除 d2.erase(d2.begin()); printDeque(d2); //区间删除 d2.erase(d2.begin(),d2.begin()+2); printDeque(d2); //清空 d2.clear(); } int main() { //test01(); test02(); system("pause"); return 0; } 总结:插入和删除提供的位置都是迭代器!
3.6 deque数据存取功能描述:对deque中的数据的存取操作
函数原型:
at(int idx); //返回索引idx所指的数据 operator[]; //返回索引idx所指的数据 front(); //返回容器中的第一个数据元素 back(); //返回容器中最后一个数据元素#include#include #include using namespace std; void test01() { deque d1; d1.push_back(1); d1.push_back(2); d1.push_back(3); d1.push_front(10); d1.push_front(20); d1.push_front(30); for (int i = 0; i < d1.size(); i++) { //通过[]的方式访问所有元素 cout << d1[i] << " "; } cout << endl; for (int i = 0; i < d1.size(); i++) { //通过at函数的方式访问所有元素 cout << d1.at(i) << " "; } cout << endl; cout << "返回最后一个数据:" << d1.back() << endl; cout << "返回第一个数据:" << d1.front() << endl; } int main() { test01(); system("pause"); return 0; } 总结:不但可以使用迭代器的方式遍历数据,还可以使用[]和at函数
3.7 deque排序
功能描述:利用算法实现对deque容器进行排序
算法:
sort(iterator beg,iterator end) //对beg和end区间内的元素进行排序#include4 案例-评委打分#include #include #include using namespace std; void printDeque(deque &d) { for (int i = 0; i < d.size(); i++) { //通过[]的方式访问所有元素 cout << d[i] << " "; } cout << endl; } void test01() { deque d1; d1.push_back(1); d1.push_back(2); d1.push_back(3); d1.push_front(10); d1.push_front(20); d1.push_front(30); printDeque(d1); //排序 默认规则从小到大 sort(d1.begin(), d1.end()); printDeque(d1); } int main() { test01(); system("pause"); return 0; } 4.1 案例描述
有5名选手:选手ABCD,10个评委分别对每个选手打分,去除最高分,去除评委中的最低分,取平均分
4.2 实现步骤
- 创建五名选手,放进vector中
- 遍历vector容器,取出每一个选手,执行for循环,可以把10个评分打分存在deque容器中
- sort算法对deque容器中分数排序,去除最高和最低分
- deque容器遍历一遍。累加总分
- 获取平均分
#include5 stack容器 5.1 stack基本概念#include #include #include #include using namespace std; class Person { public: Person(string name,int sorce) { this->m_Name = name; this->m_Sorce = sorce; } string m_Name; int m_Sorce; }; void setSorce(vector &v) { for (vector ::iterator it = v.begin(); it != v.end(); it++) { deque deq; //将随机的10个数添加到deque容器中 for (int i = 0; i < 10; i++) { int sorce = rand() % 41 + 60; deq.push_back(sorce); } //将这10个数进行展示看一下 cout << (*it).m_Name << " "; for (deque ::iterator de = deq.begin(); de != deq.end(); de++) { cout << (*de) << " "; } cout << endl; //排序 sort(deq.begin(),deq.end()); //去掉最大和最小值 deq.pop_back(); deq.pop_front(); int num = 0; for (deque ::iterator de = deq.begin(); de != deq.end(); de++) { num += (*de); } (*it).m_Sorce = num / deq.size(); } } void showSorce(vector & v) { for (vector ::iterator it = v.begin(); it != v.end(); it++) { cout << (*it).m_Name << " 平均分:" << (*it).m_Sorce << endl; } } int main() { vector v; //1,创建5名选手,放进vector for (int i = 0; i < 5; i++) { string Num = "ABCDE"; string Name = "选手"; Name += Num[i]; Person p(Name, 0); v.push_back(p); } #if 0 //测试5个选手是否放进vector容器中 for (vector ::iterator it = v.begin(); it != v.end(); it++) { cout << "姓名:" << it->m_Name << " 分数: " << it->m_Sorce << endl; } #endif //2,设置分数 setSorce(v); //3,展示平均分 showSorce(v); system("pause"); return 0; } 概念:stack是一种先进后出的数据结构,他只有一个出口
栈中只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为
栈中进入数据称为----入栈push
栈中弹出数据称为----出栈pop
5.2 stack常用接口功能描述:栈容器常用的对外接口
构造函数:
stackstk; //stack采样模板类实现,stack对象默认构造方式 stack(const stack &stk); //拷贝构造函数 赋值操作:
stack& operator=(const stack &stk) //重载等号操作符数据存取:
push(elem); //向栈顶添加元素 pop(); //从栈顶移除第一个元素 top(); //返回栈顶元素大小操作:
empty(); //判断堆栈是否为空 size(); //返回栈的大小#include6 queue容器 6.1 queue基本概念#include #include using namespace std; //stack(栈)的接口 void test01() { stack 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; } 概念:queue是一种先进先出的数据结构,它有两个出口
队列容器允许从一段新增数据,从另一端移除数据
队列中的队头和队尾才可以被外界使用,因此队列不允许有遍历行为
队列中的进数据称为----入队push
队列中的出数据称为----出队pop
#include7 list容器 7.1 list基本概念#include #include using namespace std; //queue(队列)的接口 void test01() { queue q; //入栈 q.push(10); q.push(20); q.push(30); //查看队列中的元素 先进后出 可以查看队头和队尾 while (!q.empty()) { //查看 cout << "队头元素为:" << q.front() << endl; //查看 cout << "队尾元素为:" << q.back() << endl; //出栈 q.pop(); } cout << "剩下多少个元素" << q.size() << endl; } int main() { test01(); system("pause"); return 0; } 功能:将数据进行链式存储
链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的
链表的组成:链表由一系列结点组成
结点的组成:一个是存储数据元素的数据域,另一个是存储下一个节点地址的指针域
STL中的链表是一个双向循环链表
由于链表的存储方式并不是连续的内存空间,因此链表list的迭代器只支持前移和后移,属于双向迭代器
list的优点:
- 采用动态存储分配,不会造成内存的浪费和溢出
- 链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素
list的缺点:
- 链表灵活,但是空间(指针域)和时间(遍历)额外耗费较大
list有一个重要的性质,插入和删除操作都不会造成原有的list迭代器失效,这在vector是不成立的
总结:STL中list和vector是两个最常用到的容器,各有优缺点
7.2 list构造函数功能描述:创建list容器
函数原型:
listlst; //list采用模板类实现,对象的默认构造形式 list(beg,end); //构造函数将【beg,end】区间中的元素拷贝给本身 list(n,elem); //构造函数将n个elem拷贝给本身 list(const list &lst) //拷贝构造函数 #include7.3 list赋值和交换#include #include using namespace std; void printList(list
&v) { for (list ::iterator it = v.begin(); it != v.end(); it++) { cout << (*it) << " "; } cout << endl; } void test01() { //默认构造 list L1; //插入数据 L1.push_back(10); L1.push_back(20); L1.push_back(30); printList(L1); list L2(L1.begin(),L1.end()); printList(L2); list L3(L2); //拷贝构造 printList(L2); list L4(2,100); //n个elem printList(L2); } int main() { test01(); system("pause"); return 0; } 功能描述:给list容器进行赋值,以及交换容器
函数原型:
assign(beg,end) //将【beg,end】区间的数据拷贝赋值给本身 assign(n,elem) //将n个elem拷贝赋值给本身 list& operator=(const list &lst) //重载等号运算符 swap(lst) //将lst与本身的元素互换#include7.4 list大小操作#include #include using namespace std; void printList(list
&v) { for (list ::iterator it = v.begin(); it != v.end(); it++) { cout << (*it) << " "; } cout << endl; } //赋值 void test01() { //默认构造 list L1; //插入数据 L1.push_back(10); L1.push_back(20); L1.push_back(30); printList(L1); //operator= 赋值 list L2; L2 = L1; printList(L2); //assign赋值操作 list L3; L3.assign(L2.begin(), L2.end()); printList(L3); list L4; L4.assign(10, 100); printList(L4); } //交换 void test02() { list L1; //插入数据 L1.push_back(10); L1.push_back(20); L1.push_back(30); list L2; L2.assign(10, 100); cout << "交换前" << endl; printList(L1); printList(L2); L1.swap(L2); cout << "交换后" << endl; printList(L1); printList(L2); } int main() { test01(); test02(); system("pause"); return 0; } 功能描述:对list容器的大小进行操作
函数原型:
size(); //返回容器中元素的个数 empty(); //判断容器是否为空 resize(num); //重新指定容器的长度为num,容容器变长,则以默认值填充新位置 //如果容器变短,则末尾超出容器长度的元素被删除 resize(num,elem) //重新指定容器的长度为num,容容器变长,则以elem填充新位置 //如果容器变短,则末尾超出容器长度的元素被删除#include7.5 list插入和删除#include #include using namespace std; void printList(list
&v) { for (list ::iterator it = v.begin(); it != v.end(); it++) { cout << (*it) << " "; } cout << endl; } //赋值 void test01() { //默认构造 list L1; //插入数据 L1.push_back(10); L1.push_back(20); L1.push_back(30); printList(L1); cout << "L1的大小" << L1.size() << endl; if (L1.empty()) { cout << "L1为空" << endl; } else { cout << "L1为不为空" << endl; } L1.resize(5); printList(L1); } int main() { test01(); system("pause"); return 0; } 功能描述:对list容器进行数据的插入和删除
函数原型:
push_back(elem); //在容器尾部加入一个元素 pop_back(); //删除容器尾部最后一个元素 push_front(elem); //在容器头部加入一个元素 pop_front(); //删除容器头部第一个元素 insert(pos,elem); //在pos位置插入一个elem,返回新数据的位置 insert(pos,n,elem); //在pos位置插入n个elem数据,无返回值 insert(pso,beg,end); //在pos位置插入【beg,end】区间的数据,无返回值 clear(); //移除容器中的所有数据 erase(beg,end); //删除【beg,end】区间的数据,返回下一个数据的位置 erase(pos); //删除pos位置的数据,返回下一个数据的位置 remove(elem); //删除容器中所有与elem值匹配的元素#include7.6 数据存取#include #include using namespace std; void printList(list
&v) { for (list ::iterator it = v.begin(); it != v.end(); it++) { cout << (*it) << " "; } cout << endl; } //赋值 void test01() { list L1; //尾插 L1.push_back(10); L1.push_back(20); L1.push_back(30); //头插 L1.push_front(100); L1.push_front(200); L1.push_front(300); printList(L1); //尾删和头删 L1.pop_back(); L1.pop_front(); printList(L1); //insert插入 list ::iterator it = L1.begin(); //L1.insert(it + 2, 0); //这里直接加一个int的类型的数据就是直接报错,是因为链表的地址不是连续的,这样是找不到指定位置的 //但是可以L1.insert(++it, 0),可以说明链表的迭代器只能前置加1 L1.insert(++it, 1000); printList(L1); //erase删除 L1.erase(++it); printList(L1); //remove删除 L1.remove(1000); printList(L1); //clear清除 L1.clear(); printList(L1); } int main() { test01(); system("pause"); return 0; } 功能描述:对list容器中的数据存取
函数原型:
front(); //返回第一个元素 back(); //返回最后一个元素#include#include #include using namespace std; void printList(list
&v) { for (list ::iterator it = v.begin(); it != v.end(); it++) { cout << (*it) << " "; } cout << endl; } //赋值 void test01() { list L1; //尾插 L1.push_back(10); L1.push_back(20); L1.push_back(30); cout << "第一个元素" << L1.front() << endl; cout << "最后一个元素" << L1.back() << endl; //cout << L1[0] 错误,不支持[]方式访问 //cout << L1.at(0) 错误,不支持at方式访问 //list容器的迭代器是双向迭代器,不支持随机访问 例如L1.begin()+3 } int main() { test01(); system("pause"); return 0; } 总结:
7.7 list反转和排序
- list容器不可以通过[]或者at方式访问数据
- 返回第一个元素---front
- 返回最后一个元素---back
功能描述:将容器中的元素反转,以及将容器中的数据进行排序
函数原型:
reverse(); //反转链表 sort(); //链表排序#include8 set/multiset 容器 8.1 set基本概念#include #include using namespace std; void printList(list
&v) { for (list ::iterator it = v.begin(); it != v.end(); it++) { cout << (*it) << " "; } cout << endl; } //仿函数 bool mySort(int v1, int v2) { return v1 > v2; } void test01() { list L1; //尾插 L1.push_back(50); L1.push_back(20); L1.push_back(30); L1.push_back(40); L1.push_back(10); cout << "反转前" << endl; printList(L1); cout << "反转后" << endl; L1.reverse(); printList(L1); cout << "默认排序" << endl; //所有不支持随机访问迭代器的容器,不可以使用标志算法 例如:sort(L1.begin(),L1.end()) //不支持随机访问的迭代器的容器,内部会提供对应一些算法 L1.sort(); printList(L1); cout << "从大到小排序" << endl; L1.sort(mySort); printList(L1); } int main() { test01(); system("pause"); return 0; } 简介:所有元素都会在插入时自动被排序
本质:set/multiset属于关联式容器,底层结构是用二叉树实现。
set和multiset区别:set不允许容器中有重复的元素,mutliset允许容器中有重复的元素
8.2 set构造和赋值功能描述:创建set容器以及赋值
构造:
setst; //默认构造函数 set(const set &s); //拷贝构造函数 赋值:
set& operator=(const set &s); //重载等号操作符#include#include #include using namespace std; void printSet(set &s) { for (set ::iterator it = s.begin(); it != s.end(); it++) { cout << (*it) << " "; } cout << endl; } void test01() { //set容器 set s; //insert插入数据 set容器只允许insert插入,且插入的数据会自动排序 s.insert(20); s.insert(10); s.insert(30); s.insert(20); //set不允许插入相同的数,其实就是插入相同的数相当于白插,没有用 printSet(s); //拷贝构造 set s1(s); printSet(s1); //operator= 赋值 set s2; s2 = s1; printSet(s2); } int main() { test01(); system("pause"); return 0; } 总结:set容器插入只能用inset,且插入的数据会自动排序
8.3 set大小和交换功能描述:统计set容器大小以及交换set容器
函数原型:
size(); //返回容器中元素的个数 empty(); //判断容器是否为空 swap(st); //减缓两个集合容器#include8.4 set插入和删除#include #include using namespace std; void printSet(set &s) { for (set ::iterator it = s.begin(); it != s.end(); it++) { cout << (*it) << " "; } cout << endl; } void test01() { //set容器 set s; //insert插入数据 set容器只允许insert插入,且插入的数据会自动排序 s.insert(20); s.insert(10); s.insert(30); s.insert(20); //set不允许插入相同的数,其实就是插入相同的数相当于白插,没有用 printSet(s); if (s.empty()) { cout << "容器为空" << endl; } else { cout << "容器不为空" << endl; cout << "容器中元素为" << s.size() << endl; } //交换 set s2; s2.insert(20); s2.insert(10); s2.swap(s); printSet(s); printSet(s2); } int main() { test01(); system("pause"); return 0; } 功能描述:set容器进行插入数据和删除数据
函数原型:
insert(elem); //在容器中插入元素 clear(); //清除容器中的所有元素 erase(pos); //清除指定位置的元素 erase(beg,end); //清除【beg,end】区间的元素 erase(elem); //清除容器中所有elem元素#include8.5 set查找和统计#include #include using namespace std; void printSet(set &s) { for (set ::iterator it = s.begin(); it != s.end(); it++) { cout << (*it) << " "; } cout << endl; } void test01() { //set容器 set s; //insert插入数据 set容器只允许insert插入,且插入的数据会自动排序 s.insert(20); s.insert(10); s.insert(30); s.insert(40); printSet(s); //删除 s.erase(s.begin()); printSet(s); s.erase(30); printSet(s); //清空 s.erase(s.begin(), s.end()); s.clear(); printSet(s); } int main() { test01(); system("pause"); return 0; } 功能描述:对set容器进行查找数据以及统计数据
函数原型:
find(elem); //查找elem是否存在,若存在,返回元素迭代器,不存在,返回set.end() count(elem); //统计elem的元素个数#include#include #include using namespace std; void printSet(set &s) { for (set ::iterator it = s.begin(); it != s.end(); it++) { cout << (*it) << " "; } cout << endl; } void test01() { //set容器 set s; //insert插入数据 set容器只允许insert插入,且插入的数据会自动排序 s.insert(20); s.insert(10); s.insert(30); s.insert(40); printSet(s); //查找,返回的是一个迭代器,所以也需要用一个迭代器来接收 set ::iterator pos = s.find(30); //判断是否找到的方法 if (pos == s.end()) { cout << "未找到元素" << endl; } else { cout << "找到元素:" << (*pos) << endl; } //统计确定元素的个数,对于set容器而言,要么是1要么是0,因为容器中不允许插入相同值 cout << "30的个数:" << s.count(30) << endl; } int main() { test01(); system("pause"); return 0; } 总结:
8.6 set和multiset区别
- 查找 --- find (返回的是迭代器)
- 统计 --- count (对于set,结果为1或者0)
学习目标:掌握set和multise的区别
区别:
- set不可以插入重复值,而multiset可以
- set插入数据的同时会返回插入结果,表示插入是否成功
- multiset不会检测数据,因此可以插入重复数据
#include#include #include using namespace std; void test01() { //set容器 set s; //set容器插入数据会返回pair类型,这个类型会告诉你插入的位置(迭代器),还有插入是否成功(bool) pair ::iterator, bool> ret = s.insert(10); if (ret.second) { cout << "第一次插入成功" << endl; } else { cout << "第一次插入失败" << endl; } ret = s.insert(10); if (ret.second) { cout << "第二次插入成功" << endl; } else { cout << "第二次插入失败" << endl; } //multiset可以插入重复值,他的返回值是迭代器 multiset ms; ms.insert(10); ms.insert(10); ms.insert(10); for (multiset ::iterator it = ms.begin(); it != ms.end(); it++) { cout << (*it) << " "; } cout << endl; } int main() { test01(); system("pause"); return 0; } 总结:
8.7 pair对组创建
- 如果不允许插入重复数据可以利用set
- 如果允许插入重复数据可以利用multiset
功能描述:成对出现的数据,利用对组可以返回两个数据
两种创建方式:
pairp(value1,value2); pair p = make_pair(value1,value2); #include#include using namespace std; void test01() { //对组,想要创建两个数据的时候可以使用对组 //第一种创建方式 pair p("jackie", 20); cout << "姓名:" << p.first << " 年龄:" << p.second << endl; //第一种创建方式 pair p1 = make_pair("jackie", 20); cout << "姓名:" << p1.first << " 年龄:" << p1.second << endl; } int main() { test01(); system("pause"); return 0; } 总结:两种方式都可以创建对组,选择一直即可
8.8 set容器排序学习目标:set容器默认排序规则从小到大,掌握如何改变排序规则
主要技术点:利用仿函数,可以改变排序规则
set存放内置的数据类型
#include#include #include using namespace std; class MyCompare { public: //重载()运算符 仿函数 bool operator()(int value1, int value2)const { return value1 > value2; } }; void test01() { //指定排序规则 从大到小 set s; s.insert(40); s.insert(20); s.insert(30); s.insert(10); for (set ::iterator it = s.begin(); it != s.end(); it++) { cout << (*it) << " "; } cout << endl; } int main() { test01(); system("pause"); return 0; } 总结:利用仿函数可以指定set容器的排序规则
set存放自定义的数据类型
#include#include #include using namespace std; class Person { public: Person(string name, int age) { this->Name = name; this->Age = age; } string Name; int Age; }; class MyCompare { public: //重载()运算符 仿函数 bool operator()(Person p1, Person p2)const { return p1.Age > p2.Age; } }; void test01() { //自定义的数据类型,必须指定排序规则,因为默认的排序规则不知道自定义的数据类型如何排序 set s; Person p1("张飞", 24); Person p2("关羽", 22); Person p3("刘备", 27); Person p4("赵云", 25); s.insert(p1); s.insert(p2); s.insert(p3); s.insert(p4); for (set ::iterator it = s.begin(); it != s.end(); it++) { cout << it->Name << " " << it->Age << endl; } } int main() { test01(); system("pause"); return 0; } 总结:对于自定义的数据类型,set容器必须指定排序规则才能插入数据
9 map/multimap容器 9.1 map基本概念简介:
- map中所有的元素都是pair
- pair中的第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
- 所有元素都会根据元素的键值自动排序
本质:map/multimap属于关联式容器,底层结构是用二叉树实现
优点:可以根据key值快速找到value值
map/multimap的区别:map不允许容器中有重复的key值元素,multimap允许中有重复的key值
9.2 map构造和赋值功能描述:对map容器进行构造和赋值操作
函数原理:
构造:
mapmp; //map默认构造函数 map ; //拷贝构造函数 赋值:
map& operator=(const map &mp); //重载等号操作符#include9.3 map大小和交换#include #include 功能描述:统计map容器大小以及交换map容器
函数原型:
size(); //返回容器中元素的数目 empty(); //判断容器是否为空 swap(st); //交换两个容器集合#include9.4 map插入和删除#include #include 功能描述:map容器进行插入数据和删除数据
函数原型:
insert(elem); //在容器中插入元素 clear(); //清除所有元素 erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器 erase(beg,end); //删除区间的所有元素,返回下一个元素的迭代器 erase(key); //删除容器中值为key的元素#include#include #include 总结:使用[]的方式插入,如果里面原先有对应的key值,会被覆盖,其他方式则不会,所以不推荐第四种插入方式。
9.5 map查找和统计功能描述:对map容器进行查找数据以及统计数据
函数原型:
fine(key); //查找key是否存在,若存在,返回该键的元素的迭代器,若不存在,返回map.end(); count(key); //统计key的元素的个数#include#include #include 总结:查找 --- find 返回的是迭代器
统计 --- count 对于map而言,结果为1或者0
9.6 map容器排序学习目标:map容器默认排序规则为按照key值进行从小到大的排序,掌握如何改变排序规则
主要技术点:利用仿函数,可以改变排序规则
#include#include #include 总结:
- 利用仿函数可以指定map容器的排序规则
- 对于自定义的数据类型,map必须指定排序规则,同set容器



