First Experience of STL
1. Basic concepts and composition of STL
Basic concepts: The full name of STL is the Standard template library, also known as the standard template library, which contains a large number of template classes and template functions. STL is also a collection of containers, algorithms, and other components.
Three core components: container, algorithm, iterator
Form | Meaning |
---|---|
container | Some template classes that encapsulate data structures, such as vector s, list s, and so on |
algorithm | Some data structure algorithms designed as template functions |
iterator | Read and write container data, acting as glue between containers and algorithms |
2. Custom function for sequence transformation
Sequence changes are common to us, and we often combine containers to achieve sequence changes, such as inversion, square, cube, and so on. Iterators are used to read and write container data.
Define the operation template for the sequence container:
// Define templates to implement bulk operations on containers, where MyOperator implements operations on elements template <class T, class MyOperator> void Batch_op(T a, T& b, int Num, MyOperator op) { for(int i=0;i<Num;i++) { b[i] = op(a[i]); } }
Define different sequence transformation operation templates:
// Reverse operation template<class T> T InvT(T a) { return -a; } // Square operation template<class T> T Sqrt(T a) { return a * a; } // Cube operation template<class T> T Cube(T a) { return a * a * a; }
Test function:
void test() { // Initialization vector vector<int> a{1,2,3,4,5,6,7,8,9,10}; vector<int> b(10); // Initialization iterator for container read vector<int>::iterator i; // Reverse Output cout << "Sequence inversion output:"; Batch_op(a,b,10,InvT<int>); for(i = b.begin();i != b.end(); i++) cout << *i << " "; cout << endl; // Square Output cout << "Sequence Square Output:"; Batch_op(a,b,10,Sqrt<int>); for(i = b.begin();i != b.end(); i++) cout << *i << " "; cout << endl; // Cubic Output cout << "Sequence Cube Output:"; Batch_op(a,b,10,Cube<int>); for(i = b.begin();i != b.end(); i++) cout << *i << " "; }
Run result:
Sequence inversion output: -1-2-3-4-5-6-7-8-9-10
Sequence Square Output: 149 16 25 36 49 64 81 100
Sequence Cube Output: 1 8 27 64 125 216 343 512 729 1000
3. Custom function for pixel transformation
Define the operation template for the image:
// Define image operation templates template <class MyOperator> void batch_pix(Mat &src, int w, int h, MyOperator op) { // Pixel by Pixel Operation for(int row=0;row<h;row++){ for(int col=0;col<w;col++){ src.at<uchar>(row, col) = op(src.at<uchar>(row, col)); } } }
Define different pixel transformation operation templates:
// Logarithmic transformation template<class T> class logTransform { public: int C; double Gamma; logTransform(int c=1, double gamma = 1.0):C(c),Gamma(gamma){} // Overloading Operator int operator()(T val) { float Val = float(val)/255; return 255 * C * log(1+Val*(Gamma-1)) / log(Gamma); } }; // image binaryzation template<class T> class MyThreshold { public: int threshold; MyThreshold(int n=128):threshold(n){} // Overloading Operator int operator()(T val) { //Greater Threshold*255 return (val > threshold)*255; } };
Test code:
using namespace std; #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <set> using namespace cv; int main(){ // Read Image Mat img=imread("D:\\desktop\\1.png",0); // Read image width and height int w = img.cols; int h = img.rows; // Show original image imshow("original", img); // Display Binary Image batch_pix(img, w, h ,MyThreshold<uchar>(128)); imshow("erzhi", img); // Grayscale transformation operation //batch_pix(img, w, h ,logTransform<uchar>(1, 100)); //imshow("gamma=100", img); waitKey(0); return 0; }
Binarization results:
Logarithmic transformation results:
4. Implement a simple student management system through set collection
Common operations for set containers:
function | Effect |
---|---|
s.size( ) | Returns the number of elements in a container |
s.begin( ) | Returns the first element in the container |
s.end( ) | Returns the last element in the container |
s.clear( ) | Empty all elements in the container |
s.empty( ) | Determine if the container is empty |
s.insert( ) | Insert an element |
s.erase( ) | Delete an element |
The construction of student class:
// Include constructor and operator overloads class studentInfo { public: //Constructor for two parameters studentInfo(string strNo, string strName) { _strNo = strNo; _strName = strName; } string _strNo; string _strName; //Output character overload friend ostream& operator<<(ostream& os, const studentInfo& info) { os << info._strNo << ": " << info._strName; os << endl; return os; } //Compare School Number Sizes friend bool operator < (const studentInfo& info1, const studentInfo& info2) { return info1._strNo < info2._strNo; } };
Test function:
void TestSet() { vector<studentInfo> students; // Insert Student Object Information (dynamic 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 Container Establishment set<studentInfo> studentSet(students.begin(), students.end()); // Initialize Iterator set<studentInfo>::iterator i; //Traverse student information (automatic sorting) for(i = studentSet.begin();i != studentSet.end(); i++) cout << *i << " "; cout << "-----------" << endl; //Delete the assigned number studentSet.erase(studentInfo("10021", "Zhang san")); for(i = studentSet.begin();i != studentSet.end(); i++) cout << *i << " "; cout << "-----------" << endl; //Query the names of students with a given number const char* num = "10002"; for (i = studentSet.begin(); i != studentSet.end(); i++) { if (((*i)._strNo).compare(num) == 0) cout <<"The name of the student corresponding to the number is:"<< (*i)._strName << " "; } }
Run result:
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
-----------
The name of the student corresponding to the number is Haotian Yan
5. Character Statistics via map Association Container
Map is an associated container for STL that provides one-to-one services (somewhat like a dictionary in python). The first is called the keyword (only once), and the second is called the value of the keyword. A red and black tree is built inside the map, which has the function of sorting the data automatically.
void TestMap() { // Initialize map, visible one-to-one (keyword is char, value of keyword is int) map<char, int> word_count; const char* word = "JMU-HZH"; // Assigning values to keywords for (int i = 0; i < strlen(word); i++) { ++word_count[word[i]]; } // Iterator Initializing map map<char, int>::iterator iter; // Count Output for (iter = word_count.begin(); iter != word_count.end(); iter++) { cout << "[" << iter->first << "]Number of = " << iter->second << endl; } }
Run result:
Number of [-]= 1
Number of [H]= 2
Number of [J]= 1
Number of [M]= 1
Number of [U]= 1
Number of [Z]= 1
6. Summary
This blog implements some simple applications of STL and combines opencv and other related content. First, STL is a good tool for C++ code writing. It can improve the efficiency of coding and enrich the flexibility of code. At the same time, the application of STL fully combines the functions overload, function templates, virtual functions and so on, which indicates that a complete C++ project needs flexibility and rich knowledge linkage.