文章目录
- 【C++实战四】STL初体验
-
- 1. STL的基本概念和组成
- 2. 自定义函数实现序列变换
- 3. 自定义函数实现像素变换
- 4. 通过set集合实现简单的学生管理系统
- 5. 通过map关联容器实现字符统计
- 6. 总结
【C++实战四】STL初体验 1. STL的基本概念和组成 基本概念:STL全称是Standard template library,也叫做标准模板库,其中包含有大量的模板类和模板函数。也可以说STL 是一些容器、算法和其他一些组件的集合。
三大核心组件:容器、算法、迭代器
组成 | 含义 |
---|---|
容器 | 一些封装数据结构的模板类,例如vector,list等 |
算法 | 一些被设计成模板函数的数据结构算法 |
迭代器 | 实现对容器数据的读和写,扮演着容器和算法之间的胶合剂 |
定义序列容器的操作模板:
// 定义模板实现容器的批量操作,其中MyOperator实现单元素的操作
template
void Batch_op(T a, T& b, int Num, MyOperator op)
{
for(int i=0;
i
定义不同序列变换操作模板:
// 取反操作
template
T InvT(T a)
{
return -a;
}// 平方操作
template
T Sqrt(T a)
{
return a * a;
}// 立方操作
template
T Cube(T a)
{
return a * a * a;
}
测试函数:
void test()
{
// 初始化向量
vector a{1,2,3,4,5,6,7,8,9,10};
vector b(10);
// 初始化迭代器用于容器的读取
vector::iterator i;
// 取反输出
cout << "序列取反输出:";
Batch_op(a,b,10,InvT);
for(i = b.begin();
i != b.end();
i++)
cout << *i << " ";
cout << endl;
// 平方输出
cout << "序列平方输出:";
Batch_op(a,b,10,Sqrt);
for(i = b.begin();
i != b.end();
i++)
cout << *i << " ";
cout << endl;
// 立方输出
cout << "序列立方输出:";
Batch_op(a,b,10,Cube);
for(i = b.begin();
i != b.end();
i++)
cout << *i << " ";
}
运行结果:3. 自定义函数实现像素变换 定义图像的操作模板:
序列取反输出:-1 -2 -3 -4 -5 -6 -7 -8 -9 -10
序列平方输出:1 4 9 16 25 36 49 64 81 100
序列立方输出:1 8 27 64 125 216 343 512 729 1000
// 定义图像操作模板
template
void batch_pix(Mat &src, int w, int h, MyOperator op)
{
// 逐像素操作
for(int row=0;
row(row, col) = op(src.at(row, col));
}
}
}
定义不同像素变换操作模板:
// 对数变换
template
class logTransform
{
public:
int C;
double Gamma;
logTransform(int c=1, double gamma = 1.0):C(c),Gamma(gamma){}
// 重载操作符
int operator()(T val)
{
float Val = float(val)/255;
return 255 * C * log(1+Val*(Gamma-1)) / log(Gamma);
}
};
// 图像二值化
template
class MyThreshold
{
public:
int threshold;
MyThreshold(int n=128):threshold(n){}
// 重载操作符
int operator()(T val)
{
//大于阈值*255
return (val > threshold)*255;
}
};
测试代码:
using namespace std;
#include
#include
#include
#include
using namespace cv;
int main(){
// 读取图像
Mat img=imread("D:\\desktop\\1.png",0);
// 读取图像宽高
int w = img.cols;
int h = img.rows;
// 显示原始图像
imshow("original", img);
// 显示二值图像
batch_pix(img, w, h ,MyThreshold(128));
imshow("erzhi", img);
// 灰度变换操作
//batch_pix(img, w, h ,logTransform(1, 100));
//imshow("gamma=100", img);
waitKey(0);
return 0;
}
二值化结果:
文章图片
【c++|【C++实战四】STL初体验】对数变换结果:
文章图片
4. 通过set集合实现简单的学生管理系统 set容器的常用操作:
函数 | 作用 |
---|---|
s.size( ) | 返回容器中的元素个数 |
s.begin( ) | 返回容器中的第一个元素 |
s.end( ) | 返回容器中的最后一个元素 |
s.clear( ) | 清空容器中的所有元素 |
s.empty( ) | 判断容器是否为空 |
s.insert( ) | 插入一个元素 |
s.erase( ) | 删除一个元素 |
// 包括构造函数和运算符重载
class studentInfo {
public:
//两个参数的构造函数
studentInfo(string strNo, string strName) {
_strNo = strNo;
_strName = strName;
}
string _strNo;
string _strName;
//输出符重载
friend ostream& operator<<(ostream& os, const studentInfo& info)
{
os << info._strNo << ": " << info._strName;
os << endl;
return os;
}
//比较学号大小
friend bool operator < (const studentInfo& info1, const studentInfo& info2) {
return info1._strNo < info2._strNo;
}
};
测试函数:
void TestSet()
{
vector> students;
// 插入学生对象信息(动态push)
students.push_back(studentInfo("10021", "Zhaohong Huang"));
students.push_back(studentInfo("10002", "Haotian Yan"));
students.push_back(studentInfo("10003", "Jiawen Liu"));
students.push_back(studentInfo("10011", "Xinyu Hu"));
students.push_back(studentInfo("10010", "Tao Zi"));
// 建立set容器
set> studentSet(students.begin(), students.end());
// 初始化迭代器
set>::iterator i;
//遍历学生信息(自动排序)
for(i = studentSet.begin();
i != studentSet.end();
i++)
cout << *i << " ";
cout << "-----------" << endl;
//删除指定学号
studentSet.erase(studentInfo("10021", "Zhang san"));
for(i = studentSet.begin();
i != studentSet.end();
i++)
cout << *i << " ";
cout << "-----------" << endl;
//查询指定学号的学生姓名
const char* num = "10002";
for (i = studentSet.begin();
i != studentSet.end();
i++)
{
if (((*i)._strNo).compare(num) == 0)
cout <<"该学号对应的学生姓名为:"<< (*i)._strName << " ";
}
}
运行结果:
10002: Haotian Yan5. 通过map关联容器实现字符统计 map是STL的一个关联容器,它提供一对一的服务(有点类似python中的字典)。其中第一个称为关键字(仅出现一次),第二个称为关键字的值。且map内部自建一颗红黑树,这棵树具有对数据进行自动排序的功能。
10003: Jiawen Liu
10010: Tao Zi
10011: Xinyu Hu
10021: Zhaohong Huang
-----------
10002: Haotian Yan
10003: Jiawen Liu
10010: Tao Zi
10011: Xinyu Hu
-----------
该学号对应的学生姓名为:Haotian Yan
void TestMap()
{
// 初始化map,可见一对一(关键字是char型的,关键字的值是int型的)
map word_count;
const char* word = "JMU-HZH";
// 对关键字的值进行赋值
for (int i = 0;
i < strlen(word);
i++)
{
++word_count[word[i]];
}
// 初始化map的迭代器
map::iterator iter;
// 计数输出
for (iter = word_count.begin();
iter != word_count.end();
iter++)
{
cout << "[" << iter->first << "]的个数 = " << iter->second << endl;
}
}
运行结果:
[-]的个数 = 16. 总结 本篇博客实现了一些STL的简单应用,并结合了opencv等相关内容。首先,STL是C++代码编写中一个很好的工具,它可以提高编码效率,且可以丰富代码的灵活性;同时,STL的应用充分结合了之前学习的函数重载,函数模板,虚函数等内容,说明一个完整的C++工程需要灵活且丰富的知识联动性。
[H]的个数 = 2
[J]的个数 = 1
[M]的个数 = 1
[U]的个数 = 1
[Z]的个数 = 1
推荐阅读
- 计算机视觉|计算机视觉(二)(局部图像描述子)
- CS111 EIE111
- 学习|java-->方法案例(公司迟到措施)
- #|STL迭代器详解
- 蓝桥杯|ACwing789. 数的范围 (二分法典型例题)
- 算法笔记|HDU - 2041 超级楼梯 (简单DP)
- 特殊算法技巧|康托展开简单记录
- Linux系统编程|【Linux】环境变量
- 初阶数据结构与算法|【初阶数据结构与算法】第七篇(二叉树和堆的基本概念+以及堆的实现)