C++ experiment_ 4:STL Application

Keywords: C++ Visual Studio Code

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.

Posted by jacomus on Sat, 27 Nov 2021 10:45:53 -0800