wordpress站点使用期限插件,wordpress主题git,建设门户网站都需要什么,长沙营销型目录 一、模板
1、函数模板
(1)、基本语法和使用
(2)、函数模板注意事项
(3)、普通函数与函数模板的区别
(4)、普通函数与函数模板的调用规则
(5)、模板的局限性
2、类模板
(1)、基本语法
(2)、类模板与函数模板区别
(3)、类模板中成员函数创建时机
(4)、类模板对象…目录 一、模板
1、函数模板
(1)、基本语法和使用
(2)、函数模板注意事项
(3)、普通函数与函数模板的区别
(4)、普通函数与函数模板的调用规则
(5)、模板的局限性
2、类模板
(1)、基本语法
(2)、类模板与函数模板区别
(3)、类模板中成员函数创建时机
(4)、类模板对象做函数参数
(5)、类模板与继承
(6)、类模板成员函数类外实现
(7)、类模板分文件编写
(8)、类模板与友元
二、STL常用容器
1、string
(1)、构造函数
(2)、赋值操作
(3)、string字符串拼接
(4)、string查找和替换
(5)、string字符串比较
(6)、字符串存取
(7)、插入和删除
(8)、string子串
2、vector
(1)、构造函数
(2)、赋值操作
(3)、容量和大小
(4)、插入和删除
(5)、数据存取
(6)、互换容器
(7)、预留空间
3、deque
(1)、构造函数
(2)、赋值操作
(3)、容量和大小
(4)、插入和删除
(5)、数据存取
(6)、排序
4、stack
5、queue
6、list
(1)、构造函数
(2)、赋值和交换
(3)、容量和大小
(4)、插入和删除
(5)、数据存取
(6)、反转和排序
7、set/ multiset
(1)、构造和赋值
(2)、大小和交换
(3)、插入和删除
(4)、查找和统计
(5)、set和multiset区别
(6)、pair对组创建
(7)、排序
8、map/ multimap
(1)、构造和赋值
(2)、容量和交换
(3)、插入和删除
(4)、map查找和统计
(5)、map容器排序
三、STL函数对象(仿函数)
1、基本使用
2、谓词
(1)、 基本概念
(2)、一元谓词
(3)、二元谓词
3、内建函数对象
(1)、概念
(2)、算数仿函数
(3)、关系仿函数
(4)、逻辑仿函数
四、STL常用算法
1、常用遍历算法
(1)、for_each
(2)、transform
2、常用查找算法
(1)、find
(2)、find_if
(3)、adjacent_find
(4)、binary_search
(5)、count
(6)、count_if
3、常用排序算法
(1)、sort
(2)、random_shuffle
(3)、merge
(4)、 reverse
4、常用拷贝和替换算法
(1)、copy
(2)、replace
(3)、replace_if
(4)、swap
5、常用算术生成算法
(1)、accumulate
(2)、fill
6、常用集合算法
(1)、set_intersection
(2)、set_union
(3)、set_difference 一、模板
1、函数模板
(1)、基本语法和使用
templatetypename T //typename可以替换成class
函数声明或定义
template --- 声明创建模板
typename --- 表面其后面的符号是一种数据类型可以用class代替
T --- 通用的数据类型名称可以替换通常为大写字母 //交换整型函数
void swapInt(int a, int b) {int temp a;a b;b temp;
}//交换浮点型函数
void swapDouble(double a, double b) {double temp a;a b;b temp;
}//利用模板提供通用的交换函数
templatetypename T
void mySwap(T a, T b)
{T temp a;a b;b temp;
}void test01()
{int a 10;int b 20;//swapInt(a, b);//利用模板实现交换//1、自动类型推导mySwap(a, b);//2、显示指定类型mySwapint(a, b);cout a a endl;cout b b endl;}int main() {test01();return 0;
}
总结 函数模板利用关键字 template 使用函数模板有两种方式自动类型推导、显示指定类型 模板的目的是为了提高复用性将类型参数化
(2)、函数模板注意事项
注意事项 自动类型推导必须推导出一致的数据类型T,才可以使用 模板必须要确定出T的数据类型才可以使用
//利用模板提供通用的交换函数
templateclass T
void mySwap(T a, T b)
{T temp a;a b;b temp;
}// 1、自动类型推导必须推导出一致的数据类型T,才可以使用
void test01()
{int a 10;int b 20;char c c;mySwap(a, b); // 正确可以推导出一致的T//mySwap(a, c); // 错误推导不出一致的T类型
}// 2、模板必须要确定出T的数据类型才可以使用
templateclass T
void func()
{cout func 调用 endl;
}void test02()
{//func(); //错误模板不能独立使用必须确定出T的类型funcint(); //利用显示指定类型的方式给T一个类型才可以使用该模板
}int main() {test01();test02();return 0;
}
总结 使用模板时必须确定出通用数据类型T并且能够推导出一致的类型
(3)、普通函数与函数模板的区别
普通函数与函数模板区别 普通函数调用时可以发生自动类型转换隐式类型转换 函数模板调用时如果利用自动类型推导不会发生隐式类型转换 如果利用显示指定类型的方式可以发生隐式类型转换
//普通函数
int myAdd01(int a, int b)
{return a b;
}//函数模板
templateclass T
T myAdd02(T a, T b)
{return a b;
}//使用函数模板时如果用自动类型推导不会发生自动类型转换,即隐式类型转换
void test01()
{int a 10;int b 20;char c c;cout myAdd01(a, c) endl; //正确将char类型的c隐式转换为int类型 c 对应 ASCII码 99//myAdd02(a, c); // 报错使用自动类型推导时不会发生隐式类型转换myAdd02int(a, c); //正确如果用显示指定类型可以发生隐式类型转换
}int main() {test01();return 0;
}
(4)、普通函数与函数模板的调用规则
调用规则如下 如果函数模板和普通函数都可以实现优先调用普通函数 可以通过空模板参数列表来强制调用函数模板 函数模板也可以发生重载 如果函数模板可以产生更好的匹配,优先调用函数模板
//普通函数与函数模板调用规则
void myPrint(int a, int b)
{cout 调用的普通函数 endl;
}templatetypename T
void myPrint(T a, T b)
{ cout 调用的模板 endl;
}templatetypename T
void myPrint(T a, T b, T c)
{ cout 调用重载的模板 endl;
}void test01()
{//1、如果函数模板和普通函数都可以实现优先调用普通函数// 注意 如果告诉编译器 普通函数是有的但只是声明没有实现或者不在当前文件内实现就会报错找不到int a 10;int b 20;myPrint(a, b); //调用普通函数//2、可以通过空模板参数列表来强制调用函数模板myPrint(a, b); //调用函数模板//3、函数模板也可以发生重载int c 30;myPrint(a, b, c); //调用重载的函数模板//4、 如果函数模板可以产生更好的匹配,优先调用函数模板char c1 a;char c2 b;myPrint(c1, c2); //调用函数模板
}int main() {test01();return 0;
}
总结既然提供了函数模板最好就不要提供普通函数否则容易出现二义性
(5)、模板的局限性
提供模板的重载为特定的类型提供具体化的模板
#includeiostream
using namespace std;#include stringclass Person
{
public:Person(string name, int age){this-m_Name name;this-m_Age age;}string m_Name;int m_Age;
};//普通函数模板
templateclass T
bool myCompare(T a, T b)
{if (a b){return true;}else{return false;}
}//具体化显示具体化的原型和定意思以template开头并通过名称来指出类型
//具体化优先于常规模板
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 test01()
{int a 10;int b 20;//内置数据类型可以直接使用通用的函数模板bool ret myCompare(a, b);if (ret){cout a b endl;}else{cout a ! b endl;}
}void test02()
{Person p1(Tom, 10);Person p2(Tom, 10);//自定义数据类型不会调用普通的函数模板//可以创建具体化的Person数据类型的模板用于特殊处理这个类型bool ret myCompare(p1, p2);if (ret){cout p1 p2 endl;}else{cout p1 ! p2 endl;}
}int main() {test01();test02();return 0;
}
2、类模板
(1)、基本语法
templatetypename T
类
#include string
//类模板
templateclass NameType, class AgeType
class Person
{
public:Person(NameType name, AgeType age){this-mName name;this-mAge age;}void showPerson(){cout name: this-mName age: this-mAge endl;}
public:NameType mName;AgeType mAge;
};void test01()
{// 指定NameType 为string类型AgeType 为 int类型Personstring, intP1(孙悟空, 999);P1.showPerson();
}int main() {test01();return 0;
}
(2)、类模板与函数模板区别
类模板与函数模板区别主要有两点 类模板没有自动类型推导的使用方式 Person string ,intp(孙悟空, 1000); 类模板在模板参数列表中可以有默认参数 templateclass NameType, class AgeType int
class Person...
(3)、类模板中成员函数创建时机
类模板中成员函数和普通类中成员函数创建时机是有区别的 普通类中的成员函数一开始就可以创建 类模板中的成员函数在调用时才创建
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 test01()
{MyClassPerson1 m;m.fun1();//m.fun2();//编译会出错说明函数调用才会去创建成员函数
}int main() {test01();return 0;
}
(4)、类模板对象做函数参数
一共有三种传入方式 指定传入的类型 --- 直接显示对象的数据类型 参数模板化 --- 将对象中的参数变为模板进行传递 整个类模板化 --- 将这个对象类型 模板化进行传递
#include string
//类模板
templateclass NameType, class AgeType int
class Person
{
public:Person(NameType name, AgeType age){this-mName name;this-mAge age;}void showPerson(){cout name: this-mName age: this-mAge endl;}
public:NameType mName;AgeType mAge;
};//1、指定传入的类型
void printPerson1(Personstring, int p)
{p.showPerson();
}
void test01()
{Person string, int p(孙悟空, 100);printPerson1(p);
}//2、参数模板化
template class T1, class T2
void printPerson2(PersonT1, T2p)
{p.showPerson();cout T1的类型为 typeid(T1).name() endl;cout T2的类型为 typeid(T2).name() endl;
}
void test02()
{Person string, int p(猪八戒, 90);printPerson2(p);
}//3、整个类模板化
templateclass T
void printPerson3(T p)
{cout T的类型为 typeid(T).name() endl;p.showPerson();}
void test03()
{Person string, int p(唐僧, 30);printPerson3(p);
}int main() {test01();test02();test03();return 0;
}
总结 通过类模板创建的对象可以有三种方式向函数中进行传参 使用比较广泛是第一种指定传入的类型
(5)、类模板与继承
当类模板碰到继承时需要注意一下几点 当子类继承的父类是一个类模板时子类在声明的时候要指定出父类中T的类型 如果不指定编译器无法给子类分配内存 如果想灵活指定出父类中T的类型子类也需变为类模板
templateclass T
class Base
{T m;
};//class Son:public Base //错误c编译需要给子类分配内存必须知道父类中T的类型才可以向下继承
class Son :public Baseint //必须指定一个类型
{
};
void test01()
{Son c;
}//类模板继承类模板 ,可以用T2指定父类中的T类型
templateclass T1, class T2
class Son2 :public BaseT2
{
public:Son2(){cout typeid(T1).name() endl;cout typeid(T2).name() endl;}
};void test02()
{Son2int, char child1;
}int main() {test01();test02();return 0;
}
(6)、类模板成员函数类外实现
#include string//类模板中成员函数类外实现
templateclass T1, class T2
class Person {
public://成员函数类内声明Person(T1 name, T2 age);void showPerson();public:T1 m_Name;T2 m_Age;
};//构造函数 类外实现
templateclass T1, class T2
PersonT1, T2::Person(T1 name, T2 age) {this-m_Name name;this-m_Age age;
}//成员函数 类外实现
templateclass T1, class T2
void PersonT1, T2::showPerson() {cout 姓名: this-m_Name 年龄: this-m_Age endl;
}void test01()
{Personstring, int p(Tom, 20);p.showPerson();
}int main() {test01();return 0;
}
(7)、类模板分文件编写
问题 类模板中成员函数创建时机是在调用阶段导致分文件编写时链接不到
解决 解决方式1直接包含.cpp源文件 解决方式2将声明和实现写到同一个文件中并更改后缀名为.hpphpp是约定的名称并不是强制推荐 person.hpp中代码
#pragma once
#include iostream
using namespace std;
#include stringtemplateclass T1, class T2
class Person {
public:Person(T1 name, T2 age);void showPerson();
public:T1 m_Name;T2 m_Age;
};//构造函数 类外实现
templateclass T1, class T2
PersonT1, T2::Person(T1 name, T2 age) {this-m_Name name;this-m_Age age;
}//成员函数 类外实现
templateclass T1, class T2
void PersonT1, T2::showPerson() {cout 姓名: this-m_Name 年龄: this-m_Age endl;
}
(8)、类模板与友元
全局函数类内实现 - 直接在类内声明友元即可
全局函数类外实现 - 需要提前让编译器知道全局函数的存在
#include string//2、全局函数配合友元 类外实现 - 先做函数模板声明下方在做函数模板定义在做友元
templateclass T1, class T2 class Person;//如果声明了函数模板可以将实现写到后面否则需要将实现体写到类的前面让编译器提前看到
//templateclass T1, class T2 void printPerson2(PersonT1, T2 p); templateclass T1, class T2
void printPerson2(PersonT1, T2 p)
{cout 类外实现 ---- 姓名 p.m_Name 年龄 p.m_Age endl;
}templateclass T1, class T2
class Person
{//1、全局函数配合友元 类内实现friend void printPerson(PersonT1, T2 p){cout 姓名 p.m_Name 年龄 p.m_Age endl;}//全局函数配合友元 类外实现friend void printPerson2(PersonT1, T2 p);public:Person(T1 name, T2 age){this-m_Name name;this-m_Age age;}private:T1 m_Name;T2 m_Age;};//1、全局函数在类内实现
void test01()
{Person string, int p(Tom, 20);printPerson(p);
}//2、全局函数在类外实现
void test02()
{Person string, int p(Jerry, 30);printPerson2(p);
}int main() {//test01();test02();system(pause);return 0;
}
建议全局函数做类内实现用法简单而且编译器可以直接识别
二、STL常用容器
1、string
#include string
(1)、构造函数
string(); //创建一个空的字符串 例如: string str;
string(const char* s); //使用字符串s初始化
string(const string str); //使用一个string对象初始化另一个string对象
string(int n, char c); //使用n个字符c初始化
#include string
//string构造
void test01()
{string s1; //创建空字符串调用无参构造函数cout str1 s1 endl;const char* str hello world;string s2(str); //把c_string转换成了stringcout str2 s2 endl;string s3(s2); //调用拷贝构造函数cout str3 s3 endl;string s4(10, a);cout str3 s3 endl;
}int main() {test01();return 0;
}
(2)、赋值操作
赋值的函数原型 string operator(const char* s); //char*类型字符串 赋值给当前的字符串 string operator(const string s); //把字符串s赋给当前的字符串 string operator(char 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赋给当前字符串
//赋值
void test01()
{string str1;str1 hello world;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(5, x);cout str7 str7 endl;
}int main() {test01();return 0;
}
(3)、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个字符连接到字符串结尾
//字符串拼接
void test01()
{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 abcde, 4);//str3.append(str2);str3.append(str2, 4, 3); // 从下标4位置开始 截取3个字符拼接到字符串末尾cout str3 str3 endl;
}
int main() {test01();return 0;
}
(4)、string查找和替换
功能描述 查找查找指定字符串是否存在 替换在指定的位置替换字符串 函数原型 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, 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
//查找和替换
void test01()
{//查找string str1 abcdefgde;int pos str1.find(de);if (pos -1){cout 未找到 endl;}else{cout pos pos endl;}pos str1.rfind(de);cout pos pos endl;}void test02()
{//替换string str1 abcdefgde;str1.replace(1, 3, 1111); //a1111efgdecout str1 str1 endl;
}int main() {//test01();//test02();return 0;
}
(5)、string字符串比较
比较方式 字符串比较是按字符的ASCII码进行对比 返回 0 返回 1 返回 -1 函数原型 int compare(const string s) const; //与字符串s比较 int compare(const char *s) const; //与字符串s比较
//字符串比较
void test01()
{string s1 hello;string s2 aello;int ret s1.compare(s2);if (ret 0) {cout s1 等于 s2 endl;}else if (ret 0){cout s1 大于 s2 endl;}else{cout s1 小于 s2 endl;}}int main() {test01();return 0;
}
(6)、字符串存取
string中单个字符存取方式有两种 char operator[](int n); //通过[]方式取字符 char at(int n); //通过at方法获取字符
void test01()
{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;//字符修改str[0] x;str.at(1) x;cout str endl;}int main() {test01();system(pause);return 0;
}
(7)、插入和删除
函数原型 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个字符
//字符串插入和删除
void test01()
{string str hello;str.insert(1, 111);cout str endl; //h111ellostr.erase(1, 3); //从1号位置开始3个字符cout str endl;
}int main() {test01();system(pause);return 0;
}
(8)、string子串 string substr(int pos 0, int n npos) const; //返回由pos开始的n个字符组成的字符串
//子串
void test01()
{string str abcdefg;string subStr str.substr(1, 3);cout subStr subStr endl;string email hellosina.com;int pos email.find();string username email.substr(0, pos);cout username: username endl;}int main() {test01();system(pause);return 0;
}
2、vector
(1)、构造函数 vectorT v; //采用模板实现类实现默认构造函数 vector(v.begin(), v.end()); //将v[begin(), end())区间中的元素拷贝给本身。 vector(n, elem); //构造函数将n个elem拷贝给本身。 vector(const vector vec); //拷贝构造函数。
#include vectorvoid printVector(vectorint v) {for (vectorint::iterator it v.begin(); it ! v.end(); it) {cout *it ;}cout endl;
}void test01()
{vectorint v1; //无参构造for (int i 0; i 10; i){v1.push_back(i);}printVector(v1);vectorint v2(v1.begin(), v1.end());printVector(v2);vectorint v3(10, 100);printVector(v3);vectorint v4(v3);printVector(v4);
}int main() {test01();return 0;
}
(2)、赋值操作 vector operator(const vector vec);//重载等号操作符 assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身。 assign(n, elem); //将n个elem拷贝赋值给本身。
#include vectorvoid printVector(vectorint v) {for (vectorint::iterator it v.begin(); it ! v.end(); it) {cout *it ;}cout endl;
}//赋值操作
void test01()
{vectorint v1; //无参构造for (int i 0; i 10; i){v1.push_back(i);}printVector(v1);vectorintv2;v2 v1;printVector(v2);vectorintv3;v3.assign(v1.begin(), v1.end());printVector(v3);vectorintv4;v4.assign(10, 100);printVector(v4);
}int main() {test01();system(pause);return 0;
}(3)、容量和大小 empty(); //判断容器是否为空 capacity(); //容器的容量 size(); //返回容器中元素的个数 resize(int num); //重新指定容器的长度为num若容器变长则以默认值填充新位置。 //如果容器变短则末尾超出容器长度的元素被删除。 resize(int num, elem); //重新指定容器的长度为num若容器变长则以elem值填充新位置。 //如果容器变短则末尾超出容器长度的元素被删除
#include vectorvoid printVector(vectorint v) {for (vectorint::iterator it v.begin(); it ! v.end(); it) {cout *it ;}cout endl;
}void test01()
{vectorint v1;for (int i 0; i 10; 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;}//resize 重新指定大小 若指定的更大默认用0填充新位置可以利用重载版本替换默认填充v1.resize(15,10);printVector(v1);//resize 重新指定大小 若指定的更小超出部分元素被删除v1.resize(5);printVector(v1);
}int main() {test01();system(pause);return 0;
}(4)、插入和删除 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 vectorvoid printVector(vectorint v) {for (vectorint::iterator it v.begin(); it ! v.end(); it) {cout *it ;}cout endl;
}//插入和删除
void test01()
{vectorint 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());v1.clear();printVector(v1);
}int main() {test01();system(pause);return 0;
}
(5)、数据存取 at(int idx); //返回索引idx所指的数据 operator[]; //返回索引idx所指的数据 front(); //返回容器中第一个数据元素 back(); //返回容器中最后一个数据元素
#include vectorvoid test01()
{vectorintv1;for (int i 0; i 10; i){v1.push_back(i);}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 v1的最后一个元素为 v1.back() endl;
}int main() {test01();system(pause);return 0;
}
(6)、互换容器 swap(vec); // 将vec与本身的元素互换
#include vectorvoid printVector(vectorint v) {for (vectorint::iterator it v.begin(); it ! v.end(); it) {cout *it ;}cout endl;
}void test01()
{vectorintv1;for (int i 0; i 10; i){v1.push_back(i);}printVector(v1);vectorintv2;for (int i 10; i 0; i--){v2.push_back(i);}printVector(v2);//互换容器cout 互换后 endl;v1.swap(v2);printVector(v1);printVector(v2);
}void test02()
{vectorint v;for (int i 0; i 100000; i) {v.push_back(i);}cout v的容量为 v.capacity() endl;cout v的大小为 v.size() endl;v.resize(3);cout v的容量为 v.capacity() endl;cout v的大小为 v.size() endl;//收缩内存vectorint(v).swap(v); //匿名对象cout v的容量为 v.capacity() endl;cout v的大小为 v.size() endl;
}int main() {test01();test02();system(pause);return 0;
}(7)、预留空间 减少vector在动态扩展容量时的扩展次数 reserve(int len);//容器预留len个元素长度预留位置不初始化元素不可访问。
#include vectorvoid test01()
{vectorint v;//预留空间v.reserve(100000);int num 0;int* p NULL;for (int i 0; i 100000; i) {v.push_back(i);if (p ! v[0]) {p v[0];num;}}cout num: num endl;
}int main() {test01();system(pause);return 0;
}
3、deque
#include deque
(1)、构造函数 dequeT deqT; //默认构造形式 deque(beg, end); //构造函数将[beg, end)区间中的元素拷贝给本身。 deque(n, elem); //构造函数将n个elem拷贝给本身。 deque(const deque deq); //拷贝构造函数
(2)、赋值操作 deque operator(const deque deq); //重载等号操作符 assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身。 assign(n, elem); //将n个elem拷贝赋值给本身。
(3)、容量和大小 deque.empty(); //判断容器是否为空 deque.size(); //返回容器中元素的个数 deque.resize(num); //重新指定容器的长度为num,若容器变长则以默认值填充新位置。 //如果容器变短则末尾超出容器长度的元素被删除。 deque.resize(num, elem); //重新指定容器的长度为num,若容器变长则以elem值填充新位置。 //如果容器变短则末尾超出容器长度的元素被删除。
(4)、插入和删除
两端插入操作 push_back(elem); //在容器尾部添加一个数据 push_front(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位置的数据返回下一个数据的位置。
(5)、数据存取 at(int idx); //返回索引idx所指的数据 operator[]; //返回索引idx所指的数据 front(); //返回容器中第一个数据元素 back(); //返回容器中最后一个数据元素
(6)、排序 sort(iterator beg, iterator end) //对beg和end区间内元素进行排序
#include deque
#include algorithmvoid printDeque(const dequeint d)
{for (dequeint::const_iterator it d.begin(); it ! d.end(); it) {cout *it ;}cout endl;
}void test01()
{dequeint d;d.push_back(10);d.push_back(20);d.push_front(100);d.push_front(200);printDeque(d);sort(d.begin(), d.end());printDeque(d);}int main() {test01();return 0;
}
4、stack
构造函数 stackT stk; //stack采用模板类实现 stack对象的默认构造形式 stack(const stack stk); //拷贝构造函数
赋值操作 stack operator(const stack stk); //重载等号操作符
数据存取 push(elem); //向栈顶添加元素 pop(); //从栈顶移除第一个元素 top(); //返回栈顶元素
大小操作 empty(); //判断堆栈是否为空 size(); //返回栈的大小
5、queue
构造函数 queueT que; //queue采用模板类实现queue对象的默认构造形式 queue(const queue que); //拷贝构造函数
赋值操作 queue operator(const queue que); //重载等号操作符
数据存取 push(elem); //往队尾添加元素 pop(); //从队头移除第一个元素 back(); //返回最后一个元素 front(); //返回第一个元素
大小操作 empty(); //判断堆栈是否为空 size(); //返回栈的大小
6、list
不支持随机访问
(1)、构造函数 listT lst; //list采用采用模板类实现,对象的默认构造形式 list(beg,end); //构造函数将[beg, end)区间中的元素拷贝给本身。 list(n,elem); //构造函数将n个elem拷贝给本身。 list(const list lst); //拷贝构造函数。
(2)、赋值和交换 assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身。 assign(n, elem); //将n个elem拷贝赋值给本身。 list operator(const list lst); //重载等号操作符 swap(lst); //将lst与本身的元素互换。
(3)、容量和大小 size(); //返回容器中元素的个数 empty(); //判断容器是否为空 resize(num); //重新指定容器的长度为num若容器变长则以默认值填充新位置。 //如果容器变短则末尾超出容器长度的元素被删除。 resize(num, elem); //重新指定容器的长度为num若容器变长则以elem值填充新位置。 //如果容器变短则末尾超出容器长度的元素被删除。
(4)、插入和删除 push_back(elem);//在容器尾部加入一个元素 pop_back();//删除容器中最后一个元素 push_front(elem);//在容器开头插入一个元素 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位置的数据返回下一个数据的位置。 remove(elem);//删除容器中所有与elem值匹配的元素。
(5)、数据存取 front(); //返回第一个元素。 back(); //返回最后一个元素。
(6)、反转和排序 reverse(); //反转链表 sort(); //链表排序
void printList(const listint L) {for (listint::const_iterator it L.begin(); it ! L.end(); it) {cout *it ;}cout endl;
}bool myCompare(int val1 , int val2)
{return val1 val2;
}//反转和排序
void test01()
{listint L;L.push_back(90);L.push_back(30);L.push_back(20);L.push_back(70);printList(L);//反转容器的元素L.reverse();printList(L);//排序L.sort(); //默认的排序规则 从小到大printList(L);L.sort(myCompare); //指定规则从大到小printList(L);
}int main() {test01();system(pause);return 0;
}
7、set/ multiset
#include set
简介 所有元素都会在插入时自动被排序
本质 set/multiset属于关联式容器底层结构是用二叉树实现。
set和multiset区别 set不允许容器中有重复的元素 multiset允许容器中有重复的元素
(1)、构造和赋值
构造 setT st; //默认构造函数 set(const set st); //拷贝构造函数
赋值 set operator(const set st); //重载等号操作符
(2)、大小和交换 size(); //返回容器中元素的数目 empty(); //判断容器是否为空 swap(st); //交换两个集合容器
(3)、插入和删除 insert(elem); //在容器中插入元素。 clear(); //清除所有元素 erase(pos); //删除pos迭代器所指的元素返回下一个元素的迭代器。 erase(beg, end); //删除区间[beg,end)的所有元素 返回下一个元素的迭代器。 erase(elem); //删除容器中值为elem的元素。
(4)、查找和统计 find(key); //查找key是否存在,若存在返回该键的元素的迭代器若不存在返回set.end(); count(key); //统计key的元素个数
#include set//查找和统计
void test01()
{setint s1;//插入s1.insert(10);s1.insert(30);s1.insert(20);s1.insert(40);//查找setint::iterator pos s1.find(30);if (pos ! s1.end()){cout 找到了元素 *pos endl;}else{cout 未找到元素 endl;}//统计int num s1.count(30);cout num num endl;
}int main() {test01();return 0;
}
(5)、set和multiset区别
区别 set不可以插入重复数据而multiset可以 set插入数据的同时会返回插入结果表示插入是否成功 multiset不会检测数据因此可以插入重复数据
#include set//set和multiset区别
void test01()
{setint s;pairsetint::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;}//multisetmultisetint ms;ms.insert(10);ms.insert(10);for (multisetint::iterator it ms.begin(); it ! ms.end(); it) {cout *it ;}cout endl;
}int main() {test01();return 0;
}
(6)、pair对组创建
两种创建方式 pairtype, type p ( value1, value2 ); pairtype, type p make_pair( value1, value2 );
#include string//对组创建
void test01()
{pairstring, int p(Tom, 20);cout 姓名 p.first 年龄 p.second endl;pairstring, int p2 make_pair(Jerry, 10);cout 姓名 p2.first 年龄 p2.second endl;
}int main() {test01();return 0;
}
(7)、排序
容器默认排序规则为从小到大掌握如何改变排序规则
set存放内置数据类型
#include setclass MyCompare
{
public:bool operator()(int v1, int v2) {return v1 v2;}
};
void test01()
{ setint s1;s1.insert(10);s1.insert(40);s1.insert(20);s1.insert(30);s1.insert(50);//默认从小到大for (setint::iterator it s1.begin(); it ! s1.end(); it) {cout *it ;}cout endl;//指定排序规则setint,MyCompare s2;s2.insert(10);s2.insert(40);s2.insert(20);s2.insert(30);s2.insert(50);for (setint, MyCompare::iterator it s2.begin(); it ! s2.end(); it) {cout *it ;}cout endl;
}int main() {test01();system(pause);return 0;
}
set存放自定义数据类型
#include set
#include stringclass Person
{
public:Person(string name, int age){this-m_Name name;this-m_Age age;}string m_Name;int m_Age;};
class comparePerson
{
public:bool operator()(const Person p1, const Person p2){//按照年龄进行排序 降序return p1.m_Age p2.m_Age;}
};void test01()
{setPerson, comparePerson s;Person p1(刘备, 23);Person p2(关羽, 27);Person p3(张飞, 25);Person p4(赵云, 21);s.insert(p1);s.insert(p2);s.insert(p3);s.insert(p4);for (setPerson, comparePerson::iterator it s.begin(); it ! s.end(); it){cout 姓名 it-m_Name 年龄 it-m_Age endl;}
}
int main() {test01();system(pause);return 0;
}
8、map/ multimap
简介 map中所有元素都是pair pair中第一个元素为key键值起到索引作用第二个元素为value实值 所有元素都会根据元素的键值自动排序
本质 map/multimap属于关联式容器底层结构是用二叉树实现。
优点 可以根据key值快速找到value值
map和multimap区别 map不允许容器中有重复key值元素 multimap允许容器中有重复key值元素
(1)、构造和赋值
构造 mapT1, T2 mp; //map默认构造函数: map(const map mp); //拷贝构造函数
赋值 map operator(const map mp); //重载等号操作符
#include mapvoid printMap(mapint,intm)
{for (mapint, int::iterator it m.begin(); it ! m.end(); it){cout key it-first value it-second endl;}cout endl;
}void test01()
{mapint,intm; //默认构造m.insert(pairint, int(1, 10));m.insert(pairint, int(2, 20));m.insert(pairint, int(3, 30));printMap(m);mapint, intm2(m); //拷贝构造printMap(m2);mapint, intm3;m3 m2; //赋值printMap(m3);
}int main() {test01();return 0;
}
(2)、容量和交换 size(); //返回容器中元素的数目 empty(); //判断容器是否为空 swap(st); //交换两个集合容器
(3)、插入和删除 insert(elem); //在容器中插入元素。 clear(); //清除所有元素 erase(pos); //删除pos迭代器所指的元素返回下一个元素的迭代器。 erase(beg, end); //删除区间[beg,end)的所有元素 返回下一个元素的迭代器。 erase(key); //删除容器中值为key的元素。 #include mapvoid printMap(mapint,intm)
{for (mapint, int::iterator it m.begin(); it ! m.end(); it){cout key it-first value it-second endl;}cout endl;
}void test01()
{//插入mapint, int m;//第一种插入方式m.insert(pairint, int(1, 10));//第二种插入方式m.insert(make_pair(2, 20));//第三种插入方式m.insert(mapint, int::value_type(3, 30));//第四种插入方式m[4] 40; printMap(m);//删除m.erase(m.begin());printMap(m);m.erase(3);printMap(m);//清空m.erase(m.begin(),m.end());m.clear();printMap(m);
}int main() {test01();return 0;
}
(4)、map查找和统计
函数原型 find(key); //查找key是否存在,若存在返回该键的元素的迭代器若不存在返回set.end(); count(key); //统计key的元素个数
#include map//查找和统计
void test01()
{mapint, intm; m.insert(pairint, int(1, 10));m.insert(pairint, int(2, 20));m.insert(pairint, int(3, 30));//查找mapint, 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;
}int main() {test01();system(pause);return 0;
}
(5)、map容器排序 map容器默认排序规则为 按照key值进行 从小到大排序掌握如何改变排序规则
主要技术点: 利用仿函数可以改变排序规则 对于自定义数据类型map必须要指定排序规则,同set容器
#include mapclass MyCompare {
public:bool operator()(int v1, int v2) {return v1 v2;}
};void test01()
{//默认从小到大排序//利用仿函数实现从大到小排序mapint, int, MyCompare m;m.insert(make_pair(1, 10));m.insert(make_pair(2, 20));m.insert(make_pair(3, 30));m.insert(make_pair(4, 40));m.insert(make_pair(5, 50));for (mapint, int, MyCompare::iterator it m.begin(); it ! m.end(); it) {cout key: it-first value: it-second endl;}
}
int main() {test01();system(pause);return 0;
}
三、STL函数对象(仿函数)
1、基本使用
概念 重载函数调用操作符的类其对象常称为函数对象 函数对象使用重载的()时行为类似函数调用也叫仿函数
本质 函数对象(仿函数)是一个类不是一个函数
特点 函数对象在使用时可以像普通函数那样调用, 可以有参数可以有返回值 函数对象超出普通函数的概念函数对象可以有自己的状态 函数对象可以作为参数传递 #include string//1、函数对象在使用时可以像普通函数那样调用, 可以有参数可以有返回值
class MyAdd
{
public :int operator()(int v1,int v2){return v1 v2;}
};void test01()
{MyAdd myAdd;cout myAdd(10, 10) endl;
}//2、函数对象可以有自己的状态
class MyPrint
{
public:MyPrint(){count 0;}void operator()(string test){cout test endl;count; //统计使用次数}int count; //内部自己的状态
};
void test02()
{MyPrint myPrint;myPrint(hello world);myPrint(hello world);myPrint(hello world);cout myPrint调用次数为 myPrint.count endl;
}//3、函数对象可以作为参数传递
void doPrint(MyPrint mp , string test)
{mp(test);
}void test03()
{MyPrint myPrint;doPrint(myPrint, Hello C);
}int main() {//test01();//test02();test03();return 0;
}
2、谓词
(1)、 基本概念 返回bool类型的仿函数称为谓词 如果operator()接受一个参数那么叫做一元谓词 如果operator()接受两个参数那么叫做二元谓词
(2)、一元谓词
#include vector
#include algorithm//1.一元谓词
struct GreaterFive{bool operator()(int val) {return val 5;}
};void test01() {vectorint v;for (int i 0; i 10; i){v.push_back(i);}vectorint::iterator it find_if(v.begin(), v.end(), GreaterFive());if (it v.end()) {cout 没找到! endl;}else {cout 找到: *it endl;}}int main() {test01();return 0;
}
(3)、二元谓词
#include vector
#include algorithm
//二元谓词
class MyCompare
{
public:bool operator()(int num1, int num2){return num1 num2;}
};void test01()
{vectorint v;v.push_back(10);v.push_back(40);v.push_back(20);v.push_back(30);v.push_back(50);//默认从小到大sort(v.begin(), v.end());for (vectorint::iterator it v.begin(); it ! v.end(); it){cout *it ;}cout endl;cout ---------------------------- endl;//使用函数对象改变算法策略排序从大到小sort(v.begin(), v.end(), MyCompare());for (vectorint::iterator it v.begin(); it ! v.end(); it){cout *it ;}cout endl;
}int main() {test01();return 0;
}
3、内建函数对象
(1)、概念
概念 STL内建了一些函数对象
分类: 算术仿函数 关系仿函数 逻辑仿函数
用法 这些仿函数所产生的对象用法和一般函数完全相同 使用内建函数对象需要引入头文件 #includefunctional
(2)、算数仿函数
功能描述 实现四则运算 其中negate是一元运算其他都是二元运算 仿函数原型 templateclass T T plusT //加法仿函数 templateclass T T minusT //减法仿函数 templateclass T T multipliesT //乘法仿函数 templateclass T T dividesT //除法仿函数 templateclass T T modulusT //取模仿函数 templateclass T T negateT //取反仿函数
#include functional
//negate
void test01()
{negateint n;cout n(50) endl;
}//plus
void test02()
{plusint p;cout p(10, 20) endl;
}int main() {test01();test02();return 0;
}
(3)、关系仿函数
功能描述 实现关系对比 仿函数原型 templateclass T bool equal_toT //等于 templateclass T bool not_equal_toT //不等于 templateclass T bool greaterT //大于 templateclass T bool greater_equalT //大于等于 templateclass T bool lessT //小于 templateclass T bool less_equalT //小于等于
#include functional
#include vector
#include algorithmclass MyCompare
{
public:bool operator()(int v1,int v2){return v1 v2;}
};
void test01()
{vectorint v;v.push_back(10);v.push_back(30);v.push_back(50);v.push_back(40);v.push_back(20);for (vectorint::iterator it v.begin(); it ! v.end(); it) {cout *it ;}cout endl;//自己实现仿函数//sort(v.begin(), v.end(), MyCompare());//STL内建仿函数 大于仿函数sort(v.begin(), v.end(), greaterint());for (vectorint::iterator it v.begin(); it ! v.end(); it) {cout *it ;}cout endl;
}int main() {test01();return 0;
}
(4)、逻辑仿函数
功能描述 实现逻辑运算 函数原型 templateclass T bool logical_andT //逻辑与 templateclass T bool logical_orT //逻辑或 templateclass T bool logical_notT //逻辑非
#include vector
#include functional
#include algorithm
void test01()
{vectorbool v;v.push_back(true);v.push_back(false);v.push_back(true);v.push_back(false);for (vectorbool::iterator it v.begin();it! v.end();it){cout *it ;}cout endl;//逻辑非 将v容器搬运到v2中并执行逻辑非运算vectorbool v2;v2.resize(v.size());transform(v.begin(), v.end(), v2.begin(), logical_notbool());for (vectorbool::iterator it v2.begin(); it ! v2.end(); it){cout *it ;}cout endl;
}int main() {test01();return 0;
}
四、STL常用算法
概述: 算法主要是由头文件algorithm functional numeric组成。 algorithm是所有STL头文件中最大的一个范围涉及到比较、 交换、查找、遍历操作、复制、修改等等 numeric体积很小只包括几个在序列上面进行简单数学运算的模板函数 functional定义了一些模板类,用以声明函数对象。
1、常用遍历算法
(1)、for_each
功能描述 实现遍历容器
函数原型 for_each(iterator beg, iterator end, _func); // 遍历算法 遍历容器元素 // beg 开始迭代器 // end 结束迭代器 // _func 函数或者函数对象
#include algorithm
#include vector//普通函数
void print01(int val)
{cout val ;
}
//函数对象
class print02
{public:void operator()(int val) {cout val ;}
};//for_each算法基本用法
void test01() {vectorint v;for (int i 0; i 10; i) {v.push_back(i);}//遍历算法for_each(v.begin(), v.end(), print01);cout endl;for_each(v.begin(), v.end(), print02());cout endl;
}int main() {test01();return 0;
}
(2)、transform
功能描述 搬运容器到另一个容器中
函数原型 transform(iterator beg1, iterator end1, iterator beg2, _func);
//beg1 源容器开始迭代器
//end1 源容器结束迭代器
//beg2 目标容器开始迭代器
//_func 函数或者函数对象
#includevector
#includealgorithm//常用遍历算法 搬运 transformclass TransForm
{
public:int operator()(int val){return val;}};class MyPrint
{
public:void operator()(int val){cout val ;}
};void test01()
{vectorintv;for (int i 0; i 10; i){v.push_back(i);}vectorintvTarget; //目标容器vTarget.resize(v.size()); // 目标容器需要提前开辟空间transform(v.begin(), v.end(), vTarget.begin(), TransForm());for_each(vTarget.begin(), vTarget.end(), MyPrint());
}int main() {test01();return 0;
}
总结 搬运的目标容器必须要提前开辟空间否则无法正常搬运
2、常用查找算法
算法简介 find //查找元素 find_if //按条件查找元素 adjacent_find //查找相邻重复元素 binary_search //二分查找法 count //统计元素个数 count_if //按条件统计元素个数
(1)、find
功能描述 查找指定元素找到返回指定元素的迭代器找不到返回结束迭代器end() 函数原型 find(iterator beg, iterator end, value); // 按值查找元素找到返回指定位置迭代器找不到返回结束迭代器位置 // beg 开始迭代器 // end 结束迭代器 // value 查找的元素
#include algorithm
#include vector
#include string
void test01() {vectorint v;for (int i 0; i 10; i) {v.push_back(i 1);}//查找容器中是否有 5 这个元素vectorint::iterator it find(v.begin(), v.end(), 5);if (it v.end()) {cout 没有找到! endl;}else {cout 找到: *it endl;}
}class Person {
public:Person(string name, int age) {this-m_Name name;this-m_Age age;}//重载bool operator(const Person p) {if (this-m_Name p.m_Name this-m_Age p.m_Age) {return true;}return false;}public:string m_Name;int m_Age;
};void test02() {vectorPerson 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);vectorPerson::iterator it find(v.begin(), v.end(), p2);if (it v.end()) {cout 没有找到! endl;}else {cout 找到姓名: it-m_Name 年龄: it-m_Age endl;}
}
(2)、find_if
功能描述 按条件查找元素
函数原型 find_if(iterator beg, iterator end, _Pred); // 按值查找元素找到返回指定位置迭代器找不到返回结束迭代器位置 // beg 开始迭代器 // end 结束迭代器 // _Pred 函数或者谓词返回bool类型的仿函数
#include algorithm
#include vector
#include string//内置数据类型
class GreaterFive
{
public:bool operator()(int val){return val 5;}
};void test01() {vectorint v;for (int i 0; i 10; i) {v.push_back(i 1);}vectorint::iterator it find_if(v.begin(), v.end(), GreaterFive());if (it v.end()) {cout 没有找到! endl;}else {cout 找到大于5的数字: *it endl;}
}//自定义数据类型
class Person {
public:Person(string name, int age){this-m_Name name;this-m_Age age;}
public:string m_Name;int m_Age;
};class Greater20
{
public:bool operator()(Person p){return p.m_Age 20;}};void test02() {vectorPerson 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);vectorPerson::iterator it find_if(v.begin(), v.end(), Greater20());if (it v.end()){cout 没有找到! endl;}else{cout 找到姓名: it-m_Name 年龄: it-m_Age endl;}
}int main() {//test01();test02();return 0;
}
(3)、adjacent_find
功能描述 查找相邻重复元素 函数原型 adjacent_find(iterator beg, iterator end); // 查找相邻重复元素,返回相邻元素的第一个位置的迭代器 // beg 开始迭代器 // end 结束迭代器
#include algorithm
#include vectorvoid test01()
{vectorint v;v.push_back(1);v.push_back(2);v.push_back(5);v.push_back(2);v.push_back(4);v.push_back(4);v.push_back(3);//查找相邻重复元素vectorint::iterator it adjacent_find(v.begin(), v.end());if (it v.end()) {cout 找不到! endl;}else {cout 找到相邻重复元素为: *it endl;}
}
(4)、binary_search
功能描述 查找指定元素是否存在 函数原型 bool binary_search(iterator beg, iterator end, value); // 查找指定的元素查到 返回true 否则false // 注意: 在无序序列中不可用 // beg 开始迭代器 // end 结束迭代器 // value 查找的元素
#include algorithm
#include vectorvoid test01()
{vectorintv;for (int i 0; i 10; i){v.push_back(i);}//二分查找bool ret binary_search(v.begin(), v.end(),2);if (ret){cout 找到了 endl;}else{cout 未找到 endl;}
}int main() {test01();return 0;
}
(5)、count
功能描述 统计元素个数 函数原型 count(iterator beg, iterator end, value); // 统计元素出现次数 // beg 开始迭代器 // end 结束迭代器 // value 统计的元素
#include algorithm
#include vector//内置数据类型
void test01()
{vectorint v;v.push_back(1);v.push_back(2);v.push_back(4);v.push_back(5);v.push_back(3);v.push_back(4);v.push_back(4);int num count(v.begin(), v.end(), 4);cout 4的个数为 num endl;
}//自定义数据类型
class Person
{
public:Person(string name, int age){this-m_Name name;this-m_Age age;}bool operator(const Person p){if (this-m_Age p.m_Age){return true;}else{return false;}}string m_Name;int m_Age;
};void test02()
{vectorPerson v;Person p1(刘备, 35);Person p2(关羽, 35);Person p3(张飞, 35);Person p4(赵云, 30);Person p5(曹操, 25);v.push_back(p1);v.push_back(p2);v.push_back(p3);v.push_back(p4);v.push_back(p5);Person p(诸葛亮,35);int num count(v.begin(), v.end(), p);cout num num endl;
}
int main() {//test01();test02();return 0;
}
总结 统计自定义数据类型时候需要配合重载 operator
(6)、count_if
功能描述 按条件统计元素个数
函数原型 count_if(iterator beg, iterator end, _Pred); // 按条件统计元素出现次数 // beg 开始迭代器 // end 结束迭代器 // _Pred 谓词
#include algorithm
#include vectorclass Greater4
{
public:bool operator()(int val){return val 4;}
};//内置数据类型
void test01()
{vectorint v;v.push_back(1);v.push_back(2);v.push_back(4);v.push_back(5);v.push_back(3);v.push_back(4);v.push_back(4);int num count_if(v.begin(), v.end(), Greater4());cout 大于4的个数为 num endl;
}//自定义数据类型
class Person
{
public:Person(string name, int age){this-m_Name name;this-m_Age age;}string m_Name;int m_Age;
};class AgeLess35
{
public:bool operator()(const Person p){return p.m_Age 35;}
};
void test02()
{vectorPerson v;Person p1(刘备, 35);Person p2(关羽, 35);Person p3(张飞, 35);Person p4(赵云, 30);Person p5(曹操, 25);v.push_back(p1);v.push_back(p2);v.push_back(p3);v.push_back(p4);v.push_back(p5);int num count_if(v.begin(), v.end(), AgeLess35());cout 小于35岁的个数 num endl;
}int main() {//test01();test02();return 0;
}
总结按值统计用count按条件统计用count_if
3、常用排序算法
算法简介 ()sort //对容器内元素进行排序 random_shuffle //洗牌 指定范围内的元素随机调整次序 merge // 容器元素合并并存储到另一容器中 reverse // 反转指定范围的元素
(1)、sort
函数原型 sort(iterator beg, iterator end, _Pred); // 按值查找元素找到返回指定位置迭代器找不到返回结束迭代器位置 // beg 开始迭代器 // end 结束迭代器 // _Pred 谓词
#include algorithm
#include vectorvoid myPrint(int val)
{cout val ;
}void test01() {vectorint v;v.push_back(10);v.push_back(30);v.push_back(50);v.push_back(20);v.push_back(40);//sort默认从小到大排序sort(v.begin(), v.end());for_each(v.begin(), v.end(), myPrint);cout endl;//从大到小排序sort(v.begin(), v.end(), greaterint());for_each(v.begin(), v.end(), myPrint);cout endl;
}int main() {test01();return 0;
}
(2)、random_shuffle
功能描述 洗牌 指定范围内的元素随机调整次序 函数原型 random_shuffle(iterator beg, iterator end); // 指定范围内的元素随机调整次序 // beg 开始迭代器 // end 结束迭代器 random_shuffle洗牌算法比较实用使用时记得加随机数种子
#include algorithm
#include vector
#include ctimeclass myPrint
{
public:void operator()(int val){cout val ;}
};void test01()
{srand((unsigned int)time(NULL));vectorint v;for(int i 0 ; i 10;i){v.push_back(i);}for_each(v.begin(), v.end(), myPrint());cout endl;//打乱顺序random_shuffle(v.begin(), v.end());for_each(v.begin(), v.end(), myPrint());cout endl;
}int main() {test01();return 0;
}
(3)、merge
功能描述 两个容器元素合并并存储到另一容器中 函数原型 merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest); // 容器元素合并并存储到另一容器中 // 注意: 两个容器必须是有序的 // beg1 容器1开始迭代器 // end1 容器1结束迭代器 // beg2 容器2开始迭代器 // end2 容器2结束迭代器 // dest 目标容器开始迭代器
#include algorithm
#include vectorclass myPrint
{
public:void operator()(int val){cout val ;}
};void test01()
{vectorint v1;vectorint v2;for (int i 0; i 10 ; i) {v1.push_back(i);v2.push_back(i 1);}vectorint vtarget;//目标容器需要提前开辟空间vtarget.resize(v1.size() v2.size());//合并 需要两个有序序列merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vtarget.begin());for_each(vtarget.begin(), vtarget.end(), myPrint());cout endl;
}int main() {test01();return 0;
}
(4)、 reverse
功能描述 将容器内元素进行反转 函数原型 reverse(iterator beg, iterator end); // 反转指定范围的元素 // beg 开始迭代器 // end 结束迭代器
#include algorithm
#include vectorclass myPrint
{
public:void operator()(int val){cout val ;}
};void test01()
{vectorint v;v.push_back(10);v.push_back(30);v.push_back(50);v.push_back(20);v.push_back(40);cout 反转前 endl;for_each(v.begin(), v.end(), myPrint());cout endl;cout 反转后 endl;reverse(v.begin(), v.end());for_each(v.begin(), v.end(), myPrint());cout endl;
}int main() {test01();return 0;
}
4、常用拷贝和替换算法
学习目标 掌握常用的拷贝和替换算法
算法简介 copy // 容器内指定范围的元素拷贝到另一容器中 replace // 将容器内指定范围的旧元素修改为新元素 replace_if // 容器内指定范围满足条件的元素替换为新元素 swap // 互换两个容器的元素
(1)、copy
功能描述 容器内指定范围的元素拷贝到另一容器中 函数原型 copy(iterator beg, iterator end, iterator dest); // 按值查找元素找到返回指定位置迭代器找不到返回结束迭代器位置 // beg 开始迭代器 // end 结束迭代器 // dest 目标起始迭代器 总结利用copy算法在拷贝时目标容器记得提前开辟空间
#include algorithm
#include vectorclass myPrint
{
public:void operator()(int val){cout val ;}
};void test01()
{vectorint v1;for (int i 0; i 10; i) {v1.push_back(i 1);}vectorint v2;v2.resize(v1.size());copy(v1.begin(), v1.end(), v2.begin());for_each(v2.begin(), v2.end(), myPrint());cout endl;
}int main() {test01();return 0;
}
(2)、replace
功能描述 将容器内指定范围的旧元素修改为新元素 函数原型 replace(iterator beg, iterator end, oldvalue, newvalue); // 将区间内旧元素 替换成 新元素 // beg 开始迭代器 // end 结束迭代器 // oldvalue 旧元素 // newvalue 新元素 总结replace会替换区间内满足条件的所有元素
#include algorithm
#include vectorclass myPrint
{
public:void operator()(int val){cout val ;}
};void test01()
{vectorint v;v.push_back(20);v.push_back(30);v.push_back(20);v.push_back(40);v.push_back(50);v.push_back(10);v.push_back(20);cout 替换前 endl;for_each(v.begin(), v.end(), myPrint());cout endl;//将容器中的20 替换成 2000cout 替换后 endl;replace(v.begin(), v.end(), 20,2000);for_each(v.begin(), v.end(), myPrint());cout endl;
}int main() {test01();return 0;
}
(3)、replace_if
功能描述: 将区间内满足条件的元素替换成指定元素 函数原型 replace_if(iterator beg, iterator end, _pred, newvalue); // 按条件替换元素满足条件的替换成指定元素 // beg 开始迭代器 // end 结束迭代器 // _pred 谓词 // newvalue 替换的新元素 替换区间内满足条件的所有元素
#include algorithm
#include vectorclass myPrint
{
public:void operator()(int val){cout val ;}
};class ReplaceGreater30
{
public:bool operator()(int val){return val 30;}};void test01()
{vectorint v;v.push_back(20);v.push_back(30);v.push_back(20);v.push_back(40);v.push_back(50);v.push_back(10);v.push_back(20);cout 替换前 endl;for_each(v.begin(), v.end(), myPrint());cout endl;//将容器中大于等于的30 替换成 3000cout 替换后 endl;replace_if(v.begin(), v.end(), ReplaceGreater30(), 3000);for_each(v.begin(), v.end(), myPrint());cout endl;
}int main() {test01();return 0;
}
(4)、swap
功能描述 互换两个容器的元素 函数原型 swap(container c1, container c2); // 互换两个容器的元素 // c1容器1 // c2容器2
#include algorithm
#include vectorclass myPrint
{
public:void operator()(int val){cout val ;}
};void test01()
{vectorint v1;vectorint v2;for (int i 0; i 10; i) {v1.push_back(i);v2.push_back(i100);}cout 交换前 endl;for_each(v1.begin(), v1.end(), myPrint());cout endl;for_each(v2.begin(), v2.end(), myPrint());cout endl;cout 交换后 endl;swap(v1, v2);for_each(v1.begin(), v1.end(), myPrint());cout endl;for_each(v2.begin(), v2.end(), myPrint());cout endl;
}int main() {test01();return 0;
}
总结swap交换容器时注意交换的容器要同种类型
5、常用算术生成算法
学习目标 掌握常用的算术生成算法 注意 算术生成算法属于小型算法使用时包含的头文件为 #include numeric 算法简介 accumulate // 计算容器元素累计总和 fill // 向容器中添加元素
(1)、accumulate
功能描述 计算区间内 容器元素累计总和 函数原型 accumulate(iterator beg, iterator end, value); // 计算容器元素累计总和 // beg 开始迭代器 // end 结束迭代器 // value 起始值
#include numeric
#include vector
void test01()
{vectorint v;for (int i 0; i 100; i) {v.push_back(i);}int total accumulate(v.begin(), v.end(), 0);cout total total endl;
}int main() {test01();return 0;
}
(2)、fill
功能描述 向容器中填充指定的元素 函数原型 fill(iterator beg, iterator end, value); // 向容器中填充元素 // beg 开始迭代器 // end 结束迭代器 // value 填充的值
#include numeric
#include vector
#include algorithmclass myPrint
{
public:void operator()(int val){cout val ;}
};void test01()
{vectorint v;v.resize(10);//填充fill(v.begin(), v.end(), 100);for_each(v.begin(), v.end(), myPrint());cout endl;
}int main() {test01();return 0;
}
6、常用集合算法
学习目标 掌握常用的集合算法 算法简介 set_intersection // 求两个容器的交集 set_union // 求两个容器的并集 set_difference // 求两个容器的差集
(1)、set_intersection
功能描述 求两个容器的交集 函数原型 set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest); // 求两个集合的交集 // 注意:两个集合必须是有序序列 // beg1 容器1开始迭代器 // end1 容器1结束迭代器 // beg2 容器2开始迭代器 // end2 容器2结束迭代器 // dest 目标容器开始迭代器
#include vector
#include algorithmclass myPrint
{
public:void operator()(int val){cout val ;}
};void test01()
{vectorint v1;vectorint v2;for (int i 0; i 10; i){v1.push_back(i);v2.push_back(i5);}vectorint vTarget;//取两个里面较小的值给目标容器开辟空间vTarget.resize(min(v1.size(), v2.size()));//返回目标容器的最后一个元素的迭代器地址vectorint::iterator itEnd set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());for_each(vTarget.begin(), itEnd, myPrint());cout endl;
}int main() {test01();return 0;
}
总结 求交集的两个集合必须的有序序列 目标容器开辟空间需要从两个容器中取小值 set_intersection返回值既是交集中最后一个元素的位置
(2)、set_union
功能描述 求两个集合的并集 函数原型 set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest); // 求两个集合的并集 // 注意:两个集合必须是有序序列 // beg1 容器1开始迭代器 // end1 容器1结束迭代器 // beg2 容器2开始迭代器 // end2 容器2结束迭代器 // dest 目标容器开始迭代器
#include vector
#include algorithmclass myPrint
{
public:void operator()(int val){cout val ;}
};void test01()
{vectorint v1;vectorint v2;for (int i 0; i 10; i) {v1.push_back(i);v2.push_back(i5);}vectorint vTarget;//取两个容器的和给目标容器开辟空间vTarget.resize(v1.size() v2.size());//返回目标容器的最后一个元素的迭代器地址vectorint::iterator itEnd set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());for_each(vTarget.begin(), itEnd, myPrint());cout endl;
}int main() {test01();return 0;
}
总结 求并集的两个集合必须的有序序列 目标容器开辟空间需要两个容器相加 set_union返回值既是并集中最后一个元素的位置
(3)、set_difference
功能描述 求两个集合的差集 函数原型 set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest); // 求两个集合的差集 // 注意:两个集合必须是有序序列 // beg1 容器1开始迭代器 // end1 容器1结束迭代器 // beg2 容器2开始迭代器 // end2 容器2结束迭代器 // dest 目标容器开始迭代器
#include vector
#include algorithmclass myPrint
{
public:void operator()(int val){cout val ;}
};void test01()
{vectorint v1;vectorint v2;for (int i 0; i 10; i) {v1.push_back(i);v2.push_back(i5);}vectorint vTarget;//取两个里面较大的值给目标容器开辟空间vTarget.resize( max(v1.size() , v2.size()));//返回目标容器的最后一个元素的迭代器地址cout v1与v2的差集为 endl;vectorint::iterator itEnd set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());for_each(vTarget.begin(), itEnd, myPrint());cout endl;cout v2与v1的差集为 endl;itEnd set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), vTarget.begin());for_each(vTarget.begin(), itEnd, myPrint());cout endl;
}int main() {test01();return 0;
}
总结 求差集的两个集合必须的有序序列 目标容器开辟空间需要从两个容器取较大值 set_difference返回值既是差集中最后一个元素的位置