Std::set in C + + is a container implemented based on the data structure of a balanced binary tree of red and black trees, because the values of the elements contained therein are unique and are therefore used primarily for deduplication and sorting. The purpose of this article is to explore and share how to properly use Std::set to achieve de-emphasis and sequencing functions.
1. Method One: Use the less comparison function built into the Std::set (directly define the set object of the built-in type)
This method applies to: 1) compare built-in types such as int, char, and so on. 2) only a single built-in type can be reordered and sorted: If you want to go through the ID (int) and sort by hot (int), this method is useless. The code is as follows:
1#include <iostream>2#include <Set>3 using namespacestd;4 voidMain ()5 {6STD::Set<int> MySet;//directly define a built-in type set set7Myset.insert (Ten);// The default comparison function is less8Myset.insert ( -);// sort from small to large9 for(auto It:myset)Ten { Onestd::cout<<it<<Std::endl; A } -std::cout<<"End"<<Std::endl; - the}
The results are as follows:
Output: ten End
2. Method Two: Custom Class (struct) comparison function
As mentioned earlier: defining a set object of a built-in type directly, that is, using the default less comparison function built into Std::set, may not meet our actual needs. For example, there is now a batch of struct objects that need to be inserted into the set set and sorted according to the ID, followed by the hot heat. At this point, you need to re-customize the comparison function. There are two ways to customize a comparison function:
2.1 Overloading < Operators
Why do I need to overload the < operator? Can I overload the "<=" or ">=" operators? The answer is no. Almost all methods or containers need to be sorted to meet the mathematical standard of strict weak-ordering, otherwise the behavior of these methods or containers will be unpredictable. Suppose f (x, Y) is a comparison function. If the function satisfies the following conditions, it is strictly weakly ordered.
1.F (x,x) = false;
2. If f (x, y) then!f (y,x)
3.if f (x, Y) and F (y,z) then F (x,z)
4. If!f (x, y) &&!f (y,x) then x==y; If X==y and y==z then x==z;
It seems a bit dizzy, but don't worry, as long as your comparison method satisfies the equal element forever returning false (remember a criterion: always let the comparison function return false for the same element), then your method satisfies the requirement.
In fact, when the set container determines whether an existing element A and the new Insert element B are equal, this is done: 1) A as the left operand, b as the operand, call the comparison function, and return the comparison value 2) b as the left operand, a as an operand, then call the comparison function, and return the comparison value. If the return value of 1, 22 steps is false, then A and B are considered equal, then B is not inserted into the set container, and if the return value of 1, 22 steps is true, an unknown behavior may occur, so remember a guideline: always let the comparison function return false for the same element.
#include <iostream>#include<Set>using namespacestd;structsong{intm_id; intM_hot; Song (intIdintHot ) { This->m_id =ID; This->m_hot =Hot ; } BOOL operator< (Const structSong & Right)Const //Overloading < operators { if( This->m_id = = right.m_id)//de-weight by ID return false; Else { if( This->m_hot! =right.m_hot) { return This->m_hot > Right.m_hot;//Descending } Else { return This->m_id >right.m_id; } } }};voidMain () {std::Set<song>MySet; Song S1 (Ten, -); Song S2 ( -, $); Song S3 ( -, -); Song S4 ( -, $); Myset.insert (S1); //Insert S1Myset.insert (S2);//Insert S2Myset.insert (S3);//S3 and S2 have the same ID, do not insertMyset.insert (S4);//Insert S4 for(Auto it:myset) {std::cout<<"ID:"<<it.m_id<<", hot:"<<it.m_hot<<Std::endl; } std::cout<<"End"<<Std::endl;};
The results are as follows: ID: - $ ID: - $ ID: Ten 100
End
2.2 overloaded () operator
The specific code is as follows:
1#include <iostream>2#include <Set>3 using namespacestd;4 structSong5 {6 intm_id;7 intM_hot;8SongintIdintHot )9 {Ten One This->m_id =ID; A This->m_hot =Hot ; - } - /* the bool operator< (const struct Song & right) const//Overload < operator - { - if (this->m_id = = right.m_id)//de-weight by ID - return false; + Else - { + if (this->m_hot! = right.m_hot) A { at return this->m_hot > Right.m_hot; Descending - } - Else - { - return this->m_id > right.m_id; - } in } - } to */ + }; - structComp the { * BOOL operator()(structSong left,structSong right)//overloaded () operator $ {Panax Notoginseng - if(left.m_id = = right.m_id)//de-weight by ID the return false; + Else A { the if(Left.m_hot! =right.m_hot) + { - returnLeft.m_hot > Right.m_hot;//Descending $ } $ Else - { - returnleft.m_id >right.m_id; the } - Wuyi } the } - Wu }; - voidMain () About { $STD::Set<song,comp>MySet; //What is the difference between the notation and 2.1 -Song S1 (Ten, -); -Song S2 ( -, $); -Song S3 ( -, -); ASong S4 ( -, $); +Myset.insert (S1);//Insert S1 theMyset.insert (S2);//Insert S2 -Myset.insert (S3);//S3 and S2 have the same ID, do not insert $Myset.insert (S4);//Insert S4 the for(auto It:myset) the { thestd::cout<<"ID:"<<it.m_id<<", hot:"<<it.m_hot<<Std::endl; the } -std::cout<<"End"<<Std::endl; in};
The results are as follows: ID: $100 ID: $
End
Std::set custom de-weight and sort functions in C + +