当前位置: 首页 > news >正文

pc端微信端网站建设磐安县住和城乡建设局网站

pc端微信端网站建设,磐安县住和城乡建设局网站,小程序开发网上商城,捕鱼游戏网站制作模板C提高编程1.模板1.1模板的概念1.2函数模板1.2.1函数模板语法1.2.2函数模板注意事项1.2.3函数模板案例1.2.4普通函数与函数模板的区别1.2.5普通函数与函数模板的调用规则1.2.6模板的局限性1.3类模板1.3.1类模板语法1.3.2类模板和函数模板区别1.3.3类模板中成员函数创建时机1.3.4… C提高编程1.模板1.1模板的概念1.2函数模板1.2.1函数模板语法1.2.2函数模板注意事项1.2.3函数模板案例1.2.4普通函数与函数模板的区别1.2.5普通函数与函数模板的调用规则1.2.6模板的局限性1.3类模板1.3.1类模板语法1.3.2类模板和函数模板区别1.3.3类模板中成员函数创建时机1.3.4类模板对象做函数参数1.3.5类模板与继承1.3.6类模板成员函数类外实现1.3.7类模板分文件编写1.3.8类模板与友元1.3.9类模板案例2.STL初始2.1STL的诞生2.2STL的基本概念2.3STL六大组件2.4STL容器、算法、迭代器2.4.1容器2.4.2算法2.4.3迭代器2.5容器算法迭代器初识2.5.1 vector存放内置数据类型2.5.2vector存放自定义数据类型2.5.3容器嵌套3.STL-常用容器3.1string容器3.1.1string基本概念3.1.2string构造函数3.1.3string赋值操作3.1.4string字符拼接3.1.5string查找和替换3.1.6string字符串比较3.1.7string字符存取3.1.8string插入和删除3.1.9string子串3.2vector容器3.2.1vector基本概念1.功能2.vector与普通数组区别3.动态扩展3.2.2vector构造函数3.2.3vector赋值操作3.2.4vector容量和大小3.2.5vector插入和删除3.2.6vector数据存取3.2.7vector互换容器3.2.8vector预留空间3.3deque容器3.3.1deque容器基本概念3.3.2deque构造函数3.3.3deque赋值操作3.3.4deque大小操作3.3.5deque插入删除3.3.6deque数据存取3.3.7deque排序3.4案例3.5stack容器3.5.1stack基本概念3.5.3stack常用接口1.构造函数2.赋值操作3.数据存取4.大小操作3.6queue容器3.6.1queue基本概念3.6.2queue常用接口1.构造函数2.赋值操作3.数据存取4.大小操作3.7list容器3.7.1list基本概念3.7.2list构造函数3.7.3list赋值和交换3.7.4list大小操作3.7.5list插入和删除3.7.6list数据存取3.7.7list反转和排序3.8set/multiset容器3.8.1set基本概念1.简介2.本质3.set和multiset区别3.8.2set构造和赋值3.8.3set大小和交换3.8.4set插入和删除3.8.5set查找和统计3.8.6set和multiset区别3.8.7pair对组创建3.8.8set容器排序3.9map/multimap容器3.9.1map基本概念1.简介2.本质3.优点4.map和multimap区别3.9.2map构造和赋值3.9.3map大小和交换3.9.4插入和删除3.9.5map查找和统计3.9.6map容器排序1.模板 1.1模板的概念 模板就是建立通用的摸具大大提高复用性模板的特点 模板不可以直接使用它只是一个框架模板的通用并不是万能的 1.2函数模板 C中另一种编程思想称为泛型编程主要利用的技术就是模板C提供两种模板机制:函数模板和类模板 1.2.1函数模板语法 函数模板作用 建立一个通用函数其函数返回值类型和形参类型可以不具体定制用一个虚拟的类型来代表 语法 templatetypename T 函数声明或定义解释 template — 声明创建模板typename — 表面起后面的符号是一种数据类型可以用class替代T — 通用的数据类型加粗样式名称可以替换通常为大写字母 #includeiostream using namespace std;//函数模板 templatetypename T //声明一个模板告诉编译器后面代码紧跟的T不要报错T是一个通用类型 void mySwap(T a, T b) {T temp a;a b;b temp; }void test1() {// 两种方式使用函数模板// 1.自动类型推导int a 20;int b 40;mySwap(a, b);cout a a endl; // 40cout b b endl; // 20// 2.显示指定类型mySwapint(a, b);cout a a endl; // 20cout b b endl; // 40 }int main() {test1();system(pause);return 0; }1.2.2函数模板注意事项 注意事项 自动类型推导必须推导出一致的数据类型T才可以使用模板必须要确定出T的数据类型才可以使用 #includeiostream using namespace std;templatetypename T void mySwap(T a,T b) {T temp a;a b;b temp; }//模板必须要确定出T的数据类型才可以使用 templatetypename T void func() {cout func的调用 endl; }void test1() {int a 10;int b 30;char c a;mySwap(a, b);// mySwap(a, c); // error,推导不出不一致的T类型cout a a endl;cout b b endl; } void test2() {funcint(); }int main() {//test1();test2();system(pause);return 0; }1.2.3函数模板案例 #includeiostream using namespace std;templatetypename T void mySwap(T a,T b) {T temp a;a b;b temp; } templatetypename T void arrSort(T arr[],int len) {for (int i 0;i len;i) {int max i;for (int j i 1;j len;j) {if (arr[max] arr[j]) {max j;}}if(max ! i){mySwap(arr[max], arr[i]);}} } templatetypename T void showArr(T arr[], int len) {for (int i 0;i len;i) {cout arr[i] ;}cout endl; } void test1() {char arr[] abefcej;arrSortchar(arr, sizeof(arr) / sizeof(char));showArr(arr, sizeof(arr) / sizeof(char)); } int main() {test1();system(pause);return 0; }1.2.4普通函数与函数模板的区别 区别 普通函数调用时可以发生自动类型转换(隐式类型转换)函数模板调用时如果利用自动类型推导不会发生隐式类型转换如果利用显示指定类型的方式可以发生隐式类型转换 #includeiostream using namespace std;//函数模板 templatetypename T T myAdd2(T a, T b) {return a b; }// 普通函数 int myAdd(int a, int b) {return a b; } void test1() {int a 12;int b 13;char c s;cout myAdd(a, b) endl;// 25// 隐藏类型转化cout myAdd(a, c) endl;// 127cout myAdd2(a, b) endl;// 25// 自动类型推导 -- 不能自动转换(隐式转换)//cout myAdd2(a, c) endl;// error//显示指定类型cout myAdd2int(a, c) endl;// 127 }int main() {test1();system(pause);return 0; }总结: 建议使用显示指定类型的方式调用函数模板自己可以确定通用类型 1.2.5普通函数与函数模板的调用规则 调用规则 如果函数模板和普通函数都可以实现优先调用普通函数可以通过空模板参数列表来强制调用函数模板函数模板也可以发生重载如果函数模板可以产生更好的匹配优先调用函数模板 #includeiostream using namespace std;void myPrint(int a,int b) {cout 调用普通函数 endl; }template typename T void myPrint(T a, T b) {cout 调用函数模板 endl; }template typename T void myPrint(T a, T b,T c) {cout 调用函数模板的重载 endl; }void test1() {int a 10;int b 20;//函数模板和普通函数都可以调用优先调用普通函数//普通函数只有函数声明调用会报错myPrint(a, b);//空模板参数列表强制调用函数模板myPrint(a, b);//函数模板可以发生重载myPrint(a, b, 20);//函数模板产生更好的匹配优先调用函数模板char a1 a;char b1 b;myPrint(a1, b1);// 调用函数模板 }int main() {test1();system(pause);return 0; }1.2.6模板的局限性 局限性 模板的通用性并不是万能的 利用具体化的模板可以解决自定义类型的通用化 #includeiostream using namespace std; #includestring class Person { public:Person(string name,int age){this-m_Name name;this-m_Age age;}string m_Name;int m_Age; };templatetypename T bool myCompare(T a, T b) {if (a b) {return true;}else {return false;} } // 利用具体化Person的版本实现代码具体优先调用 template bool myCompare(Person p1, Person p2) {if (p1.m_Name p2.m_Name p1.m_Age p2.m_Age) {return true;}else {return false;} }void test1() {int a 10;int b 20;bool res myCompare(a, b);if (res) {cout ab endl;}else {cout a ! b endl;} } void test2() {Person person1(Jack, 20);Person person2(Jack, 20);bool res myCompare(person1, person2);if (res) {cout person1 person2 endl;}else {cout person1 ! person2 endl;} } int main() {//test1();test2();system(pause);return 0; }1.3类模板 1.3.1类模板语法 类模板的作用 建立一个通用类类中的成员 数据类型 可以不具体规定用一个虚拟的类型来代表 语法 templateclass T 类template — 声明创建模板class — 表明其后免得符号是一种数据类型可以用 typename 代替T — 通用的数据类型名称可以替换通常为大写字幕 #includeiostream using namespace std; #includestring//类模板 templateclass NameType,class AgeType class Person { public:Person(NameType name,AgeType age) {this-m_Name name;this-m_Age age;}void showPerson() {cout name this-m_Name ,age this-m_Age endl;}NameType m_Name;AgeType m_Age;}; void test1() {Personstring, int p1(类模板, 20);p1.showPerson(); }int main() {test1();system(pause);return 0; }1.3.2类模板和函数模板区别 类模板和函数模板的区别 类模板没有自动类型推导的使用方式类模板在模板参数列表中可以有默认参数 #includeiostream using namespace std;//类模板和函数模板的区别//类模板在参数列表中可以有默认参数 AgeType int templateclass NameType,class AgeType int class Person { public:Person(NameType name,AgeType age){this-m_Name name;this-m_Age age;}void showPerson(){cout name this-m_Name ,age this-m_Age endl;}NameType m_Name;AgeType m_Age; };void test1() {// 类模板没有自动化类型推导使用方式//Person p(数字化, 10);Personstring, int p(数字化, 10);p.showPerson(); } void test2() {Personstring p(智能化, 10);p.showPerson(); } int main() {//test1();test2();system(pause);return 0; }1.3.3类模板中成员函数创建时机 类模板中成员函数和普通类中成员函数创建时机是有区别的 普通类中成员函数一开始就可以创建类模板中成员函数在调用时才创建 #includeiostream using namespace std;class Person1 { public:void showPerson1(){cout Person1 show endl;} };class Person2 { public:void showPerson2(){cout Person2 show endl;} };templateclass T class MyClass { public:T obj;//类模板的成员函数void fun1() {obj.showPerson1();}void fun2() {obj.showPerson2();} };void test1() {MyClassPerson1 m;m.fun1();// 类模板中成员函数在调用时创建// m.fun2(); } int main() {system(pause);return 0; }1.3.4类模板对象做函数参数 类模板实例化出的对象向函数传参的方式 指定传入的类型 — 直接显示对象的数据类型 推荐参数模板化 — 将对象中的参数变为模板进行传递整个类模板化 — 将这个对象类型 模板化 进行传递 #includeiostream using namespace std; templateclass T,class K class Person { public:Person(T name, K age) {this-m_Name name;this-m_Age age;}void showPerson() {cout name this-m_Name ,age this-m_Age endl;}T m_Name;K m_Age;}; // 1.指定传入类型推荐 void printPerson1(Personstring, int p) {p.showPerson(); }void test1() {Personstring, int p(智能化, 120);printPerson1(p); }// 2.参数模板化 templateclass T,class K void printPerson2(PersonT, K p) {p.showPerson();//查看推导的类型cout T的类型为: typeid(T).name() endl; //class std::basic_stringchar,struct std::char_traitschar,class std::allocatorchar cout K的类型为: typeid(K).name() endl; //int }void test2() {Personstring, int p(数字化, 10);printPerson2(p); }// 3.整个类模板化 templateclass T void printPerson3(T p) {p.showPerson();cout T的数据类型: typeid(T).name() endl; } void test3() {Personstring, int p(自动化, 30);printPerson3(p); }int main() {//test1();//test2();test3();system(pause);return 0; }1.3.5类模板与继承 类模板碰到继承时需要注意一下几点 当子类继承的父类是一个类模板时子类在声明的时候要指定出父类中的T类型如果不指定编译器无法给子类分配内存如果想灵活指定出父类中的T的类型子类也需要变成类模板 #includeiostream using namespace std; #includestringtemplateclass T,class K class Person { public:Person(T name, K age);/*{this-m_Name name;this-m_Age age;}*/void showPerson();/*{cout 姓名: this-m_Name 年龄 this-m_Age endl;}*/T m_Name;K m_Age;};//构造函数的类外实现 templateclass T,class K PersonT,K::Person(T name, K age) {this-m_Name name;this-m_Age age; } // 成员函数的类外实现 templateclass T,class K void PersonT, K::showPerson() {cout 姓名: this-m_Name 年龄 this-m_Age endl; }void test1() {Personstring,int p(智能组装, 8);p.showPerson(); } int main() {test1();system(pause);return 0; }1.3.6类模板成员函数类外实现 #includeiostream using namespace std; #includestringtemplateclass T,class K class Person { public:Person(T name, K age);/*{this-m_Name name;this-m_Age age;}*/void showPerson();/*{cout 姓名: this-m_Name 年龄 this-m_Age endl;}*/T m_Name;K m_Age;};//构造函数的类外实现 templateclass T,class K PersonT,K::Person(T name, K age) {this-m_Name name;this-m_Age age; } // 成员函数的类外实现 templateclass T,class K void PersonT, K::showPerson() {cout 姓名: this-m_Name 年龄 this-m_Age endl; }void test1() {Personstring,int p(智能组装, 8);p.showPerson(); } int main() {test1();system(pause);return 0; }1.3.7类模板分文件编写 类模板中成员函数创建时机是在调用阶段导致分文件编写时链接不到 解决方式: 直接包含.cpp源文件 头文件 person.h #pragma once #includeiostream using namespace std; #includestring templateclass T,class K class Person { public:Person(T name,K age);void showPerson();T m_Name;K m_Age;};源文件 person.cpp #include person.htemplateclass T, class K PersonT, K::Person(T name, K age) {this-m_Name name;this-m_Age age; }templateclass T, class K void PersonT, K::showPerson() {cout 姓名: this-m_Name 年龄 this-m_Age endl; }源文件 #includeiostream using namespace std; #includestring// 1.第一种解决方式直接包含 源文件 //#include person.cpp// 2.第二种解决方式将.h和.cpp中的内容写到一起将后缀名改为.hpp文件 #includeperson.hpp//templateclass T,class K //class Person //{ //public: // Person(T name, K age); // void showPerson(); // T m_Name; // K m_Age; //}; // //templateclass T,class K //PersonT, K::Person(T name, K age) //{ // this-m_Name name; // this-m_Age age; //} // //templateclass T,class K //void PersonT, K::showPerson() //{ // cout 姓名: this-m_Name 年龄 this-m_Age endl; //}void test1() {Personstring,int person(数据化, 20);person.showPerson(); }int main() {test1();system(pause);return 0; }将声明和实现写在同一个文件中并更改后缀名.hpphpp是约定的名称并不是强制 头文件 person.hpp #pragma once #includeiostream using namespace std; #includestring templateclass T, class K class Person { public:Person(T name, K age);void showPerson();T m_Name;K m_Age;};templateclass T, class K PersonT, K::Person(T name, K age) {this-m_Name name;this-m_Age age; }templateclass T, class K void PersonT, K::showPerson() {cout 姓名: this-m_Name 年龄 this-m_Age endl; }引入方式同上 1.3.8类模板与友元 全局函数类内实现 — 直接在类内声明友元即可全局函数类外实现 — 需要提前让编译器知道全局函数的存在 #includeiostream #includestring using namespace std;// 声明Person类 templateclass T, class K class Person;//类外实现templateclass T, class K void printPerson2(PersonT, K p) {cout -----------全局函数的类外实现----------- endl;cout 姓名: p.m_Name ,年龄: p.m_Age endl; }//类模板 templateclass T,class K class Person {// 全局函数 类内实现friend void printPerson(PersonT, K p){cout 姓名: p.m_Name ,年龄: p.m_Age endl;}//全局函数 类外实现// 加空模板参数列表// 全局函数 是类外实现需要让编译器提前知道这个函数的存在friend void printPerson2(PersonT, K p);public:Person(T name, K age){this-m_Name name;this-m_Age age;} private:T m_Name;K m_Age; };// 1.全局函数在类内实现 void test1() {Personstring, int p(Rose, 18);printPerson(p); }// 2.全局函数在类外实现 void test2() {Personstring, int p(Jack, 20);printPerson2(p); } int main() {//test1();test2();system(pause);return 0; }1.3.9类模板案例 #pragma once #includeiostream using namespace std;templateclass T class MyArray { public:MyArray(int capacity){this-m_Capacity capacity;this-m_Size 0;this-pAddress new T[this-m_Capacity];}//析构函数~MyArray(){if (this-pAddress ! NULL) {delete[] this-pAddress;this-pAddress NULL;}}//拷贝构造MyArray(const MyArray arr) {this-m_Capacity arr.m_Capacity;this-m_Size arr.m_Size;//this-pAddress arr.pAddress;//深拷贝this-pAddress new T[arr.m_Capacity];//将arr中的数据都拷贝过来for (int i 0;i this-m_Size;i){this-pAddress[i] arr.pAddress[i];}}// operator 防止浅拷贝问题MyArray operator(const MyArray arr){//先判断原来堆区是否有数据如果有先释放if (this-pAddress ! NULL){delete[] this-pAddress;this-pAddress NULL;this-m_Capacity 0;this-m_Size 0;}//深拷贝this-m_Capacity arr.m_Capacity;this-m_Size arr.m_Size;this-pAddress new T[arr.m_Capacity];for(int i 0;ithis-m_Size;i){this-m_Capacity[i] arr.m_Capacity[i];}return *this;}//尾插法void Push_Back(const T val){// 判断容量是否有空间if (this-m_Capacity this-m_Size){return;}this-pAddress[this-m_Size] val;//更新数组大小this-m_Size;}//尾删法void Pop_Back(){//让用户访问不到最后一个元素即为尾删逻辑删除if (this-m_Size 0){return;}this-m_Size--;}//通过下标方式访问数组的元素T operator[](int index){return this-pAddress[index];}//返回数组的容量int getCapacity(){return this-m_Capacity;}//返回数组的大小int getSize(){return this-m_Size;}//遍历数组void printArray(){for (int i 0;i this-m_Size;i){cout this-pAddress[i] ;}cout endl;}private:// 指针指向堆区开辟的真实数组T* pAddress;// 数据容量int m_Capacity;//数据大小int m_Size; }; #includeiostream using namespace std; #include MArray.hppvoid printArray(MyArrayint arr) {for (int i 0;i arr.getSize();i){cout arr[i] ;}cout endl; }void test1() {MyArrayint arr(5);for (int i 0;i 5;i) {//利用尾插法插入数据arr.Push_Back(i);}printArray(arr);cout arr的容量为: arr.getCapacity() endl;cout arr的容量为: arr.getSize() endl;MyArrayint arr2(arr);cout ----arr2的打印输出---- endl;printArray(arr2);arr2.Pop_Back();cout ----arr2尾删后打印输出---- endl;printArray(arr2);cout arr2的容量为: arr.getCapacity() endl;cout arr2的容量为: arr.getSize() endl;//遍历数组arr2.printArray();}int main() {test1();system(pause);return 0;}2.STL初始 2.1STL的诞生 C的面对对象和泛型编程思想目的就是复用性的提升大多数情况下数据结构和算法都未能有一套标准导致被迫从事大量重复工作为了建立数据结构和算法的一套标准诞生了STL 2.2STL的基本概念 STL(Standard Template Library,标准模板库)STL从广义上分为容器(container)、算法(algorithm)、迭代器(iterator)容器和算法之间通过迭代器进行无缝连接STL几乎所有的代码都采用了模板类或模板函数 2.3STL六大组件 STL分为六大组件 容器各种数据结构如vector、list、deque、set、map等等用来存放数据算法各种常用的算法如sort、find、copy、for_each等迭代器扮演了容器与算法之间的胶合剂仿函数行为类似函数可作为算法的某种策略适配器一种用来修饰容器或仿函数或迭代器接口的东西空间配置器负责空间的配置与管理 2.4STL容器、算法、迭代器 2.4.1容器 STL容器就是运用最广泛的一些数据结构实现出来常用的数据结构 数组链表树栈队列集合映射表 容器分为序列式容器和关联式容器 序列式容器强调值得排序序列式容器中得每个元素均有固定得位置关联式容器二叉树结构各元素之间没用严格得物理上的顺序关系 2.4.2算法 有限的步骤解决逻辑或数学上的问题算法分为: 质变算法和非质变算法 质变算法是指运算过程中会更改区间内的元素内容如拷贝、替换、删除非质变算法是指运算过程中不会更改区间内的元素内容例如查找、计数、遍历、寻找极值等等 2.4.3迭代器 容器和算法之间粘合剂提供一种方法使之能够依序寻找某个容器所含的各个元素而又无暴露该容器的内部表示方式每个容器都有自己专属的迭代器迭代器使用非常类似于指针迭代器种类: 种类功能支持运算输入迭代器对数据的只读访问只读支持、、!输出迭代器对数据的只写访问只写支持向前迭代器读写操作并能向前推进迭代器读写支持、、!双线迭代器读写操作并能向前和向后操作读写支持、--随机访问迭代器读写操作可以以跳跃的方式访问任意数据功能最强的迭代器读写支持、--、[n]、-n、、、、 常用的容器迭代器种类为双向迭代器和随机访问迭代器 2.5容器算法迭代器初识 2.5.1 vector存放内置数据类型 容器 vector算法 for_each迭代器 vectorint::iterator #includeiostream #includevector #includealgorithm using namespace std; // vector容器存放内置数据类型//遍历 void printContainer(int val) {cout val ; }void test1() {//创建了一个vector容器vectorint vec;//向容器中插入数据vec.push_back(10);vec.push_back(20);vec.push_back(30);vec.push_back(50);vec.push_back(90);vec.push_back(20);// 通过迭代器访问容器中的数据// 起始迭代器 指向容器中第一个元素vectorint::iterator itBegin vec.begin();// 结束迭代器 指向容器中最后一个元素的下一个位置vectorint::iterator itEnd vec.end();//第一种遍历方式cout while循环遍历 endl;while (itBegin ! itEnd){ cout *itBegin ;itBegin;}cout endl;//第二种遍历方式cout for循环遍历容器 endl;for (vectorint::iterator it vec.begin();it ! vec.end();it){ cout *it ;}cout endl;//第三种遍历方式for_each(vec.begin(), vec.end(), printContainer);}int main() {test1();system(pause);return 0; }2.5.2vector存放自定义数据类型 #includeiostream #includevector #includealgorithm using namespace std;// vector容器存放自定义数据类型// 自定义数据类型 class Person { public:Person(string name, int age){this-m_Name name;this-m_Age age;}string m_Name;int m_Age; };//遍历 void printInfo(Person person) {cout 标签: person.m_Name ,年限: person.m_Age endl; }void test1() {vectorPerson vp;Person p1(数字化, 10);Person p2(模块化, 23);Person p3(拟人化, 1);Person p4(智能化, 9);Person p5(树脂化, 24);Person p6(机械化, 11);//向容器添加数据vp.push_back(p1);vp.push_back(p2);vp.push_back(p3);vp.push_back(p4);vp.push_back(p5);vp.push_back(p6);//遍历容器中的数据// while方式遍历cout -----------while遍历--------- endl;vectorPerson::iterator itBegin vp.begin();vectorPerson::iterator itEnd vp.end();while (itBegin ! itEnd){cout 标签: (*itBegin).m_Name ,年限: (*itBegin).m_Age endl;itBegin;}// for方式遍历cout --------for遍历------- endl;for (vectorPerson::iterator itBegin vp.begin();itBegin ! vp.end();itBegin){cout 标签: (*itBegin).m_Name ,年限: (*itBegin).m_Age endl;}//for_each方式遍历cout --------for_each遍历------- endl;for_each(vp.begin(), vp.end(), printInfo); } int main() {test1();system(pause);return 0; }2.5.3容器嵌套 #includeiostream #includevector #includealgorithm using namespace std; // vector容器存放内置数据类型//遍历 void printContainer(int val) {cout val ; }void test1() {//创建了一个vector容器vectorint vec;//向容器中插入数据vec.push_back(10);vec.push_back(20);vec.push_back(30);vec.push_back(50);vec.push_back(90);vec.push_back(20);// 通过迭代器访问容器中的数据// 起始迭代器 指向容器中第一个元素vectorint::iterator itBegin vec.begin();// 结束迭代器 指向容器中最后一个元素的下一个位置vectorint::iterator itEnd vec.end();//第一种遍历方式cout while循环遍历 endl;while (itBegin ! itEnd){ cout *itBegin ;itBegin;}cout endl;//第二种遍历方式cout for循环遍历容器 endl;for (vectorint::iterator it vec.begin();it ! vec.end();it){ cout *it ;}cout endl;//第三种遍历方式for_each(vec.begin(), vec.end(), printContainer);}int main() {test1();system(pause);return 0; }3.STL-常用容器 3.1string容器 3.1.1string基本概念 本质string是c风格的字符串而string本质上是一个类string和char *区别 char * 是一个指针string是一个类类内部封装了char * 管理这个字符串是一个char *型的容器 3.1.2string构造函数 构造函数原型 创建空字符串 string();字符串s初始化 string(const char * s);使用一个字符串初始化另一个字符串 string(const string str);使用n个字符c初始化 string(int n,char c);#includeiostreamusing namespace std; //string构造函数void test1() {//1.默认构造函数string s1;//2.字符串初始化const char* str hello;string s2(str);cout s2 s2 endl;//3.一个字符串给另一个字符串初始化string s3(s2);cout s3 s3 endl;//使用n个字符初始化string s4(4, x);cout s4 s4 endl;}int main() {test1();system(pause);return 0; }3.1.3string赋值操作 给string字符串进行赋值赋值的函数原型 char*类型字符串 赋值给当前的字符串 string operator(const char *s)把字符串s赋值给当前字符串 string operator(const string s)字符赋值给当前字符串 string operator(char c)把字符串赋值给当前的字符串 string assign(const char *s)把字符串s的前面n个字符赋给当前字符串 string assign(const char * s,int n)把字符串s赋给当前字符串 string assgin(const string s)用n个字符c赋给当前字符串 string assign(int n,char c)#includeiostream using namespace std; #includestring //string赋值操作void test1() {string str1;str1 hello;cout str1 str1 endl;string str2;str2 str1;cout str2 str2 endl;string str3;str3 a;cout str3 str3 endl;string str4;str4.assign(hello C);cout str4 str4 endl;string str5;str5.assign(hello c,5);cout str5 str5 endl;string str6;str6.assign(str5);cout str6 str6 endl;string str7;str7.assign(4, g);cout str7 str7 endl; }int main() {test1();system(pause);return 0; }3.1.4string字符拼接 实现在字符串末尾拼接字符串函数原型 重载操作符 string operator(const char* str) string operator(const char c) string operator(const string str)把字符串s连接到当前字符串结尾 string append(const char *s)把字符串s的前n个字符连接到当前字符串结尾 string append(const char*s,int n)同operator(const string str) string append(const string s)字符串中从pos开始的n个字符连接到字符换末尾 string append(const string s,int pos,int n)str7 bbb;cout str7 str7 endl;str7.append(hello, 2, 2);cout str7 str7 endl; // gggg bbbll3.1.5string查找和替换 查找: 查找指定字符串是否存在替换: 在指定的位置替换字符串函数原型 查找str字符串第一次出现位置从pos开始查找 int find(const string str,int pos 0) const查找s第一次出现位置从pos开始查找 int find(const char* s,int pos 0) const从pos位置查找s的前n个字符第一次位置 int find(const char s,int pos,int n) const查找字符c第一次出现的位置 int find(const char c,int pos 0) const查找str最后一次位置从pos开始查找 int rfind(const string str,int pos npos) const查找s最后一次出现位置从pos开始查找 int rfind(const char * s,int pos npos) const从pos查找s的前n个字符最后一次位置 int rfind(const char s,int pos,int n) const查找字符c最后一次出现的位置 int rfind(const char c,int pos 0) const替换从pos开始n个字符为字符串 string replace(int pos,int n,const string str)替换从pos开始的n个字符为字符串s string replace(int pos,int n,const char* s)3.1.6string字符串比较 字符串之间的比较逐个比较比较方式 字符串比较是按字符的ASCII码进行对比结果 返回 0 返回 1 返回 -1 函数原型 与字符串s比较 int compare(const string s) const与字符串s比较 int compare(const char * s) conststring strs hello;string strs1 hollw;int comp strs.compare(strs1);cout comp comp endl;// -13.1.7string字符存取 string中单个字符存取通过[ ]方式获取字符 char operator[](int n)通过at方式获取字符 char at(int n)string strs hello; cout 字符: strs[2] endl;// l3.1.8string插入和删除 对string字符串进行插入和删除字符串操作函数原型 插入字符串 string insert(int pos,const char* s)插入字符串 string insert(int pos,const string str)在指定位置插入n个字符c string insert(int pos,int n,char c)删除从pos开始的n个字符 string erase(int pos,int n npos)string strs hello;string str12;str12 strs.erase(1, 3);cout str12 str12 endl;// ho3.1.9string子串 从字符串中获取想要的子串函数原型 返回pos开始的n个字符组成的字符串 string substr(int pos 0,int n npos) conststring strs hello;string stru;stru strs.substr(1, 3);cout stru stru endl;// ell3.2vector容器 3.2.1vector基本概念 1.功能 vector数据结构和数组非常类似也称为单端数组 2.vector与普通数组区别 不同之处在于数组是静态空间而vector可以动态扩展 3.动态扩展 并不是在原空间之后续接新空间而是找更大的内存空间然后将原数据拷贝新空间释放原空间 vector容器的迭代器是支持随机访问的迭代器 3.2.2vector构造函数 创建vector容器函数原型 采用模板实现类实现默认构造函数 vectorT v;将v[begin(),end()]区间中的元素拷贝给本身 vector(v.begin(),v.end())构造函数将n个elem拷贝给本身 vector(n.elem)拷贝构造函数 vector(const vector vec)#includeiostream using namespace std; #includevectorvoid printVector(vectorint vec) {for (vectorint::iterator it vec.begin();it ! vec.end();it){cout *it ;}cout endl; } void test1() {//默认无参构造函数vectorint v1;for (int i 0;i 10;i){v1.push_back(i 1);}printVector(v1);// 通过区间方式进行构造vectorint v2(v1.begin(), v1.end());printVector(v2);//n个elem方式构造vectorint v3(4, 88);printVector(v3);//拷贝构造vectorint v4(v3);printVector(v4); }int main() {test1();system(pause);return 0; }3.2.3vector赋值操作 给vector容器赋值操作函数原型 重载等号操作符 vector operator(const vector vec)将[begin,end)区间中的数据拷贝赋值给本身 assign(beg,end)将n个element拷贝赋值给本身 assign(n,elem)//赋值 operatorvectorint v11;v11 v4;printVector(v11);//assignvectorint v12;v12.assign(v4.begin(), v4.end());printVector(v12);3.2.4vector容量和大小 对vector容器的容量和大小操作函数原型 判断容器是否为空 empty()容器容量 capacity()返回容器中元素的个数 size()重新指定容器的长度为num若容器长度变长则以默认值填充新位置如果容器变短则末尾超出容器长度的元素被删除 resize(int num)重新指定容器的长度num若容器变长则elem值填充新位置如果容器变短则末尾超出容器长度的元素被删除 resize(int num,elem)cout 容量: v12.capacity() endl;// 4cout 容量: v12.size() endl;// 4v12.resize(8);cout 容量: v12.capacity() endl;// 8cout 容量: v12.size() endl;// 83.2.5vector插入和删除 对vector容器进行插入、删除操作函数原型 尾部插入元素ele push_back(ele)删除最后一个元素 pop_back()迭代器指向位置pos插入元素ele insert(const_iterator pos,ele)迭代器指向位置pos插入count个元素ele insert(const_iterator pos,int count,ele)删除迭代器指向的元素 erase(const_iterator pos)删除迭代器从start到end之间的元素 erase(const_iterator start,const_iterator end)删除容器中所有元素 claer()v12.push_back(78);cout 容量: v12.capacity() endl;// 12cout 容量: v12.size() endl;// 9printVector(v12);//插入迭代器 v12.insert(v12.begin(), 10);printVector(v12); 3.2.6vector数据存取 对vector中的数据存取操作函数原型 返回索引idx所指的数据 at(int idx)返回索引idx所指的数据 operator[idx]返回容器中第一个数据元素 front()返回容器中最后一个数据元素 back()3.2.7vector互换容器 实现两个容器内元素进行互换函数原型 将vec与本身的元素互换 swap(vec)//巧用swap收缩内存 v.resize(3); vectorint(v).swap(v)3.2.8vector预留空间 减少vector在动态扩展容量时的扩展次数函数原型 容器预留len个元素长度预留位置不初始化元素不可访问 reserve(int len)3.3deque容器 3.3.1deque容器基本概念 双端数组可以对头端进行插入删除操作deque与vector区别 vector对于头部的插入删除效率低数据量越大效率越低deque相对而言对头部的插入删除速度会比vector快vector访问元素时的速度会比deque快这和两者内部实现有关 deque内部工作原理 deque内部有一个中控器维护每段缓冲区中的内容缓冲区中存放的真实数据中控器维护的每个缓冲区的地址使得使用deque时像一片连续的内存空间 deque容器的迭代器也是支持随机访问的 3.3.2deque构造函数 deque容器构造函数原型 默认构造形式 dequeT depT构造函数将[beg,end)区间中的元素拷贝给本身 deque(beg,end)构造函数将n个elem拷贝给本身 deque(n,elem)拷贝构造函数 deque(const deque dep)#includeiostream #includedeque using namespace std;//添加const避免值被修改 void printDeque(const dequeint dep) {for (dequeint::const_iterator it dep.begin();it ! dep.end();it){cout *it ;}cout endl; }void test1() {//默认构造dequeint dep;for(int i 0;i 10;i){dep.push_back(i 1);}printDeque(dep);dequeint dep2(dep.begin(), dep.end());printDeque(dep2); }int main() {test1();system(pause);return 0; }3.3.3deque赋值操作 给deque容器进行赋值函数原型 重载等号操作符 deque operato(const deque dep)将[beg,end)区间中的数据拷贝赋值给本身 assign(beg,end)将n个elem拷贝赋值给本身 assign(n,elem)3.3.4deque大小操作 对deque容器大小进行操作函数原型 判断容器是否为空 empty()返回容器中元素的个数 size()重新指定容器的长度为num若容器变长则以默认值填充新位置如果容器变短则末尾超出容器长度的元素被删除 resize(num)重新指定容器的长度为num若容器变长则以elem值填充新位置如果容器变短则末尾超出容器长度的元素被删除 resize(num.elem)3.3.5deque插入删除 向deque容器中插入删除元素函数原型 容器尾部添加一个元素 push_back(elem)在容器头部插入一个元素 push_front(elem)删除容器最后一个元素 pop_back()删除容器第一个元素 pop_front()在pos位置插入一个elem元素的拷贝返回新数据的位置 insert(const_iterator pos,elem)在pos位置插入n个elem数据无返回值 insert(const_iterator pos,n,elem)在pos位置插入[beg,end)区间的数据无返回值 insert(const_iterator pos,beg,end)清空容器的所有数据 clear()删除[beg,end)区间的数据返回下一个数据的位置 erase(beg,end)删除pos位置的数据返回下一个数据的位置 erase(const_iterator pos)// 在dep1前面插入dep2 dep1.insert(dep1.begin(),dep2.begin(),dep2.end())3.3.6deque数据存取 对deque中的数据存取操作函数原型 返回所有idx所指的数据 at(idx)返回索引idx所指的数据 operator[]返回容器中第一数据元素 front()返回容器中最后一个数据元素 back()3.3.7deque排序 利用算法实现对deque容器进行排序算法 对beg和end区间内元素进行排序 sort(iterator beg,iterator end)3.4案例 3.5stack容器 3.5.1stack基本概念 stack是一种先进后出(First In Last Out,FILO)的数据结构它只有一个出口 栈中只有顶端的元素才可以被外界使用因此栈不允许有遍历行为栈中进入数据称为 ------- 入栈 push栈中弹出数据称为 ------- 出栈 pop 3.5.3stack常用接口 1.构造函数 stack采用模板类实现stack对象默认构造函数 stackT stk;拷贝构造函数 stack(const stack stack)2.赋值操作 重载等号操 stack operator(const stack stack)3.数据存取 向栈顶添加元素 push(elem)从栈顶移除第一个元素 pop()返回栈顶元素 top()4.大小操作 判断堆栈是否为空 empty()返回栈的大小 size()3.6queue容器 3.6.1queue基本概念 queue是一种先进先出(First In First Out,FIFO)的数据结构它有两个出口 队列容器允许从一端新增数据另一端移除数据 队列中只有队头和队尾可以被外界使用因此队列不允许有遍历行为 队列中进数据称为 — 入队 push 队列中出数据称为 — 出队 pop 3.6.2queue常用接口 栈容器常用的对外接口 1.构造函数 queue采用模板类实现queue对象的默认构造形式 queueT que;拷贝函数 queue(const queue que)2.赋值操作 重载等号操作符 queue operator(const queue que)3.数据存取 往队尾添加元素 push(elem)从队头移除第一个元素 pop()返回最后一个元素 back()返回第一个元素 front()4.大小操作 判断堆栈是否为空 empty()返回栈的大小 size()3.7list容器 3.7.1list基本概念 将数据进行链式存储链表是一种物理存储单元上非连续的存储结构数据元素的逻辑顺序是通过链表中的指针链接实现的链表的组成 链表是由一系列结点组成每一个结点有一个存储数据元素的数据域和一个存储下一个结点地址的指针域 STL中的链表是一个双向循环链表 链表的存储方式并不是连续的内存空间链表list中的迭代器只支持前移和后移属于双向迭代器list的优点 采用动态存储分配不会造成内存浪费和溢出链表执行插入和删除操作十分方便修改指针即可不需要移动大量元素 list的缺点 链表灵活但是空间(指针域)和时间(遍历)额外消耗较大 3.7.2list构造函数 创建list容器函数原型 list采用模板类实现对象默认构造形式 listT lst;构造函数将[beg,end)区间中的元素拷贝给本身 list(beg,end)构造函数将n个elem拷贝给本身 list(n,elem)拷贝构造函数 list(const list lst)#includeiostream #includelist using namespace std; void printList(const listint lst) {for (listint::const_iterator it lst.begin();it ! lst.end();it){cout *it ;}cout endl; }void test1() {listint lst;lst.push_back(20);lst.push_back(22);lst.push_back(21);lst.push_back(29);lst.push_back(90);printList(lst);listint lst1(lst.begin(), lst.end());printList(lst1);listint lst2(5, 30);printList(lst2);listint lst3;lst3 lst;printList(lst3); }int main() {test1();system(pause);return 0; }3.7.3list赋值和交换 给list容器进行赋值以及交换list容器函数原型 将[beg,end)区间中的数据拷贝赋值给本身 assign(beg,end)将n个elem拷贝给本身 assign(e,elem)重载等号操作符 list operator(const list lst)将lst与本身的元素互换 swap(lst)listint lst4;lst4.assign(lst.begin(), lst.end());printList(lst4);lst4.swap(lst2);printList(lst2);printList(lst4);3.7.4list大小操作 对list容器的大小操作函数原型 返回容器中元素的个数 size()判断容器是否为空 empty()重新指定容器的长度为num若容器变长则以默认值填充新位置如果容器变短则末尾超出容器长度的元素被删除 resize(num)重新指定容器的长度为num若容器变长则以elem值填充新位置如果容器变短则末尾超出容器长度的元素被删除 resize(num,elem)3.7.5list插入和删除 对list容器进行数据的插入和删除函数原型 在容器尾部加入一个元素 push_back(elem)删除容器最后一个元素 pop_back()在容器开头插入一个元素 push_front(elem)从容器开头移除第一个元素 pop_front()在pos位置插入elem元素的拷贝返回新数据的位置 insert(pos,elem)在pos位置插入n个elem数据无返回值 insert(pos,n,elem)在pos位置插入[beg,end)区间的数据无返回值 insert(pos,beg,end)移除容器的所有数据 clear()删除[beg,end)区间的数据返回下一个数据的位置 erase(beg,end)删除pos位置的数据返回下一个数据的位置 erase(pos)删除容器中所有与elem值匹配的元素 remove(elem)lst4.insert(lst4.begin(), 4, 22);printList(lst4);lst4.pop_back();printList(lst4);3.7.6list数据存取 对list容器中数据进行存取(不支持随机访问)函数原型 返回第一个元素 front()返回最后一个元素 back()//验证迭代器是否支持随机访问 listint::iterator it lst.begin(); it; it--; // it it 1;//error,不支持随机访问3.7.7list反转和排序 将容器中的元素反转以及将容器中的数据进行排序函数原型 反转链表 reverse()链表排序 sort()所有不支持随机访问迭代器的容器不支持用标准算法 lst.sort()3.8set/multiset容器 3.8.1set基本概念 1.简介 所有元素都会在插入时自动被排序 2.本质 set/multiset属于关联式容器底层结构是用二叉树实现 3.set和multiset区别 set不允许容器存中有重复的元素multiset允许容器中有重复的元素 #includeiostream using namespace std; #includesetvoid printSet(const setint st) {for(setint::const_iterator it st.begin();it ! st.end();it){cout *it ;}cout endl; }void test() {setint st;st.insert(10);st.insert(20);st.insert(50);st.insert(40);st.insert(30);st.insert(30);cout 遍历容器 endl;printSet(st);// 10 20 30 40 50 }int main() {test();system(pause);return 0; }3.8.2set构造和赋值 创建set容器以及赋值函数原型 构造 默认构造函数 setT st拷贝构造函数 set(const set st)赋值 重载等号操作符 set operator(const set st)3.8.3set大小和交换 统计set容器大小以及交换set容器函数原型 返回容器中元素的数据 size()判断容器是否为空 empty()交换两个集合容器 swap()3.8.4set插入和删除 set容器进行插入数据和删除数据函数原型 在容器中插入元素 insert(elem)清除所有元素 clear()删除pos迭代器所指元素返回下一个元素的迭代器 erase(pos)删除区间[beg,end)的所有元素返回下一个元素的迭代器 erase(beg,end)删除容器中值为elem的元素 erase(elem)setint::iterator it st.begin(); it; setint::iterator its st.erase(it); cout 下一个元素的迭代器 *its endl;// 303.8.5set查找和统计 对set容器进行查找数据以及统计函数原型 查找key是否存在若存在返回该键的元素的迭代器若不存在返回set.end() find(key)统计key的元素个数 count(key)setint::iterator it1 st.find(20);if (it1 ! st.end()){cout 找到元素 *it1 endl;}else{cout 未找到该元素 endl;}int num st.count(30);cout 元素的个数: num endl;// 13.8.6set和multiset区别 区别 set不可以插入重复数据而multisetset插入数据的同时会返回插入结果表示是否插入成功multiset不会检测数据因此可以插入重复数据 3.8.7pair对组创建 成对出现的数据利用对组可以返回两个数据两种创建方式pairtype,type p (value1,value2) pairtype,type p make_pair(value1,value2)#includeiostream using namespace std;void test() {//第一种方式pairstring, int p(Tom, 22);cout 姓名: p.first 年龄: p.second endl;//第二种方式pairstring, int p2 make_pair(Jerry, 18);cout 姓名: p2.first 年龄: p2.second endl; }int main() {test();system(pause);return 0; }3.8.8set容器排序 set容器默认排序规则为从小到大改变排序规则技术点 利用仿函数可以改变排序规则 #includeiostream #includedeque #includealgorithm using namespace std;//添加const避免值被修改 void printDeque(const dequeint dep) {for (dequeint::const_iterator it dep.begin();it ! dep.end();it){cout *it ;}cout endl; }void test1() {//默认构造dequeint dep;for(int i 0;i 10;i){dep.push_back(i 1);}printDeque(dep);dequeint dep2(dep.begin(), dep.end());printDeque(dep2);sort(dep2.begin(), dep2.end());printDeque(dep2); }int main() {test1();system(pause);return 0; }3.9map/multimap容器 3.9.1map基本概念 1.简介 map中所有元素都是pairpair中第一个元素为key键值起索引作用第二个元素为value实值所有元素都会根据元素的键值自动排序 2.本质 map/multimap属于关联式容器底层结构使用二叉树实现 3.优点 可以根据key值快速找到value值 4.map和multimap区别 map不允许容器中重复key值元素multimap允许容器中重复key值元素 3.9.2map构造和赋值 对map容器进行构造和赋值操作函数原型 ma默认构造函数 mapT1,T2 mp;拷贝构造函数 map(const map mp)重载等号操作符 map operator(const map mp)mapstring,int mp; mp.insert(pairstring,int (Tom,18)); 3.9.3map大小和交换 统计map容器的大小以及交换map容器函数原型 返回容器中元素的数目 size()判断容器是否为空 empty()交换两个集合 swap()3.9.4插入和删除 map容器进行插入数据和删除数据函数原型 在容器中插入元素 insert(elem)清除所有元素 clear()删除pos迭代器所指的元素返回下一个元素的迭代器 erase(pos)删除区间[beg,end)的所有元素返回下一个元素的迭代器 erase(beg,end)删除容器中值为key的元素 erase(key)3.9.5map查找和统计 对map容器进行查找数据以及统计数据函数原型 查找key是否存在若存在返回该键的元素的迭代器若不存在返回set.end() find(key)统计key的元素个数 count(key)3.9.6map容器排序 map容器默认排序规则为按照key值进行 从小到大排序技术点 利用仿函数可以改变排序规则 #includeiostream using namespace std; #includemap #includestringclass MyCompare { public:bool operator()(string str1,string str2)const{return str1 str2;} };void test() {mapstring, int,MyCompare mp;//mp.insert(pairstring, int(数字化, 13));mp.insert(make_pair(数字化, 13));//同上mp.insert(make_pair(模块化, 31));mp.insert(make_pair(智能化, 20));mp.insert(make_pair(系统化, 8));mp.insert(make_pair(助手化, 22));for (mapstring, int::iterator it mp.begin();it ! mp.end();it){cout 项目名称: (*it).first 项目年限 it-second endl;} }int main() {test();system(pause);return 0; }
http://www.dnsts.com.cn/news/135572.html

相关文章:

  • 弹出快捷菜单一般通过福州seo网站推广优化
  • 哪个网站是vue做的广州网站建设外包
  • 鸟人 网站建设农产品电子商务网站开发
  • 想开工作室没有项目南宁seo网络推广公司
  • 广州网站建设公司乐云seo598济南市住房和城乡建设部网站
  • 生鲜网站开发广州模板建站平台
  • 网站建设公司有哪些原兔展h5制作
  • 手机网站开发 手机模拟器成都最新规划官方消息
  • 长春免费建站北京个人网站备案
  • 网站优化设计建门户网站需要多少钱
  • jsp做的大型网站如何做网站的优化
  • 滕州市做网站网络服务提供者发现用户利用其网络
  • 企业介绍ppt案例欣赏北京正规seo搜索引擎优化价格
  • 杭州网站建设h5wordpress首页只能是page
  • 大连白云小学网站建设为网站做IPhone客户端
  • 蜘蛛互联网站建设织梦仿视频网站模板
  • 注册网站建设开发网站托管服务内容
  • php 网站调试信息流广告二级代理
  • 微信群公告如何做网站链接效果图素材网站
  • 网页 网 址网站区别wordpress安装文档下载
  • 清远专业网站建设515ppt网站建设
  • 深圳网站建设价格是多少钱阿里巴巴网站建设目的
  • 好乐买的网站推广方式长沙交互网站设计服务商
  • 网站设计步骤及图解html网页制作免费模板下载
  • 网络运维网站德州网站建设哪一家好
  • 国家建设部网站倪虹建筑工程网上培训平台
  • 怎么建立一个网站平台高考加油第1ppt模板免费下载
  • 公司建网站哪家重庆网站公司建设
  • 六安网站制作模仿软件下载wordpress
  • 建设银行租房平台网站0wordpress