- 实验内容
- 初识STL
- STL的诞生
- STL的六大组件
- 容器
- 算法
- 迭代器
- vector存放内置数据类型
- vector存放自定义数据类型
- vector容器嵌套容器
- 撰写自己的算法和函数,结合容器和迭代器解决序列变换,像素变换
- 序列变换
- 像素变换
- set
- 用set存储学生信息,并进行增删改查 *** 作
- map
- 输入一个字符串,用map统计每个字符出现的次数并输出字符及对应的次数
- 自写案例
- 撰写自己的算法和函数,结合容器和迭代器解决序列变换(如取反、平方、立方),像素变换(二值化、灰度拉伸);
- 用set存储学生信息,并进行增删改查 *** 作;
- 输入一个字符串,用map统计每个字符出现的次数并输出字符及对应的次数。
- 长久以来,软件界一直希望建立一种可重复利用的东西
- C++的面向对象和泛型编程思想,目的就是复用性的提升
- 大多情况下,数据结构和算法都未能有一套标准,导致被迫从事大量重复工作
- 为了建立数据结构和算法的一套标准,诞生了STL
STL大体分为六大组件,分别是:容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器
1.容器:各种数据结构,如vector、list、 deque、set、map等,用来存放数据。
2.算法:各种常用的算法,如sort、find、copy、for_each等
3.迭代器:扮演了容器与算法之间的胶合剂。
4.仿函数:行为类似函数,可作为算法的某种策略。
5.适配器:一种用来修饰容器或者仿函数或迭代器接口的东西。
6.空间配置器:负责空间的配置与管理。
容器:置物之所也
STL容器就是将运用最广泛的一些数据结构实现出来
常用的数据结构:数组,链表,树,栈,队列,集合,映射表等
这些容器分为序列式容器和关联式容器两种:
序列式容器:强调值的排序,序列式容器中的每个元素均有固定的位置。关联式容器:二叉树结构,各元素之间没有严格的物理上的顺序关系
算法:问题之解法也
有限的步骤,解决逻辑或数学上的问题,这一门学科我们叫做算法(Algorithms)
算法分为:质变算法和非质变算法。
质变算法:是指运算过程中会更改区间内的元素的内容。例如拷贝,替换,删除等等
非质变算法:是指运算过程中不会更改区间内的元素内容,例如查找、计数、遍历、寻找极值等等
迭代器:容器和算法之间粘合剂
提供一种方法,使之能够依序寻访某个容器所含的各个元素,而又无需暴露该容器的内部表示方式。每个容器都有自己专属的迭代器
迭代器使用非常类似于指针,初学阶段我们可以先理解迭代器为指针
常用的容器中迭代器种类为双向迭代器,和随机访问迭代器
STL中最常用的容器为vector,可以理解为数组
容器:vector
算法:for_each
迭代器:vector
//创建一个vector容器 vectorv; //向容器中插入数据 v.push_back(10); v.push_back(20); v.push_back(30); v.push_back(40); //通过迭代器访问容器中的数据 vector ::iterator itBegin = v.begin()//起始迭代器,指向容器中第一个元素 vector ::iterator itEnd = v.end()//结束迭代器,指向容器中最后一个元素的下一个位置 //第一种遍历方式 while(itBegin != itEnd) { cout<<*itBegin< ::iterator it = v.begin();it != v.end();it++) { cout<<*it< 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() { vectorv; Person p1("a",10); Person p2("b",20); Person p3("c",30); Person p4("d",40); //向容器中添加数据 v.push_back(p1); v.push_back(p2); v.push_back(p3); v.push_back(p4); //遍历容器中的数据 for(vector ::iterator it;it!=v.end();it++) { //方法一: cout<<(*it).m_name; cout<<(*it).m_age< m_name; cout< m_age< vector容器嵌套容器 void test01() { vector>v; //创建小容器 vector v1; vector v2; vector v3; vector v4; //往小容器红插入数据 for(int i=0;i<4;i++) { v1.push_back(i+1); v1.push_back(i+2); v1.push_back(i+3); v1.push_back(i+4); } //将小容器插入到大容器 v.push_back(v1); v.push_back(v2); v.push_back(v3); v.push_back(v4); //遍历 for(vector >::interator it=v.begin();it!=v.end();it++) { for(vector ::iterator vit=(*it).begin();vit!=(*it).end();vit++) { cout<<*vit< 撰写自己的算法和函数,结合容器和迭代器解决序列变换,像素变换 序列变换 //取反 templateT InvT(T a) { return -a; } //平方 T SqrT(T a) { return a*a; } //立方 T CubeT(T a) { return a*a*a; } //自定义 *** 作运算函数 template void transCalcT(inputIter begInput, inputIter endInput, outputIter begOutput, MyOperator op) { for(;begInput != endInput;begInput++, begOutput++) { *begOutput = op(*begInput); } } //测试函数 void test01() { const int N = 5; int a[N] = {1,2,3,4,5}; int b[N]; //设置一个容量为5的容器vb,数据类型为double vector像素变换vb(N); transCalcT(a,a+N,vb.begin(),InvT ); } // 二值化 templatesetclass MyThreshold{ public: MyThreshold(int n=128):_nThreshold(n){} int operator()(T val) { //在二值化过程中,对每一个像元进行二值化处理,若小于2,则置为0,反之则置为1 return val<_nThreshold?0:1; } int _nThreshold; }; //灰度变换 template class Mytrans { public: Mytrans(int n=128):c(n){} int operator()(T val) { //将每一个像元大小增加10 return val+=10; } int c; }; 基本概念:
用set存储学生信息,并进行增删改查 *** 作
所有元素都会在插入时自动被排序
本质:
set/multiset属于关联式容器,底层结构是用二叉树实现。
set和multiset区别:
set不允许容器中有重复的元素;multiset允许容器中有重复的元素//用set存储学生信息,并进行增删改查 *** 作 //创建一个Student类 class Student { public: Student(string name, int age) { //初始化赋值 this->m_name = name; this->m_age = age; } string m_name; int age; } class compareStudent { public: bool operator()(const Student&s1, const Student&s2) { //按照年龄降序 return p1.m_age > p2.m_age; } // 根据姓名删除元素 bool del(string Name){ for(auto it:s){ if(!Name.compare(it.m_name)){ s.erase(it); return true; } } return true; } // 根据姓名查找年龄 int searchAge(string Name){ for(auto it:s){ if(!Name.compare(it.m_name)){ return it.m_age; } } return -1; } // 根据姓名修改年龄 void updateInfo(string name, int afterAge){ for(auto it:s){ if(it.m_name==name){ s.erase(it); break; } } s.insert(Student(name, afterAge)); }//测试函数 void test01() { //自定义数据类型,都会制定排序规则 sets; //创建学生信息 Student s1("刘备",20); Student s2("关羽",25); Student s3("张飞",36); Student s4("赵云",41); //插入set容器中 s.insert(s1); s.insert(s2); s.insert(s3); s.insert(s4); //遍历s中的学生信息 for(set ::iterator it = s.begin();it!=s.end();it++) { cout<<"姓名: "< m_name<<" 年龄: "< m_age< map map的基本概念:
map中所有元素都是pair
pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
所有元素都会根据元素的键值自动排序
本质:
map/multimap属于关联式容器,底层结构是用二叉树实现。
优点:
可以根据key值快速找到value值
map和multimap区别:
map不允许容器中有重复key值元素
multimap允许容器中有重复key值元素map默认构造函数:map
输入一个字符串,用map统计每个字符出现的次数并输出字符及对应的次数mp
map拷贝构造函数:map(const map &mp)
赋值 重载等号 *** 作符:map& operator=(const map &mp)void countChar(string str){ mapcountChar; //遍历字符串中的每一个字符 for(int i = 0;i 自写案例 需要完成的内容:
- 公司今天招聘了10个员工(ABCDEFGHI),10名员工进入公司之后,需要指派员工在哪个部门工作
- 员工信息有:姓名 工资组成,部门分为、策划、美术、研发
- 随机给10名员工分配部门和工资
- 通过multimap进行信息的插入key(部门编号)value(员工)
- 分部门显示员工信息
class Worker { public: string m_name; int m_salary; }; //创建员工 void createWorker(vector&v) { string nameSeed = "ABCDEFGHIJ"; for(int i=0;i<10;i++) { Worker worker; worker.m_name = "员工"; worker.m_name += nameSeed[i]; worker.m_salary = rand()%10000+10000;//10000~19999 //将员工放到容器中 v.push_back(worker); } } //员工分组 void setGroup(vector &v,multimap &m) { for(vector ::iterator it = v.begin();it!=v.end();it++) { //产生随机部门编号 int deptID = rand()%3;//三个部门 //将员工插到分组中,key部门编号,value具体员工 m.insert(make_pair(deptID, *it); } } //分组显示员工 void showWorkerByGroup(multimap &m) { cout<<"策划部门; "< ::iterator pos = m.find(0); int count = m.count(0); int index = 0; for(;pos!=m.end() && index second.m_name<<" 工资: "< second.m_salary< second.m_name<<" 工资: "< second.m_salary< second.m_name<<" 工资: "< second.m_salary< //主函数 int main() { //1、创建员工 vectorvWorker; createWorker(vWorker); //2、员工分组 multimap mWorker; setGroup(vWorker, mWorker); //3、分组显示员工 showWorkerByGroup(mWorker); system("pause"); return 0; } 欢迎分享,转载请注明来源:内存溢出
评论列表(0条)