A summary of the set container in STL 2

Source: Internet
Author: User

http://blog.csdn.net/sunshinewave/article/details/8068326

1. About Set

C + + STL has been widely praised, also used by many people, not only to provide such as vector, String, list and other convenient containers, more importantly, STL encapsulates a lot of complex data structure algorithms and a large number of commonly used data structure operations. Vector package Array, list encapsulates the linked list, map and set encapsulated two fork tree, in the encapsulation of these data structures, STL in accordance with the use of the programmer's habits, as a member function of the common operations, such as: Insert, sort, delete, find and so on. Let the user in the STL use process, do not feel unfamiliar.

For set, it must be stated that the set associative container. Set as a container is also used to store the data type of the same data type, and can be extracted from a data collection, the value of each element in the set is unique, and the system can be automatically sorted according to the value of the element. It should be noted that the value of the elements in the set can not be changed directly. The standard associative container set, multiset, map, Multimap inside C + + STL is a very efficient balanced retrieval binary tree: Red-black trees, also become RB trees (red-black tree). The statistical performance of RB Tree is better than that of general balanced binary tree, so the STL is chosen as the internal structure of the associative container.

There are a few questions about set:

(1) Why is the insertion and deletion efficiency of map and set higher than with other sequence containers?

Most people say it's simple because there's no need for memory copy and memory movement for associative containers. That's right, that's true. All elements within a set container are stored as nodes, with a node structure similar to that of a linked list, pointing to parent and child nodes. The structure chart might look like this:

A
/ \
B C
/ \ / \
D E F G

As a result, you just need to make a little transformation, and point the pointer to the new node. Delete the same time, a little change after the pointer to the node to point to the other node is OK. All that is done here is that the pointer is swapped out, and the memory movement is not related.

(2) Why does the previously saved iterator not expire after each insert?

Iterator here is the equivalent of a pointer to a node, the memory does not change, the pointer to the memory is how to invalidate it (of course, the deleted element itself has been invalidated). Each time the pointer is deleted and inserted, it is possible for the cursor to fail relative to the vector, and the call Push_back at the end of the insertion. Because in order to ensure the continuous storage of internal data, the iterator pointed to the block within the deletion and insertion process may have been overwritten by other memory or memory has been freed. Even when the push_back, the container internal space may not be enough, need a new larger memory, only the previous memory freed, request new larger memory, copy the existing data elements to the new memory, and finally put the elements need to be inserted into the last, then the previous memory pointer is naturally unusable. In particular, when working with algorithms such as find, keep this principle in mind: do not use outdated iterator.

(3) How does the set insert and search speed change when the number of data elements increases?

If you know log2 's relationship, you should have a thorough understanding of the answer. Finding in set is using binary lookup, that is, if there are 16 elements, you will need to compare up to 4 times to find the result, 32 elements, and a maximum of 5 times. So there are 10,000 of them? The maximum number of comparisons is log10000, up to 14, and 20,000 if it is a single element. Up to 15 times. See, when the amount of data increases by one time, the number of searches is only 1 more times, more than 1/14 of the search time. Once you understand this, you can safely put the elements inside.

Common methods in 2.set

Begin (), which returns the first element of a set container

End (), which returns the last element of the set container

Clear () to delete all the elements in the set container

Empty () to determine if the set container is null

Max_size (), returns the maximum number of elements that the set container may contain

Size () to return the number of elements in the current set container

Rbegin, the return value is the same as end ()

Rend (), the value returned is the same as Rbegin ()

Write a program to practice these simple operations:

1 #include <iostream> 2 #include <set> 3  4 using namespace std; 5  6 int main () 7 {8     Set<int> ; S 9     S.insert (1);     S.insert (2), one     S.insert (3),     and S.insert (1);     cout<< "Set has a size value of:" The value of the maxsize of <<s.size () <<endl;14     cout<< "set is:" <<s.max_size () <<endl;15 cout     << the first element in set is: The last element in the <<*s.begin () <<endl;16     cout<< set is: "<<*s.end () < <endl;17     s.clear ();     if (S.empty ())     {         cout<< "set is empty!!! The size value of the "<<endl;21     }22     cout<<" set is: "<<s.size () <<endl;23     cout<<" set The value of MaxSize is: "<<s.max_size () <<endl;24     return 0;25}

Operation Result:

Summary: insert 3 after inserting a 1, but we found that the last value in set is still 3 ha, this is set. Also note that the Begin () and end () functions do not check if set is empty, and it is best to use empty () before use to verify that the set is empty.

count () is used to find the number of occurrences of one of the key values in the set. This function is not very useful in set, because a key value can only occur 0 or 1 times in set, which makes it possible to determine if a key value has occurred in set.

Example code:View Code

#include <iostream> 2 #include <set> 3  4 using namespace std; 5  6 int main () 7 {8     set<int> S 9     S.insert (1),     S.insert (2),     one S.insert (3),     S.insert (1),     and cout<< "Set 1 occurrences are:" <<s.count (1) <<endl;14     cout<< "Set 4 occurrences are:" <<s.count (4) <<endl;15     return 0;16}

Operation Result:

Equal_range () , returns a pair of locators that represent the first element greater than or equal to the given key value and the first element greater than the given key value, which is a pair type and, if one of the pair locators fails, equals the value of end (). I haven't met the specific purpose of this.

Example code:

#include <iostream> 2 #include <set> 3  4 using namespace std; 5  6 int main () 7 {8     set<int> S 9     set<int>::iterator iter;10 for     (int i = 1; I <= 5; ++i) One by one     {         s.insert (i);     }14     for (iter = S.begin (); ITER! = S.end (); ++iter)     {         cout<<*iter<< "";     }18     cout<< endl;19     pair<set<int>::const_iterator,set<int>::const_iterator> pr;20     PR = S.equal_ Range (3);     cout<< "The first number greater than or equal to 3 is:" <<*pr.first<<endl;22     cout<< "The first number greater than 3 is:" < <*pr.second<<endl;23     return 0;24}

Operation Result:

Erase (iterator), remove the value that the locator iterator points to

Erase (First,second), remove the value between the locator first and second

Erase (Key_value), remove the value key_value the key value

Check out the program:

#include <iostream> 2 #include <set> 3  4 using namespace std; 5  6 int main () 7 {8     set<int> S 9     set<int>::const_iterator iter;10     set<int>::iterator first;11     set<int>::iterator Second;12 for     (int i = 1; I <=, ++i) (         S.insert (i),     }16     //First deletion of     s.erase ( S.begin ());     ///second deletion of first     = S.begin ();     second = S.begin ();     second++;22 second++     ;     s.erase (First,second);     8//The third deletion of the [     S.erase] (+     cout<< "in the set after the element is:";     iter = S.begin (); Iter! = S.end (); ++iter)     {         cout<<*iter<< "";     }31     cout<<endl;32     return 0;33}

Operation Result:

Summary:The delete operation in set is not to do any error checking, such as whether the locator is legitimate and so on, so use when you must pay attention to.

find () , returns the given value of the locator, and returns end () if it is not found.

Example code:

#include <iostream> 2 #include <set> 3  4 using namespace std; 5  6 int main () 7 {8     int a[] = {1, 2, 3}; 9     set<int> S (a,a+3),     set<int>::iterator iter;11     if (iter = S.find (2))! = S.end ())         cout<<*iter<<endl;14     }15     return 0;16}

Insert (key_value); Insert Key_value into set, the return value is Pair<set<int>::iterator,bool>,bool indicates whether the insertion was successful, and iterator represents the insertion position, if Key_ Value is already in set, then iterator represents the position of the key_value in set.

inset (first,second); Inserts the element between the locator first and second into the set, and the return value is void.

Example code:

#include <iostream> 2 #include <set> 3  4 using namespace std; 5  6 int main () 7 {8     int a[] = {1, 2, 3}; 9     set<int> s;10     set<int>::iterator iter;11     s.insert (a,a+3); (     iter = S.begin (); Iter! = S.end (); ++iter) (         cout<<*iter<< ""),     }16     cout<<endl;17     pair<set<int >::iterator,bool> pr;18     PR = s.insert (5); +     if (pr.second)     {         Cout<<*pr.first <<endl;22     }23     return 0;24}

Operation Result:

Lower_bound (key_value) , returns the first locator greater than or equal to Key_value

Upper_bound (key_value), returns the last locator greater than or equal to Key_value

Example code:

#include <iostream> 2 #include <set> 3  4 using namespace std; 5  6 int main () 7 {8     set<int> S 9     S.insert (1);     S.insert (3);     S.insert (4);     Cout<<*s.lower_bound (2) <<endl;13     Cout<<*s.lower_bound (3) <<endl;14     cout<<*s.upper_bound (3) <<endl;15     return 0 ; 16}
#include <iostream> 2 #include <set> 3  4 using namespace std; 5  6 int main () 7 {8     SET<INT&G T S 9     S.insert (1);     S.insert (3);     S.insert (4);     Cout<<*s.lower_bound (2) <<endl;     Cout<<*s.lower_bound (3) <<endl;14     cout<<*s.upper_bound (3) <<endl;15     Return 0;16}

Operation Result:

Http://www.cnblogs.com/wonderKK/archive/2012/04/10/2441379.html

Set is a standard associative container in STL (Vector,list,string,deque is a sequence container, and Set,multiset,map,multimap is a standard associative container), which is implemented using a balanced search tree-red and black trees. Insert delete operation only need pointer operation node to complete, do not involve memory move and copy, so efficiency is high. Set, as the name implies, is the meaning of "set", the elements are unique in set, and by default the elements are automatically sorted in ascending order, supporting the intersection (set_intersection) of the set, the difference (set_difference) and (set_union), the symmetric difference ( Set_symmetric_difference) and so on some set of operations, if you need the elements in the collection to allow repetition then you can use Multiset
#include <set>
#include <iterator>
#include <iostream>
using namespace Std;
int main ()
{
set<int>eg1;
Insert
Eg1.insert (1);
Eg1.insert (100);
Eg1.insert (5);
Eg1.insert (1);//element 1 is not inserted again in set because it already exists 1
Eg1.insert (10);
Eg1.insert (9);
Traversing set, you can see that the elements are ordered
Set<int>::iterator Set_iter=eg1.begin ();
cout<< "Set named EG1:" <<endl;
for (; Set_iter!=eg1.end (); set_iter++) cout<<*set_iter<< "";
cout<<endl;
Use the size () function to get the current number of elements
cout<< "Now there is" <<eg1.size () << "elements in the set EG1" <<endl;
The IF (Eg1.find () ==eg1.end ())//find () function can find out if an element exists
cout<< "T in the set EG1" <<endl;

set<int>eg2;
for (int i=6;i<15;i++)
Eg2.insert (i);
cout<< "Set named EG2:" <<endl;
For (Set_iter=eg2.begin (); Set_iter!=eg2.end (); set_iter++)
cout<<*set_iter<< "";
cout<<endl;
Get two set and
set<int>eg3;
cout<< "Union:";
Set_union (Eg1.begin (), Eg1.end (), Eg2.begin (), Eg2.end (),insert_iterator<set<int> > (Eg3,eg3.begin ())) ;//Note the form of a fifth parameter
Copy (Eg3.begin (), Eg3.end (),ostream_iterator<int> (cout, ""));
cout<<endl;
Get two sets of the intersection, note the set to receive the result before collection operation to call the clear () function to clear the
Eg3.clear ();
Set_intersection (Eg1.begin (), Eg1.end (), Eg2.begin (), Eg2.end (),insert_iterator<set<int> > (EG3, Eg3.begin ()));
cout<< "intersection:";
Copy (Eg3.begin (), Eg3.end (),ostream_iterator<int> (cout, ""));
cout<<endl;
Gets the difference of two set
Eg3.clear ();
Set_difference (Eg1.begin (), Eg1.end (), Eg2.begin (), Eg2.end (),insert_iterator<set<int> > (eg3,eg3.begin ()));
cout<< "Difference:";
Copy (Eg3.begin (), Eg3.end (),ostream_iterator<int> (cout, ""));
cout<<endl;
The symmetry difference of two sets is obtained, that is, if the two set is a and B, then the symmetry difference is aub-a∩b
Eg3.clear ();
Set_symmetric_difference (Eg1.begin (), Eg1.end (), Eg2.begin (), Eg2.end (),insert_iterator<set<int> > (eg3 , Eg3.begin ()));
Copy (Eg3.begin (), Eg3.end (),ostream_iterator<int> (cout, ""));
cout<<endl;

return 0;
}

Set will sort the elements, so the question is what sort of rules are there? The above example code we found that the elements of the int type can automatically determine the size order, but the char* will not be automatically judged by strcmp, let alone the user-defined type, in fact set the standard form is Set<key, Compare, alloc> ,

Parameters Description Default Value
Key types of keywords and values for a collection
Compare The keyword comparison function, which is the parameter type of the key parameter, returns true if the first argument is less than the second argument, otherwise false Less<key>
Alloc Set allocator for internal memory management Alloc

Here is a sample code with a keyword type of char*

#include <iostream>
#include <iterator>
#include <set>
using namespace Std;
struct LTSTR
{
BOOL Operator () (const char* S1, const char* s2) const
{
Return strcmp (S1, S2) < 0;
}
};

int main ()
{
const int N = 6;
Const char* A[n] = {"Isomer", "ephemeral", "prosaic",
"Nugatory", "artichoke", "serif"};
Const char* B[n] = {"Flat", "this", "artichoke",
"Frigate", "prosaic", "isomer"};

Set<const char*,ltstr> A (a, A + N);
Set<const char*,ltstr> B (b, B + N);
Set<const char*,ltstr> C;

cout << "Set A:";
Copy (A.begin (), A.end (), Ostream_iterator<const char*> (cout, ""));
Set<const Char*,ltstr>::iterator ITR;
For (Itr=a.begin (); Itr!=a.end (); itr++) cout<<*itr<< "";
cout << Endl;
cout << "Set B:";
Copy (B.begin (), B.end (), Ostream_iterator<const char*> (cout, ""));
cout << Endl;

cout << "Union:";
Set_union (A.begin (), A.end (), B.begin (), B.end (),
Ostream_iterator<const char*> (cout, ""),
Ltstr ());
cout << Endl;

cout << "intersection:";
Set_intersection (A.begin (), A.end (), B.begin (), B.end (), Ostream_iterator<const char*> (cout, ""), Ltstr ());
cout<<endl;
Set_difference (A.begin (), A.end (), B.begin (), B.end (), Inserter (C, C.begin ()), Ltstr ());
cout << "Set C (difference of A and B):";
Copy (C.begin (), C.end (), Ostream_iterator<const char*> (cout, ""));
cout <<endl;
return 0;
}

Ltstr can also be defined as such
Class Ltstr
{
Public
BOOL Operator () (const char* s1,const char*s2) const
{
Return strcmp (S1,S2) <0;
}
};

More general application way that is, the data type is also a user-defined class to replace, the comparison of function customization, and even can be added two-level comparison, such as first sorted by total number of points, for the same score by ID, the following is the sample code

#include <set>
#include <iostream>
using namespace Std;
struct
{
int id;
int score;
String name;
};
struct Compare
{
BOOL Operator () (const entity& E1,CONST entity& E2) Const {
if (E1.score<e2.score) return true;
Else
if (E1.score==e2.score)
if (e1.id<e2.id) return true;

return false;
}
};

int main ()
{
set<entity,compare>s_test;
Entity A,b,c;
A.id=123;a.score=90;a.name= "Bill";
B.id=121;b.score=85;b.name= "Mary";
C.id=130;c.score=85;c.name= "Jerry";
S_test.insert (a); S_test.insert (b); S_test.insert (c);
Set<entity,compare>::iterator ITR;
cout<< "Score List (ordered by score): \ n";
For (Itr=s_test.begin (); Itr!=s_test.end (); itr++)
cout<<itr->id<< "---" <<itr->name<< "---" <<itr->score<<endl;
return 0;
}

A summary of the set container in STL 2

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.