诸暨制作网站的公司有哪些,毕设网站代做一般预算多少钱,北京封闭小区名单最新,多语言的网站STL
STL#xff08;Standard Template Library,标准模板库#xff09;STL从广义上分为#xff1a; 容器#xff08;container#xff09;算法 (algorithm)迭代器 (iterator) 容器 和 算法之间通过迭代器进行无缝连接。STL几乎所有的代码都采用模板类或者模板函数
1、ST…STL
STLStandard Template Library,标准模板库STL从广义上分为 容器container算法 (algorithm)迭代器 (iterator) 容器 和 算法之间通过迭代器进行无缝连接。STL几乎所有的代码都采用模板类或者模板函数
1、STL六大组件
STL大体分为六大组件分别是容器、算法、迭代器、仿函数、适配器配接器、空间配置器
容器各种数据结构如vector、list、deque、set、map等用来存放数据算法各种常用的算法如sort、find、copy、for_each等迭代器扮演了容器与算法之间的胶合剂仿函数行为类似函数可作为算法的某种策略适配器一种用来修饰容器或仿函数或迭代器接口的东西空间适配器负责空间的配置与管理
2、STL中容器、算法、迭代器
容器放置东西用的。
STL容器就是将运用最广泛的一些数据结构实现出来
常用的数据结构数组链表树栈队列集合映射表等。
这些容器分为 序列式容器和关联式容器两种
序列式容器 强调值的排序序列式容器中的每个元素均有固定的位置。 关联式容器 二叉树结构各元素之间没有严格的物理上的顺序关系
算法解决问题的解法
有限的步骤解决逻辑或数学上的问题这就叫做算法algorithm
算法分为质变算法和非质变算法
质变算法: 是指运算过程中会更改区间内的元素的内容。例如拷贝替换删除等等 非质变算法 是指运算过程中不会更改区间内的元素内容。例如:查找、计数、遍历、寻找极值等等
迭代器容器和算法之间的粘合剂
提供一种方法使能够依次按照顺序寻访某个容器所含的各个元素而又无需暴露该容器的内部表示方法。
每个容器都有自己专属的迭代器
迭代器使用非常类似于指针初学阶段我们可以先理解迭代器为指针。
迭代器种类
种类功能支持运算输入迭代器对数据的只读访问只读支持、、输出迭代器对数据的只写访问只写支持前向迭代器读写操作并能向前推进迭代器读写支持、、双向迭代器读写操作并能向前和向后操作读写支持、–随机访问迭代器读写操作可以以跳跃的方式访问任意数据功能最强的迭代器读写支持、–、[n]、-n、、、、
常用的容器中迭代器种类分为双向迭代器和随机访问迭代器
3、容器算法迭代器初识
3.1、 vector存放内置数据类型
容器vector
算法for_each
迭代器: vector::iterator *it 的数据类型只需要看vector 的尖括号里面内容 例如这里面就是int型 示例
#includeiostream
using namespace std;
#includevector
#includealgorithm
//vector 容器存放内置的数据类型void myPrint(int val) {cout val endl;
}void test01() {//创建容器数组vectorint v;//插入数据-尾插v.push_back(10);v.push_back(20);v.push_back(30);v.push_back(40);v.push_back(50);//通过迭代器访问容器中的数据vectorint::iterator itBegin v.begin(); //起始迭代器指向容器中第一个元素vectorint::iterator itEnd v.end(); //结束迭代器指向容器中最后一个元素的下一个元素//第一种遍历方式while (itBegin!itEnd){cout *itBegin endl;itBegin;}//第二种方式常用cout 第二种 endl;for (vectorint::iterator it v.begin(); it ! v.end(); it) {cout *it endl;}//第三种方式(算法)cout 第三种 endl;//底层原理就是利用一个for循环输出输出方式是调用我们给定的函数回调函数for_each(v.begin(), v.end(), myPrint);
}3.2、Vector存放自定义数据类型
示例
#includeiostream
#includestring
#includevector
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 test01() {vectorPerson v;Person p1(a,10);Person p2(b,20);Person p3(c,30);Person p4(d,40);Person p5(e,50);//添加数据v.push_back(p1);v.push_back(p2);v.push_back(p3);v.push_back(p4);v.push_back(p5);//遍历数据for (vectorPerson::iterator it v.begin(); it ! v.end(); it) {cout 姓名 (*it).m_Name 年龄(*it).m_Age endl;cout 姓名 it-m_Name 年龄it-m_Age endl;}
}//存放自定义数据类型 指针
void test02() {vectorPerson* v;Person p1(a, 10);Person p2(b, 20);Person p3(c, 30);Person p4(d, 40);Person p5(e, 50);//添加数据v.push_back(p1);v.push_back(p2);v.push_back(p3);v.push_back(p4);v.push_back(p5);for (vectorPerson*::iterator it v.begin(); it ! v.end(); it) {cout 姓名: (*it)-m_Name 年龄: (*it)-m_Age endl;}
}3.3、Vector容器嵌套容器
#includeiostream
using namespace std;
#includevector//容器嵌套容器
void test01() {vectorvectorint v;//创建小容器vectorint v1;vectorint v2;vectorint v3;vectorint v4;//向小容器添加数据for (int i 0; i 4; i){v1.push_back(i 1);v2.push_back(i 1);v3.push_back(i 1);v4.push_back(i 1);}//将小容器插入到大容器中v.push_back(v1);v.push_back(v2);v.push_back(v3);v.push_back(v4);for (vectorvectorint::iterator it v.begin(); it ! v.end(); it) {//(*it)还是个容器还需要遍历for(vectorint::iterator vit (*it).begin();vit!(*it).end();vit){cout *vit ;}cout endl;}
}4、常用容器
4.1、string容器
4.1.1、string基本概念
本质
string是C风格的字符串而string本质上是一个类
string和char * 区别
char * 是一个指针string是一个类类内部封装了char *管理这个字符串是一个char *型的容器
特点
string类内部封装了许多成员方法
例如查找find拷贝copy删除delete 替换replace插入insert
string管理char*所分配的内存不用担心赋值越界和取值越界等由类内部进行负责
4.1.2、string构造函数
构造函数原型
string() //创建一个空的字符串 例如string str;string(const char *s) //使用字符串s初始化string(const string str)//使用一个string对象初始化另一个string对象string(int n,char c); //使用n个字符c初始化
示例
#includeiostream
#includestring
using namespace std;void test01() {string s1;//默认构造const char* str hello world;string s2(str);cout s2 s2 endl;string s3(s2);cout s2 s3 endl;string s4(10, a);cout s4 s4 endl;
}4.1.3、string赋值操作
功能描述
给string字符串进行赋值操作
赋值的函数原型
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 * sint n) //把字符串s的前N个字符赋给当前的字符串string assign(const string s) //把字符串S赋给当前字符串string assign(int n char c) //用n个字符c赋给当前字符串
void test01() {string str1;str1 hello;cout str1 str1 endl;string str2;str2 str1;cout str2 str1 endl;string str3;str3 a;cout str3 str3 endl;string str4;str4.assign(hello c);cout str4 str4 endl;string str5;str5.assign(hello, 3);cout str5 str5 endl;string str6;str6.assign(str5);cout str6 str6 endl;string str7;str7.assign(7,w);cout str7 str7 endl;}4.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 *sint n)//把字符串s的前n个字符连接到当前字符串结尾string append(const string s)//同operator(const string str);string append(const string sint pos,int n)//从字符串s中从pos开始的n个字符连接到字符串结尾
void test01() {string str1 我;str1 爱玩游戏;cout str1的值: str1 endl;str1 :;cout str1的值: str1 endl;string str2 csgo;str1 str2;cout str1的值: str1 endl;str1.append(、);cout str1的值: str1 endl;str1.append(lol,cf, 4);cout str1的值: str1 endl;str1.append(str2);cout str1的值: str1 endl;str1.append(string字符串拼接, 5, 11);cout str1的值: str1 endl;
}4.2、vector容器
作用类似于数组
4.3、deque容器
双端数据可以对头端进行插入删除操作
deque与vector区别
vector对于头部的插入删除效率低数据量越大效率越低deque相对而言对头部的插入删除速度会比vector快vector访问元素时速度会比deque快这和两者的内部实现有关
deque内部工作原理
deque内部有个中控器维护每段缓冲区 中的内容缓冲区中存放真实数据。中控器维护的是每个缓冲区的地址使得使用deque时像一片连续的内存空间 4.4、stack容器
stack是一种先进后出First In Last Out,FILO的数据结构它只有一个出口 栈中只有顶端的元素才可以被外界使用因此栈不允许有遍历行为
4.5、queue容器
概念Queue是一种先进先出First In First OutFIFO的数据结构它有两个出口 队列容器允许从一端新增元素从另一端移除元素队列中只有队头和队尾才可以被外界使用因此队列不允许有遍历行为队列中进数据称为 – 入队 push队列中出数据称为 – 出队 pop
4.6、list容器
功能将数据进行链式存储
链表list是一种物理存储单元上非连续的存储结构数据元素的逻辑顺序是通过链表中的指针链接实现的
链表的组成链表由一系列节点组成
节点的组成一个是存放数据元素的数据域另一个是存储下一个节点地址的指针域
STL中的链表是一个双向循环链表 这里的第一个节点的前一个节点指向最后一个最后一个的后一个节点指向第一个节点
由于链表的存储方式并不是连续的内存空间因此链表list中的迭代器只能支持前进和后移属于双向迭代器
list的优点
采用动态存储分配不会造成内存浪费和溢出链表执行插入和删除操作十分方便修改指针即可不需要移动大量元素
list的缺点
链表灵活但是空间指针域和时间遍历额外消耗较大
list一个重要性质插入或删除一个节点都不会造成原有的list迭代器的失效这在vector是不成立的
4.7、set/multiset容器
简介所有元素都会在插入时自动被排序
本质set/multiset属于关联式容器底层结构是用二叉树实现
set和mulitiset区别:
set不允许容器中有重复的元素mulitiset允许容器中有重复的元素
4.8、pair对组创建
成对出现的数据利用对组可以返回俩个数据
创建方法
pairtype,type p (vlaue1,vlaue2);pairtype,type p make_pair(value1,value2)
取值
p.first取第一个 p.second 取第二个
4.9、map/multimap容器
简介
map中所有元素都是pairpair中第一个元素为key(键值)起到索引作用第二个元素为value实值所有的元素都会根据元素的键值自动排序
本质
map/multimap属于关联式容器底层结构都是二叉树实现。
优点
可以根据key值快速找到value值
map/multimap区别
map不允许容器中有重复key值元素multimap允许容器中有重复key值元素
5、函数对象
概念
重载函数调用操作符的类其对象称为函数对象函数对象使用重载的时行为类似函数调用也叫仿函数
本质
函数对象仿函数是一个类而不是一个函数
5.1、函数对象使用
特点 函数对象在使用时可以像普通函数那样调用可以有参数可以有返回值 函数对象超出普通函数的概念函数对象可以有自己的状态 函数对象可以作为参数传递
示例
#includeiostream
#includestring
using namespace std;//1、-函数对象在使用时可以像普通函数那样调用可以有参数可以有返回值
//2、- 函数对象超出普通函数的概念函数对象可以有自己的状态
//3、- 函数对象可以作为参数传递class addNum {
public:int operator()(int a, int b) {return a b;}
};
//1、-函数对象在使用时可以像普通函数那样调用可以有参数可以有返回值
void test01() {addNum add;int a add(10, 20);cout add: a endl;
}//2、- 函数对象超出普通函数的概念函数对象可以有自己的状态
class Myprint {
public:Myprint() {count 0;}void operator()(string input) {cout input endl;count;}//自己的状态int count;
};void test02() {Myprint myPrint;myPrint(test);myPrint(test);cout 次数有 myPrint.count endl;
}//3、- 函数对象可以作为参数传递
void doPrint(Myprint a, string b) {a(b);
}
void test03() {Myprint my;doPrint(my, hello);
}5.2、谓词
概念
返回bool类型的仿函数称为谓词如果operator接受一个参数那么叫一元谓词如果operator接受二个参数那么叫二元谓词
示例
一元
//找大于5的数字
class findFive {
public:int operator()(int a) {if (a5){return a;}}
};void test01() {vectorint v;for (int i 0; i 10; i){v.push_back(i);}vectorint::iterator v2 find_if(v.begin(), v.end(), findFive());if (v2 v.end()){cout no endl;}else {cout yes endl;}
}二元
class MyCompare
{
public:bool operator()(int num1, int num2) {return num1 num2;}
};void test01() {vectorint v;v.push_back(10);v.push_back(20);v.push_back(30);v.push_back(40);sort(v.begin(), v.end(),MyCompare());for (vectorint::iterator it v.begin(); it ! v.end(); it) {cout *it ;}cout endl;
}5.3、内建函数对象
概念
STL内建了一些函数对象
分类
算数仿函数关系仿函数逻辑仿函数
用法
这些仿函数所产生的对象用法和一般函数完全相同使用内建函数对象需要引入头文件 #include
5.1.1、算术仿函数
功能描述
实现四则运算其中negate是一元运算其他都是二元运算
#includeiostream
#includefunctional
using namespace std;
//内建函数对象 算术仿函数//negate 一元仿函数 取反仿函数
void test01() {negateint n;cout n(50) endl;
}//plus 二元仿函数 加法
void test02() {plusint p;cout p(10, 20) endl;
}5.1.2、关系仿函数
功能描述
实现关系对比
示例
#includeiostream
#includevector
#includealgorithm
#includefunctional
using namespace std;void test01() {vectorint v;v.push_back(10);v.push_back(30);v.push_back(20);v.push_back(50);for (vectorint::iterator it v.begin(); it ! v.end(); it) {cout *it ;}cout endl;//greaterint() 内建函数sort(v.begin(), v.end(), greaterint());for (vectorint::iterator it v.begin(); it ! v.end(); it) {cout *it ;}cout endl;
}5.1.3、逻辑仿函数
功能
实现逻辑运算
示例
#includeiostream
#includevector
#includealgorithm
#includefunctional
using namespace std;
//逻辑非 logical_notvoid 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;//取反 搬到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;
}6、常用算法
概述
头文件主要由 - 范围涉及 比较、交换、查找、遍历操作、复制、修改等等 - 定义了一些模版类用以声明函数对象 - 只包括序列上面进行简单数学运算的模板函数
6.1、常用遍历算法
6.1.1、for_each
功能遍历容器
//提供一个仿函数
class print02 {
public:void operator()(int val) {cout val ;}
};for_each(v2.begin(), v2.end(), print02());
6.1.2、transform
功能搬运容器到另一个容器
//提供仿函数可以修改值
class Transform {
public:int operator()(int v) {return v 1000;}
};vectorint v2;v2.resize(v.size());transform(v.begin(), v.end(), v2.begin(), Transform());6.2、常用的查找算法
6.2.1、find
功能描述查找指定元素找到返回指定元素的迭代器找不到返回迭代器end()
#includeiostream
#includevector
#includealgorithm
using namespace std;//find//内置数据类型
void test01() {vectorint v1;for (int i 0; i 10; i){v1.push_back(i);}//for (int i : v1) {// cout i endl;//}vectorint::iterator it find(v1.begin(), v1.end(), 5);if (itv1.end()){cout 没有找到 endl; }else {cout 找到了 endl;}
}//自定义数据类型
class Person {
public:Person(string name, int age) {this-m_Name name;this-m_Age age;}bool operator(const Person p1) {if (p1.m_Namethis-m_Namep1.m_Agethis-m_Age){return true;}else {return false;}}string m_Name;int m_Age;
};
void test02() {vectorPerson v1;Person p1(aa, 10);Person p2(bb, 20);Person p3(cc, 30);Person p4(dd, 40);Person p5(dd, 40);v1.push_back(p1);v1.push_back(p2);v1.push_back(p3);v1.push_back(p4);vectorPerson::iterator it find(v1.begin(), v1.end(), p5);if (it v1.end()){cout 未找到 endl;}else {cout 找到了 endl;}
}6.2.2、find_if
功能描述
按照条件查询元素并返回第一个满足条件的位置的迭代器
6.2.3、adjacent_find
功能描述
查找相邻重复元素返回第一个满足条件的迭代器
#includevector
#includealgorithm
#includeiostream
using namespace std;void test01() {vectorint v;v.push_back(0);v.push_back(0);v.push_back(1);v.push_back(1);v.push_back(2);v.push_back(0);v.push_back(3);v.push_back(3);vectorint ::iterator it adjacent_find(v.begin(), v.end());if (itv.end()){cout 没找到 endl;}else {cout 找到了 *it endl;}}6.2.4、binary_search
功能描述
查找指定元素是否存在必须有序存在返回true 不存在 false
#includevector
#includealgorithm
#includeiostream
using namespace std;void test01() {vectorint v;for (int i 0; i 10; i){v.push_back(i);}if (binary_search(v.begin(), v.end(), 10)){cout 找到了 endl;}else{cout 没有 endl;}
}6.2.5、count
功能描述
统计元素个数返回int的数据
void test01() {vectorint v;v.push_back(10);v.push_back(10);v.push_back(30);v.push_back(10);v.push_back(50);int num count(v.begin(), v.end(), 10);cout num endl;
}class Person {
public:Person(string name,int age) {this-m_Name name;this-m_Age age;}//必须重载号才能对比自定义数据类型bool operator(const Person a) {if (this-m_Name a.m_Name this-m_Age a.m_Age){return true;}else {return false;}}string m_Name;int m_Age;
};void test02() {vectorPerson v2;Person p1(aa, 10);Person p2(aa, 10);Person p3(ba, 20);Person p4(ca, 30);Person p5(aa, 10);v2.push_back(p1);v2.push_back(p2);v2.push_back(p3);v2.push_back(p4);int num count(v2.begin(), v2.end(), p5);cout num endl;
}6.2.6、count_if
功能描述
按照条件统计元素个数
6.3、排序算法
6.3.1、sort
功能描述
对容器内元素进行排序默认升序降序需要加greater()
sort(v.begin(),v.end(),greaterint())6.3.2、random_shuffle
功能描述
洗牌 指定范围内的元素随机调整次序
random_shuffle(v.begin(),v.end())//可以模拟真实的随机 加一个随机数种子
#includectime
strand((unsigned)time(NULL));6.3.4、merge
功能描述
容器元素合并并存储到另一个容器俩个容器都必须有序
//目标容器
vectorint vTarget;
vTarget,resize(v1.size()v2.size())
merge(v1.begin(),v1.end(),v2.begin(),v2.end(),vTarget.begin());6.3.5、reverse
功能描述
反转指定范围的元素
reverse(v.begin(),v.end());6.4、拷贝和替换算法
6.4.1、copy
功能描述
容器内指定范围的元素拷贝到另一个容器中
//新容器
vectorint v2;
v2.resize(v1.size());
copy(v1.begin(),v1.end(),v2.begin());6.4.2、replace
功能描述
将容器内指定范围的旧元素修改为新元素
replace(v.begin(),v.end(),oldValue,newValue);6.4.3、replace_if
功能描述
将容器内指定范围满足条件的元素替换为新元素
//_pred规则
class Greater30{
public:bool operator()(int val){return val30;}
}
//_pred 指的就是你自定义的规则
replace(v.begin(),v.end(),_pred,newValue);6.4.4、swap
功能描述
互换俩个容器的元素两个容器必须同等类型
//swap(container c1,container c2);
vectorint v1;
vectorint v2;swap(v1,v2);6.5、常用算数生成算法
头文件
#include numeric6.5.1、accumulate
功能描述
计算区间内 容器元素累计总和
//accumulate(iterator beg,iterator end,value);
//value 起始的累加值accumulate(v.begin(),v.end(),0);6.5.2、fill
功能描述
向容器中添加元素
//fill(iterator beg,iterator end,value);
//value 起始的累加值fill(v.begin(),v.end(),100);6.6、常用集合算法
注意事项使用方法前必须保证容器是有序的
6.6.1、set_intersection
功能描述
求两个容器的交集
vectorint vTarget;
vTarget,resize(v1.size()v2.size());set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),vTarget.begin());6.6.2、set_union
功能描述
求两个容器的并集
vectorint vTarget;
vTarget,resize(v1.size()v2.size());set_union(v1.begin(),v1.end(),v2.begin(),v2.end(),vTarget.begin());6.6.3、set_difference
功能描述
求两个容器的差集
vectorint vTarget;
vTarget,resize(两个容器中较大的容器的大小);set_difference(v1.begin(),v1.end(),v2.begin(),v2.end(),vTarget.begin());