Experimental Background
The full name of STL is Standard Template Library. STL involves many aspects, including but not limited to containers, iterators, algorithms, and function objects. This blog only introduces the most intuitive content of STL, involving principles and deeper concepts. You need to look for your own materials to learn.
Summary:
1. The Standard Template Library (STL) defines a set of concepts that provide a logical basis for generic programming.
2. The parameters of each class template and function template in STL are defined by the concept in this system.
3. When using STL templates, type parameters can be either existing types in the C++ standard library or custom types as long as they are models of the required concepts.
1. Containers
Containers are objects that contain a set of elements. The container class library contains 13 Basic containers. These containers can be divided into two basic types: sequential containers and associative containers. Sequential containers organize a set of elements of the same type in a strictly linear form. Associated containers have the ability to quickly extract elements based on a set of indexes. Depending on how the elements are organized, associative containers can be divided into ordered and out-of-order, where the key s in ordered containers are stored sequentially, and out-of-order containers use hash functions to organize the elements.
2. Iterators
Iterators provide sequential access to each element in a container. For iterators, you can use the'++'operator to get an iterator that points to the next element, and you can use the'*' operator to access the element that an iterator points to. If the element type is a class or structure, you can also use the'->'operator to directly access a member of the element, and some iterators support the'-' operator to get an iterator for the previous element. Pointers have the same characteristics, so the pointer itself is an iterator, which is a generalized pointer.
3. Sequence Transformations (Reverse, Square, Cubic)
h function:
//Reverse template <typename T> T InvT(T a) { return -a; } //square template <typename T> T SqrT(T a) { return a*a; } //cube template <typename T> T CubicT(T a) { return a*a*a; } //Array Reverse template <typename T> void transInvT(T a[],T b[],int num) { for(int i=0;i<num;i++) { b[i]=InvT(a[i]); } } //Array Square template <typename T> void transSqrT(T a[],T b[],int num) { for(int i=0;i<num;i++) { b[i]=SqrT(a[i]); } } //Array Cube template <typename T> void transCubicT(T a[],T b[],int num) { for(int i=0;i<num;i++) { b[i]=CubicT(a[i]); } } //Output function, traversing the output with a pointer template <typename T> void outputCont(string strName,ostream &os,T begin,T end) { os<<strName<<":"; for(;begin!=end;begin++) { os<<*begin<<"\t"; } os<<endl; }
main function:
int main() { const int N=5; int a[N]={1,2,3,4,5}; int b[N]; outputCont("a",cout,a,a+N); transInvT(a,b,N); outputCont("InV a",cout,b,b+N); transSqrT(a,b,N); outputCont("Sqr a",cout,b,b+N); transCubicT(a,b,N); outputCont("cubic a",cout,b,b+N); return 0; }
We still need to use different functions to do the corresponding operation, can we continue to simplify? The answer is yes.
//Universal Function Template template <typename inputIter,typename outputIter,typename Myoperator> void transvoid(inputIter begInput,inputIter endInput,outputIter begOutput,Myoperator op) { for(;begInput!=endInput;begInput++,begOutput++) { *begOutput = op(*begInput); } }
First, let's analyze the inputs and outputs. There are three declarations in the template representing three different types. The first two are the starting and ending addresses of the objects we want to execute, the third is the starting address of the output objects, and the last is the name of the functions we want to execute.
vector <float>va(N); vector <double>vb(N); vector <char>vc(N); transvoid(a,a+N,va.begin(),InvT<int>); transvoid(a,a+N,vb.begin(),SqrT<int>); transvoid(a,a+N,vc.begin(),CubicT<int>); outputCont("va",cout,va.begin(),va.end()); outputCont("vb",cout,vb.begin(),vb.end()); outputCont("vc",cout,vc.begin(),vc.end());
As shown in the figure, both float and double containers perform perfectly, except that vc is missing the corresponding character due to character containers.
Note:
1. The starting address of the container is the container name.begin(), and the ending address is the container name.end().
2. In the generic function template transvoid, the input function name Myoperator op needs to specify the container type, which is the same as the execution object type. (Obviously, for which type of operation you have to declare which type of function I want to use)
For example, reverse operations on container vb:
transvoid(vb.begin(),vb.end(),va.begin(),InvT<double>); outputCont("Invt vb",cout,va.begin(),va.end());
4. Pixel transformation (binarization, gray stretch)
Pixel transformation involves the reading and storage of images in C++ language. This is only a conceptual introduction. The specific C++ pixel transformation needs to be viewed and studied in another blog or book.
//image binaryzation template <typename T> class Mythreshold { public: //Default is 128 when n has no input parameters Mythreshold(int n=128):_nThreshold(n){} int operator()(T val) { //_ nThreshold is n return val<_nThreshold?0:1; } int _nThreshold; }; //Gray stretch template <typename T> class Mytrans { public: //Default 128 Mytrans(int n=128):c(n){} int operator()(T val) { return val+=c; } int c; };
transvoid(a,a+N,vb.begin(),Mythreshold<int>(2)); outputCont("Inv a by treshold",cout,vb.begin(),vb.end()); transvoid(a,a+N,vb.begin(),Mytrans<int>()); outputCont("Inv a by trans",cout,vb.begin(),vb.end());
Binarization is when we give a parameter, and if the value in the array is less than this parameter, it becomes 0, otherwise it becomes 1. In the experiment, we set the value to 2, because only 1 is smaller than 2, so there is only one 0, and all that remains is 1.
Grayscale stretching is when we give a parameter that is added to all the values in the array. If we don't give the parameter, the default value is the 128 we set.
5. Storage management of student information
Here we use a container called a set, which, as the name implies, describes objects very similar to what is mathematically called a set. A set in a STL is made up of non-repeating elements with a limited number, but the elements of the set themselves are ordered, so it is efficient to find the specified elements, or it is easy to get the interval of the elements of a specified size range within the container. That's why we store student information.
5.1. Student Information Storage
//Define structure to store student information class studentInfo { public: studentInfo(string strNo, string strName) { _strNo = strNo; _strName = strName; } string _strNo; string _strName; //Overload the output to output the structure friend ostream& operator<<(ostream& os, const studentInfo& info) { os << info._strNo << " " << info._strName; return os; } //Implement structure comparison friend bool operator<(const studentInfo& info1, const studentInfo& info2) { return info1._strNo < info2._strNo; } };
void TestSet() { vector<studentInfo> students; students.push_back(studentInfo("10021", "Zhang san")); students.push_back(studentInfo("10002", "Li si")); students.push_back(studentInfo("10003", "Wang wu")); students.push_back(studentInfo("10011", "Wang Liu")); students.push_back(studentInfo("10010", "Wu Liu")); set<studentInfo> studentSet(students.begin(), students.end()); outputCont("student set",cout, studentSet.begin(), studentSet.end()); }
5.2. Additions, deletions and alterations
5.2.1.Increase
studentSet.insert(studentInfo("10001","jack"));
Use the function insert that comes with the set type.
5.2.2. Delete
studentSet.erase(studentInfo("10001","jack"));
Use the erase function that comes with the set type
5.2.3. Change
The parameter in the change that comes with the set type is const, so we build a new modify function ourselves
template <typename T> //Change by number void updatedata(string strNo,string afterNo,string afterName,ostream &os,T begin,T end) { vector<studentInfo> students; students.push_back(studentInfo("10021","zhang san")); students.push_back(studentInfo("10002","Li si")); students.push_back(studentInfo("10003","wang wu")); students.push_back(studentInfo("10011","wang liu")); students.push_back(studentInfo("10010","wu liu")); set<studentInfo> studentSet(students.begin(),students.end()); //Delete the number information to be modified for(;begin!=end;begin++) { if((*begin)._strNo==strNo) { studentSet.erase(*begin); break; } } //Add the modified number information studentSet.insert(studentInfo(afterNo,afterName)); outputCont("student set",cout,studentSet.begin(),studentSet.end()); }
5.2.4. Check
//Find by number template <typename T> void strNoSearch(string strNo,ostream &os,T begin,T end) { for(;begin!=end;begin++) { if((*begin)._strNo==strNo) { os<<"find the student:"<<*begin<<endl; } } } //Find by name template <typename T> void strNameSearch(string strName,ostream &os,T begin,T end) { for(;begin!=end;begin++) { if((*begin)._strName==strName) { os<<"find the student:"<<*begin<<endl; } } } //set's own find function if(studentSet.find(studentInfo("10001","jack"))!=studentSet.end()) { cout<<"find the student."<<endl; }
5.2.5. Testing
void TestSet() { vector<studentInfo> students; students.push_back(studentInfo("10021","zhang san")); students.push_back(studentInfo("10002","Li si")); students.push_back(studentInfo("10003","wang wu")); students.push_back(studentInfo("10011","wang liu")); students.push_back(studentInfo("10010","wu liu")); set<studentInfo> studentSet(students.begin(),students.end()); //Add Student Information studentSet.insert(studentInfo("10001","jack")); outputCont("student set",cout,studentSet.begin(),studentSet.end()); //Find Student Information if(studentSet.find(studentInfo("10001","jack"))!=studentSet.end()) { cout<<"find the student."<<endl; } //School Number Search strNoSearch("10001",cout,studentSet.begin(),studentSet.end()); //Name Lookup strNameSearch("jack",cout,studentSet.begin(),studentSet.end()); //Delete Student Information studentSet.erase(studentInfo("10001","jack")); outputCont("student set",cout,studentSet.begin(),studentSet.end()); //Change Student Information updatedata("10011","10011","aaa",cout,studentSet.begin(),studentSet.end()); }
6.map Dictionary Use
Maps are made up of keys and additional data, so they are much like a dictionary, such as the student's course results, a course corresponding to a grade, and a search for a given course will find the corresponding grade for that course.
void TestMap() { //Mapping used to store the number of occurrences of letters map<char,int> s; //Store input characters char c; do { //Enter the next character cin>>c; //Determine if it is a letter if (isalpha(c)) { //Convert letters to lowercase c = tolower(c); //Add 1 to the frequency of the letter s[c]++; } //Encountering "." ends input } while (c != '.'); //Output number of occurrences per letter for (map<char,int>::iterator iter = s.begin(); iter != s.end(); ++iter) { cout <<iter->first<<" "<<iter->second<< " "; } cout<<endl; }
7. Summary
STL is a standard template library of C++. There are many things worth studying and learning. This blog only introduces the most basic and simple content. Interested students can continue to look for relevant materials to learn.