1.STL--standard template library标准模板库
类模板构成容器  函数模板构成算法

1)迭代器(it):++,*,->,==,!=
     输入迭代器:可读*it的值,但不一定能修改(设置)*it的值
     输出迭代器:可以设置*it的值,但不一定能读取*it的值
     前向迭代器:可以读取也可以设置*it的值
     双向迭代器:支持--
     随机迭代器:几乎跟指针一样,支持--,+n,-n,比较大小,[下标]

2)适配器:是使一事物的行为类似于另一事物的行为的一种机制,包括容器适配器,迭代器适配器和函数适配器。

3)函数模板(通用算法algorithm)--->关于算法的  查找 排序
     内容太多,通用算法依赖迭代器实现,可以从头到尾遍历整个容器的方法
   for_each()  find find_if  count count_if sort copy
   iterator find(pos_beg, pos_end, data)
   iterator find_if(pos_beg, pos_end, cond), bool cond(element)

int count(...), int count_if(...)

01sort.cpp

#include <string>
#include <algorithm>  //sort排序算法需要的头文件class Person
{string name;int age;
public:Person(const char* name, int age):name(name),age(age){}friend ostream&operator<<(ostream&o,const Person&p){return o<<p.name<<':'<<p.age;}friend bool operator<(const Person& a,const Person& b){return a.age<b.age;}
};template<typename T>
void print(T b, T e)
{while(b!=e)cout << *b++ << ' ';cout << endl;
}int main()
{int a[6]={8,1,6,3,2,5};double b[4]={5.5,3.3,6.6,2.2};string c[5]={"nice","to","see","you","all"};Person d[3]= {Person("芙蓉",18),Person("杨强",20),Person("薇薇",16)};sort(a,a+6);sort(b,b+4);sort(c,c+5);sort(d,d+3);print(a,a+6);print(b,b+4);print(c,c+5);print(d,d+3);  //半开区间 [)含头不含尾return 0;
}

4)类模板(容器containter)---->关于数据结构  数组 链表 栈 队列 二叉树
       a.标准容器:序列(顺序)式容器(vector是个能够存放任意类型的动态数组,能够增加和压缩数据;deque适合首尾删除增加;list链表)
           关联式容器(set不允许重复;multiset允许重复;map不允许重复;multimap允许重复)
           迭代器(标准容器类都有一个内部类iterator,支持* -> ++ == !=),用来访问容器里的内容
            插入迭代器,iostream迭代器,反向,const迭代器,
              五种迭代器:输入,输出,前向,双向,随机访问迭代器
            迭代器是封装成类的指针,数组里面,指针是最原始的迭代器
            每种容器都自己负责封装迭代器类

b.容器适配器(特殊容器):栈 队列 优先队列

c.函数对象:(仿函数)对象能像函数一样使用,比如重载()运算符

d.内存分配器allocator

标准容器(类模板)共性://特殊容器不支持下面操作
   构造函数(包括无参构造,拷贝构造,区间构造(两个迭代器表示的两个位置))
   析构函数

迭代器相关函数:

iterator,reverse_iterator,const_iterator,const_reverse_iterator

.begin()正向iterator,返回指向第一个元素位置的迭代器

.end()返回指向超越最后一个位置的迭代器
           .rbegin()反向reverse_iterator,反向迭代器

.rend()

标准都支持 * -> == ++ -- = !=
   插入:.insert(pos,element)  其中pos是个表示位置的迭代器
   删除:.erase(pos), .erase(pos_beg,pos_end)
   清除:.clear() 清除容器里所以的数据
   大小:.size()  .max_size()
   交换:.swap(c2) (成员函数) .swap(c1,c2)(通用算法也就是函数)

运算:= > < >= <= == !=

02container.cpp

#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include "print.h"
int main()
{int a[5]={33,22,11,55,44};vector<int> vi(a,a+5);cout << vi.size() << endl;sort(vi.begin(), vi.end());//只能是数组、vector和dequevector<int>::iterator b = vi.begin();while(b!=vi.end())cout << *b++ << ' ';cout << endl;for(int i=0; i<5; i++)cout << a[i] << ',';cout << endl;print(vi.begin(), vi.end());print(a, a+5);print(vi.rbegin(), vi.rend());b = vi.begin();vi.insert(++++b,66);vi.insert(vi.begin(), 77);vi.insert(vi.end(),88);print(vi.begin(), vi.end());cout << vi.size() << '/' << vi.max_size() << endl;vi.erase(------vi.end());print(vi.begin(), vi.end());vi.erase(++++vi.begin(),--vi.end());print(vi.begin(), vi.end());vector<int> v2(a,a+5);print(v2.begin(), v2.end());cout << "==================" << endl;vi.swap(v2);print(vi.begin(), vi.end());print(v2.begin(), v2.end());cout << "==================" << endl;swap(vi,v2);print(vi.begin(), vi.end());print(v2.begin(), v2.end());cout << "==================" << endl;vector<int> t=vi;vi = v2;v2 = t;print(vi.begin(), vi.end());print(v2.begin(), v2.end());vi.clear();cout << vi.size() << endl;print(vi.begin(), vi.end());vector<int> x;cout << "vector当前容量:" << x.capacity() << endl;
}

print.h

#ifndef PRINT_H
#define PRINT_H 1
//输出一个指定区间中的所有数据(含头不含尾)
template<typename T>
void print(T b, T e, char c=' ')
{while(b!=e)cout << *b++ << c;cout << endl;
}
#endif

————————————————————————————————————————
序列式容器共性vector deque list:
  构造函数:增加了指定元素个数和初始值(初始值默认是0)
  插入:.insert(pos,n,element)  .insert(pos,pos_beg,pos_end)

赋值:.assign(n,element)  .assign(pos_beg,pos_end) 旧的全部清理新的插入(pos_beg和pos_end是其他 列的位置)

调整:.resize(n,element=0) 把大小调整为n 添加的个数的内容是element
  首尾:.front(), .back()  可以修改首尾元素的值

增删:.push_back(element)  .pop_back() 只删除,返回void

03sequence.cpp

#include <deque>
#include <iostream>
using namespace std;
#include "print.h"
#include <string>int main()
{deque<string> ds;
//  deque< vector<int> >;ds.push_back("曾文武");ds.push_back("赵旭泽");ds.push_back("薛小娟");ds.push_back("高上");print(ds.begin(),ds.end(),',');ds.insert(++++ds.begin(),2,"芙蓉");print(ds.begin(),ds.end(),',');string s[3]={"张彦春","张永香","刘克磊"};ds.insert(----ds.end(),s,s+3);print(ds.begin(),ds.end(),',');ds.pop_back(); ds.pop_back();print(ds.begin(),ds.end(),',');cout << "front:" << ds.front() << ",back:" << ds.back() << endl;ds.resize(12,"郭益如");print(ds.begin(),ds.end(),',');ds.assign(5,"康森林");print(ds.begin(),ds.end(),',');//ds.clear();ds.front() = "孙冬冬";ds.back() = "梁振杰";print(ds.begin(),ds.end(),',');
}

print.h

<span style="font-size:18px;">#ifndef PRINT_H
#define PRINT_H 1
//输出一个指定区间中的所有数据(含头不含尾)
template<typename T>
void print(T b, T e, char c=' ')
{while(b!=e)cout << *b++ << c;cout << endl;
}
#endif
</span>

个性:
  1.vector个性:其实就是一个动态数组(数组实现) 当容量不够时重新分配的大小是原来的两倍
     vector迭代器在插入删除之后可能会失效因为可能会重新分配内存,如果插入删除过再用迭代器需要重新去取得
     当前容量:.capacity()
     约定容量:.reserver(n)只要不超过这个容量就不用重新再分配,以免反复重新分配空间

下标[]:   .operator[](i)不检查越界  .at(i)这个函数做越界检查,越界会抛出异常

04vector.cpp

#include <iostream>
using namespace std;
#include <vector>
#include "print.h"
#include <exception>
#include <typeinfo>int main()
{vector<double> vd, vv;for(int i=0; i<9; i++){vd.push_back(i+0.1);cout << &*vd.begin() << ':';得到首个元素的地址 会发现有变化cout << vd.size() << '/' << vd.capacity() << endl;}cout << "------------------" << endl;vv.reserve(9);for(int i=0; i<9; i++){vv.push_back(i+0.5);cout << vv.size() << '/' << vv.capacity() << endl;}vd[3] = 123.45;vv.at(5) = 67.8;for(int i=0; i<=vd.size(); i++)cout << vd[i] << ' ';cout << endl;try{for(int i=0; i<=vv.size(); i++)cout << vv.at(i) << ' ';cout << endl;}catch(exception& e){cout << "异常:" << e.what() << endl;cout << "类型:" << typeid(e).name() << endl;}int m=3, n=5;void print(const vector< vector<int> >& v);vector< vector<int> > vvi(m, vector<int>(n) );//二维数组print(vvi);vvi.resize(m+3);vvi[1].assign(9,1);vvi[5].assign(4,5);print(vvi);
}
void print(const vector< vector<int> >& v)
{for(int i=0; i<v.size(); i++){for(int j=0; j<v[i].size(); j++){cout << v[i][j] << ' ';}cout << endl;}
}

2.deque的个性:double-ended queue
    下标[]: .operator[](i) 不检查越界, .at(i)越界抛异常

增删: .push_front(element), .push_back() .pop_front() .pop_back()

适合从前面插入或删除数据

05deque.cpp

#include <iostream>
using namespace std;
#include <deque>
#include "print.h"
int main()
{deque<char> dc;dc.push_back(97);dc.push_back('c');dc.push_front('s');dc.push_front('d');dc.push_back('k');dc.push_front('$');print(dc.begin(),dc.end());//该函数在前面类中有定义dc[1] = 't';for(int i=0; i<dc.size(); i++)cout << dc[i] << ',';cout << endl;dc.pop_back();dc.pop_front();print(dc.begin(),dc.end());
}

3.list的个性:双向链表
    增删:.push_front(element), .pop_front(), .remove(element)//==
    不支持下标[]
    除重:.unique()相邻的重复元素只保留一个
    排序:.sort(compare_func=less)默认用小于符号比较,从小到大排序
    倒置:.reverse()颠倒链表中元素顺序
    转移:.splice(pos,list2), .splice(pos,list2,pos2), .splice(pos,list2,pos_beg,pos_end)

归并:.merge(list2) 两组都排好序的归并后的结果才是排好序的

06list.cpp

#include <iostream>
using namespace std;
#include <list>
#include "print.h"
#include <cassert>
bool compare(int x, int y)
{x%=3, y%=3;return x<y;
}
int main()
{int a[10]={3,8,8,8,5,5,1,8,8,7}, b[6]={9,3,5,2,7,6};list<int> li(a,a+10), lili(b,b+6);print(li.begin(), li.end());li.unique();print(li.begin(), li.end());li.sort();print(li.begin(), li.end());li.unique();print(li.begin(), li.end());li.reverse();print(li.begin(), li.end());li.splice(li.begin(),lili);//转移之后lili为空print(li.begin(), li.end());assert(lili.empty());li.remove(5);print(li.begin(), li.end());li.sort();li.unique();print(li.begin(), li.end());lili.push_back(0);lili.push_back(4);lili.push_back(7);lili.push_back(5);lili.push_back(10);lili.sort();print(lili.begin(), lili.end());li.merge(lili);print(li.begin(), li.end());lili.assign(b,b+6);print(lili.begin(), lili.end());lili.sort(greater<int>());print(lili.begin(), lili.end());lili.sort(compare);print(lili.begin(), lili.end());
}

———————————————————————————————————————————  
关联式容器共性:都是用二叉查找树实现的,都自动根据关键字排序
  set<K>,  multiset<K>, map<K,V>, multimap<K,V)
  查找:.find(key)返回一个迭代器指向找到的第一个元素,失败返回.end()
  统计:.count(key)统计关键字等于key的元素的个数
  删除:.erase(key)删除关键字等于key的所有元素
  区间:.lower_bound(key)取得关键字为key的第一个元素的位置, .upper_bound(key)取得关键字 为key的最后一个元素之后的位置, .equal_range(key)一次取得关键字为key的元素的区间,返回一个pair

插入: .insert(element)//由于是二叉查找树实现的所以插入的时候不用指定位置

01associate.cpp

#include <set>
#include <iostream>
using namespace std;
#include "../stl1/print.h"
struct Person{string name;int age;
public:Person(const char* n, int a):name(n),age(a){}
};
bool operator<(const Person& a, const Person& b)
{return a.age<b.age||a.age==b.age&&a.name<b.name;}
ostream& operator<<(ostream&o, const Person& x)
{return o<<x.name<<':'<<x.age;}
int main()
{multiset<Person> mp;mp.insert(Person("赵元培",26));mp.insert(Person("郭益如",18));mp.insert(Person("姚连斌",20));mp.insert(Person("赵元培",26));mp.insert(Person("赵元培",26));mp.insert(Person("王臣彬",21));mp.insert(Person("郭益如",18));mp.insert(Person("姚连斌",20));mp.insert(Person("张洪铭",22));mp.insert(Person("赵元培",26));mp.insert(Person("郭益如",18));mp.insert(Person("王臣彬",21));mp.insert(Person("郭益如",18));mp.insert(Person("王臣彬",21));mp.insert(Person("郭益如",18));print(mp.begin(), mp.end());multiset<Person>::iterator it=mp.find(Person("张洪铭",22));if(it==mp.end()) cout << "没有找到张洪铭" << endl;else cout << "发现目标:" << *it << endl;it=mp.find(Person("芙蓉",22));if(it==mp.end()) cout << "没有找到芙蓉" << endl;else cout << "发现目标:" << *it << endl;it = mp.find(Person("郭益如",18));cout << mp.count(*it) << "个" << *it << endl;it = mp.find(Person("赵元培",26));cout << mp.count(*it) << "个" << *it << endl;multiset<Person>::iterator ib, ie;ib = mp.lower_bound(Person("王臣彬",21));ie = mp.upper_bound(Person("王臣彬",21));cout << "===================" << endl;print(ib, ie);cout << "===================" << endl;pair<multiset<Person>::iterator,multiset<Person>::iterator>p=mp.equal_range(Person("姚连斌",20));print(p.first,p.second);typedef multiset<Person>::iterator Iter;pair<Iter,Iter>q=mp.equal_range(Person("郭益如",18));print(q.first,q.second);cout << "===================" << endl;mp.erase(Person("郭益如",18));mp.erase(Person("赵元培",26));print(mp.begin(), mp.end());
}

个性:
   1.map的个性:
    不允许key重复
    强调元素是map(key,value)一对
    支持以key为下标访问对应的value的引用,如果key不存在就新增一个元素以这个为key。
    别的关联式容器不支持以Key为下标

如果存的是对应关系就用map,如果存的只是关心的数据不存在对应关系就用set,set把整个元素作为key来比较。

02map.cpp

#include <iostream>
using namespace std;
#include <map>
#include "print.h"
struct P{string name;int age;
public:P(){}P(const char* n, int a):name(n),age(a){}
};
ostream& operator<<(ostream&o, const P& x)
{return o<<x.name<<':'<<x.age;}
int main()
{map<int,P> mis;mis.insert(map<int,P>::value_type(8,P("王龙",20)));mis.insert(pair<int,P>(5,P("钟玉龙",22)));mis.insert(make_pair(4,P("李霖",21)));mis[3] = P("何军军",20);mis[6] = P("蒲嗣良",23);mis.insert(make_pair(5,P("芙蓉",18)));print(mis.begin(), mis.end());mis[6] = P("蒲松龄",300);print(mis.begin(), mis.end());
}

print.h

#ifndef PRINT_H
#define PRINT_H 1
//输出一个指定区间中的所有数据(含头不含尾)
template<typename T>
void print(T b, T e, char c=' ')
{while(b!=e)cout << *b++ << c;if(c!='\n') cout << endl;
}
template<typename K, typename V>
ostream& operator<<(ostream& o, const pair<K,V>& p)
{return o << p.first << ':' << p.second;
}
#endif

2.multimap的个性:
     允许重复key
     元素是key/value对

不支持方括号下标

04multiset.cpp

#include <map>
#include <iostream>
using namespace std;
#include "print.h"
#include <string>
int main()
{typedef multimap<string,double> MSD;MSD m;m.insert(MSD::value_type("王刚",100000));m.insert(make_pair("何军军",120000));m.insert(make_pair("杨勇",20000));m.insert(make_pair("何军军",160000));m.insert(make_pair("杨勇",3000));m.insert(MSD::value_type("王刚",220000));m.insert(MSD::value_type("王刚",150000));m.insert(make_pair("何军军",130000));m.insert(make_pair("杨勇",1000000));m.insert(make_pair("杨勇",110000));print(m.begin(), m.end());MSD::iterator ib = m.begin(), ie;MSD cnt;while(ib!=m.end()){string name = ib->first;ie = m.upper_bound(name);double sum = 0.0;while(ib!=ie) sum += ib++->second;cnt.insert(make_pair(name,sum*0.03));}print(cnt.begin(),cnt.end());
}

3.set的个性
    元素就是key
    不允许重复key  如果重复就会被抛弃

可以默认被排好序

05set.cpp

#include <set>
#include <iostream>
using namespace std;
#include <string>
#include "print.h"
#include <fstream>
int main()
{set<string> ss;//set<char*> ss;string s;//char s[100];ifstream fin("maillist");if(!fin){return 1;}while(fin>>s) ss.insert(s);print(ss.begin(), ss.end(), '\n');
}

4.multiset的个性
    元素就是key

允许有重复的key

06mutiset.cpp

#include <set>
#include <iostream>
using namespace std;
#include "print.h"
#include <string>
#include <map>
int main()
{multiset<string> ms;string name;cout << "请输入你选举的人的姓名(Ctrl+D表示结束):\n";while(cin>>name){//Ctrl+D表示输入结束ms.insert(name);}print(ms.begin(), ms.end());multiset<string>::iterator ib=ms.begin(), ie;multimap<int,string> mis;while(ib!=ms.end()){mis.insert(make_pair(ms.count(*ib),*ib));ib = ms.upper_bound(*ib);}print(mis.begin(),mis.end(),'\n');
}

————————————————————————————————————————————
迭代器:是一种检查容器内元素并遍历元素的数据类型
  标准库为每种容器定义了一种迭代器类型,而且只有少数的容器比如vecotr deque支持下标操作
  所以,一般容器都能使用迭代器来检查、遍历容器,有的还可以使用下标来实现

特殊容器:stack queue  priority_queue
相同:  .push(element)  .pop()  .empty()  都不提供迭代器
不同: 栈: .top()
       队列 .front()  .back()
       优先队列  .top() 入的时候不讲究顺序,出的时候通过堆调整来实现最大的先出

07special.cpp

#include <queue>
#include <iostream>
using namespace std;int main()
{priority_queue<int> pq;pq.push(50);pq.push(80);pq.push(20);pq.push(70);pq.push(60);pq.push(30);while(!pq.empty()){cout << pq.top() << endl;pq.pop();//最大的先出}
}

priorty_queue使用堆调整:只保证最大的在前面 不保证别的

STL——标准模板库相关推荐

  1. 补8-5日复习内容 STL 标准模板库的容器

    //有关 STL 标准模板库的函数 /* string 的 */ /* #include <iostream> #include <string> #include <w ...

  2. stl标准模板库_C ++标准模板库(STL)中的array :: fill()

    stl标准模板库 fill() is a member function of "array container", which sets a given value to all ...

  3. stl标准模板库_C ++标准模板库(STL)中的数组及其常用功能

    stl标准模板库 "array" is a container in C++ STL, which has fixed size, which is defined in &quo ...

  4. C++的STL标准模板库思维导图

    STL标准模板库思维导图 C++ 语言的核心优势之一就是便于软件的重用.C++ 中有两个方面体现重用: 一是面向对象的继承和多态机制: 二是通过模板的概念实现了对泛型程序设计的支持. C++ 的标准模 ...

  5. stl标准模板库_如何在C ++ STL(标准模板库)中使用Pair

    stl标准模板库 In this article, we'll take a look at using pair in C++ Standard Template Library (STL). 在本 ...

  6. STL 标准模板库—容器部分【C++】

    STL标准模板库 包含内容: 容器类:vector.list.deque.set.map等 迭代器:"泛型指针",每个容器都有自己的迭代器,[vector和deque的迭代器是随机 ...

  7. 19.3 C++STL标准模板库大局观-容器的说明和简单应用例续

    19.1 C++STL标准模板库大局观-STL总述.发展史.组成与数据结构谈 19.2 C++STL标准模板库大局观-容器分类与array.vector容器精解 19.3 C++STL标准模板库大局观 ...

  8. 信息学奥赛中的STL(标准模板库)--2022.09.30

    1.信息学奥赛一本通 第5版 第8章 C++实用技巧与模版库(6节) 第一节  排序算法 第二节 运算符重载 第三节  字符串(string) 第四节 FIFO队列和优先队列 第五节  动态数组 第六 ...

  9. 19.1 C++STL标准模板库大局观-STL总述、发展史、组成与数据结构谈

    19.1 C++STL标准模板库大局观-STL总述.发展史.组成与数据结构谈 19.2 C++STL标准模板库大局观-容器分类与array.vector容器精解 19.3 C++STL标准模板库大局观 ...

  10. C++ STL 标准模板库介绍与入门

    目录 1.概述 1.1.C++ 标准库 1.2.Boost库 2.STL 版本 2.1.HP 原始版本 2.2.P. J. 实现版本 2.3.RW 实现版本 2.4.SGI 实现版本 2.5.STLp ...

最新文章

  1. java创建请求拦截器_80.简单Retrofit+RxJava+日志拦截器结合使用
  2. React进阶—性能优化
  3. [置顶] Android的IPC访问控制设计与实现
  4. 160 - 32 genocide1
  5. 消息队列应用场景解析
  6. 多媒体计算机图形,计算机图形学几何造型多媒体可视化虚拟现实.DOC
  7. 显示器显示颜色差,导致BUG一例
  8. 你知道低代码BPM平台吗?
  9. 简析国内外电商的区别
  10. hive安装mysql_Hive安装MySql
  11. 如何从零学习 React 技术栈
  12. JavaSpring全面总结
  13. 利用python进行数据分析_第二章_案例2_movielens_电影评分分析
  14. 既生 HTTP 何生 WebSocket ?
  15. 助力智慧医疗|解析i.MX8MM在麻醉系统中的应用方案
  16. 2022年520最实用的礼物,苹果平板的触控笔
  17. VSCode上的Git使用手记(持续更新ing...)
  18. 【arxiv】网站打不开
  19. web网页实现打电话,发短信,发邮件等:万能的a标签
  20. 【单元复习】之标日初级下册第十一、十二单元

热门文章

  1. 校内题目T2695 桶哥的问题——吃桶
  2. python爬取英雄联盟所有皮肤价格表_用python网络爬虫爬取英雄联盟英雄图片
  3. Java联网3D坦克大战(网络编程)
  4. Java HashMap底层实现和原理分析(一)
  5. android ip 黑白名单,“IP 黑白名单”功能说明
  6. 贪婪的大脑:为何人类会无止境地寻求意义 目录
  7. ValidateCode源码
  8. php三D立体模拟,【HTML5】3D模型--百行代码实现旋转立体魔方实例
  9. 信迈AM5728 DSP+ARM高性能图像处理核心板功能介
  10. 安装python时无法访问筛选器,如何使用Python筛选器功能(详解)