c++|【C++实战四】STL初体验


文章目录

  • 【C++实战四】STL初体验
    • 1. STL的基本概念和组成
    • 2. 自定义函数实现序列变换
    • 3. 自定义函数实现像素变换
    • 4. 通过set集合实现简单的学生管理系统
    • 5. 通过map关联容器实现字符统计
    • 6. 总结

【C++实战四】STL初体验 1. STL的基本概念和组成 基本概念:STL全称是Standard template library,也叫做标准模板库,其中包含有大量的模板类和模板函数。也可以说STL 是一些容器、算法和其他一些组件的集合。
三大核心组件:容器、算法、迭代器
组成 含义
容器 一些封装数据结构的模板类,例如vector,list等
算法 一些被设计成模板函数的数据结构算法
迭代器 实现对容器数据的读和写,扮演着容器和算法之间的胶合剂
2. 自定义函数实现序列变换 序列变化是我们经常会遇到的,且我们经常结合容器实现序列变化,例如取反,平方,立方等操作。并采用迭代器进行容器数据的读写。
定义序列容器的操作模板:
// 定义模板实现容器的批量操作,其中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 << " "; }

运行结果:
序列取反输出:-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
3. 自定义函数实现像素变换 定义图像的操作模板:
// 定义图像操作模板 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初体验
文章图片

【c++|【C++实战四】STL初体验】对数变换结果:
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 Yan
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
5. 通过map关联容器实现字符统计 map是STL的一个关联容器,它提供一对一的服务(有点类似python中的字典)。其中第一个称为关键字(仅出现一次),第二个称为关键字的值。且map内部自建一颗红黑树,这棵树具有对数据进行自动排序的功能。
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; } }

运行结果:
[-]的个数 = 1
[H]的个数 = 2
[J]的个数 = 1
[M]的个数 = 1
[U]的个数 = 1
[Z]的个数 = 1
6. 总结 本篇博客实现了一些STL的简单应用,并结合了opencv等相关内容。首先,STL是C++代码编写中一个很好的工具,它可以提高编码效率,且可以丰富代码的灵活性;同时,STL的应用充分结合了之前学习的函数重载,函数模板,虚函数等内容,说明一个完整的C++工程需要灵活且丰富的知识联动性。

    推荐阅读