c + + < set > set() usage

Posted by pabs1983 on Thu, 11 Nov 2021 09:34:13 +0100

  There are several questions about set:

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

Most people say that it is very simple, because there is no need to copy and move memory for associated containers. Yes, indeed. All elements in the set container are stored in the form of nodes. Its node structure is similar to that of a linked list, pointing to parent and child nodes. The structure diagram may be as follows:

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

The iterator here is equivalent to a pointer to the node. If the memory has not changed, how can the pointer to the memory become invalid (of course, the deleted element itself has become invalid). Compared with vector, the pointer may become invalid every time it is deleted or inserted. Call push_ The same is true when back is inserted at the tail. In order to ensure the continuous storage of internal data, the block pointed to by the iterator may have been overwritten by other memory during deletion and insertion, or the memory has been released. Even when pushing_ Back, the internal space of the container may not be enough, and a new and larger memory is needed. Only release the previous memory, apply for a new and larger memory, copy the existing data elements to the new memory, and finally put the elements to be inserted to the last, then the previous memory pointer will not be available. Especially when working with find and other algorithms, keep this principle in mind: do not use expired iterators.

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

If you know the relationship between log2, you should know the answer thoroughly. The binary search is used in the set search, that is, if there are 16 elements, the result can be found by comparing at most 4 times, and there are 32 elements, the result can be compared at most 5 times. What about 10000? The maximum number of comparisons is log10000, and the maximum number is 14. What if it is 20000 elements? No more than 15 times. You see, when the amount of data doubles, the number of searches is only one more time, 1 / 14 more search time. After you understand this truth, you can put elements into it at ease.

2. Common methods in set

begin()      , returns the first element of the set container

end() returns the last element of the set container

clear()            , Delete all elements in the set container

empty(), judge whether the set container is empty

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

size(), returns the number of elements in the current set container

rbegin, the returned value is the same as end()

The value returned by rend() is the same as rbegin()

 #include <iostream>
 #include <set>
  
 using namespace std;
 
 int main()
 {
     set<int> s;
     s.insert(1);
     s.insert(2);
     s.insert(3);
     s.insert(1);
     cout<<"set of size The value is:"<<s.size()<<endl;
     cout<<"set of maxsize The value of is:"<<s.max_size()<<endl;
     cout<<"set The first element in is:"<<*s.begin()<<endl;
     cout<<"set The last element in is:"<<*s.end()<<endl;
     s.clear();
     if(s.empty())
     {
         cout<<"set Empty!!!"<<endl;
     }
     cout<<"set of size The value is:"<<s.size()<<endl;
     cout<<"set of maxsize The value of is:"<<s.max_size()<<endl;
     return 0;
}

Output interpretation

Summary: after inserting 3, although a 1 is inserted, we find that the last value in set is still 3. Ha, this is set. Also note that the begin() and end() functions do not check whether the set is empty. You'd better use empty() to check whether the set is empty before use

 #include <iostream>
 #include <set>
 
 using namespace std;
 
 int main()
 {
     set<int> s;
     s.insert(1);
     s.insert(2);
     s.insert(3);
     s.insert(1);
     cout<<"set The number of occurrences in 1 is:"<<s.count(1)<<endl;
     cout<<"set The number of occurrences in 4 is:"<<s.count(4)<<endl;
     return 0;
 }

count()   Used to find the number of occurrences of a key value in set. This function is not very practical in set, because a key value can only appear 0 or 1 times in set, which becomes to judge whether a key value has appeared in set.

#include <iostream>
#include <set>

using namespace std;

int main()
{
    set<int> s;
    set<int>::const_iterator iter;
    set<int>::iterator first;
    set<int>::iterator second;
    for(int i = 1 ; i <= 10 ; ++i)
    {
        s.insert(i);
    }
    //First deletion
    s.erase(s.begin());
    //Second deletion
    first = s.begin();
    second = s.begin();
    second++;
    second++;
    s.erase(first,second);
    //Third deletion
    s.erase(8);
    cout<<"After deletion set The elements in are:";
    for(iter = s.begin() ; iter != s.end() ; ++iter)
    {
        cout<<*iter<<" ";
    }
    cout<<endl;
    return 0;
}

erase(iterator)   , Deletes the value pointed to by the locator iterator

erase(first,second) to delete the value between first and second of the locator

erase(key_value) to delete the key value_ Value of value

#include <iostream>
#include <set>

using namespace std;

int main()
{
    int a[] = {1,2,3};
    set<int> s(a,a+3);
    set<int>::iterator iter;
    if((iter = s.find(2)) != s.end())
    {
        cout<<*iter<<endl;
    }
    return 0;
}

find()   , Returns the locator of the given value. If it is not found, end() is returned.

#include <iostream>
#include <set>

using namespace std;

int main()
{
    int a[] = {1,2,3};
    set<int> s;
    set<int>::iterator iter;
    s.insert(a,a+3);
    for(iter = s.begin() ; iter != s.end() ; ++iter)
    {
        cout<<*iter<<" ";
    }
    cout<<endl;
    pair<set<int>::iterator,bool> pr;
    pr = s.insert(5);
    if(pr.second)
    {
        cout<<*pr.first<<endl;
    }
    return 0;
}

insert(key_value);   Will key_ Insert value into set  , The return value is pair < set < int >:: iterator, bool >, bool indicates whether the insertion is successful, and iterator represents the insertion position, if key_ Value is already in set, then the key represented by iterator_ The position of value in set.

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

#include <iostream>
#include <set>

using namespace std;

int main()
{
    set<int> s;
    s.insert(1);
    s.insert(3);
    s.insert(4);
    cout<<*s.lower_bound(2)<<endl;
    cout<<*s.lower_bound(3)<<endl;
    cout<<*s.upper_bound(3)<<endl;
    return 0;
}

lower_bound(key_value)  , Returns the first key greater than or equal to_ Value locator

upper_bound(key_value), return the last key greater than or equal to_ Value locator

3, Custom comparison function
     (1) Element is not a structure:
         Example: / / customize the comparison function myComp and overload the "()" operator

 struct myComp
 {
    bool operator()(const your_type &a,const your_type &b)
     {
      return a.data-b.data>0;
     }
 }
    set<int,myComp>s;
    set<int,myComp>::iterator it;

  (2) If the element is a structure, you can write the comparison function directly in the structure.
         Example:

struct Info
{
    string name;
    float score;
    //Overload the "<" operator to customize the collation
    bool operator < (const Info &a) const
    {
       //Sort by score from large to small
       return a.score<score;
     }
}
     set<Info> s;
     set<Info>::iterator it;

Topics: C++ linked list