C + + Base container

Source: Internet
Author: User

Introduction to sequential containers :

Sequential Container type Description
Vector Variable-size arrays that support fast access and may be slow to insert or delete outside the trailer
Deque Double-ended queues. Fast access is supported, and insertion and deletion in the kinsoku will be quick.
List Two-way list. Only bidirectional sequential access is supported. Insert Delete Soon
Forward_list One-way list. Only one-way sequential access is supported, and insertion or deletion is quick at any location
Array Fixed size array, support fast random access, cannot add delete element
String Similar to vectors, designed to hold characters. Random access fast, add delete at tail fast

Where array and forward_list are the added types of the new C + + standard. Array is a more secure and easy-to-use arrays type than built-in arrays. While the Forward_list design goal is the avenue with the best handwritten unidirectional list equivalent performance, so it does not have a size operation, while for other containers, size is a fast constant time operation.

Basic principles of container selection :

    • The vector should be used unless there are good reasons;
    • If the program has a lot of small elements, and the extra overhead of space is important, do not use list and forward_list;
    • If a random access element is required, a vector or deque is used;
    • If you need to insert a delete in the middle of the container, you should use list or forward_list;
    • If you need to insert the deletion in the container, do not need to insert the deletion in the middle, then use deque;
    • If you only need to insert elements in the middle of the container when you are reading the data, and then randomly access the elements, first determine if you really need to insert in the middle, can be inserted in the tail and then reflow to achieve, if still must be inserted in the middle, then the list to accept the data in the copy to the vector;

Note: Older compilers need to add a space between the two angle brackets of vector<vector<string> >.

Common operations for all containers:

summary of related types :

size_type unsigned integer, sufficient to store the maximum possible container length for this container type

iterator type of iterator for this container type

Read-only iterator type for the const_iterator element

reverse_iterator iterator addressing elements in reverse order (Forward_lsit not supported)

const_reverse_iterator Read-only (cannot write) reverse iterator (Forward_lsit not supported)

Difference_type is sufficient to store a signed integer of two iterator differences, which can be a negative number

value_type Element type

The lvalue type of the reference element, which is synonymous with value_type&

The constant lvalue type of the const_reference element, equivalent to the const value_type&

summary of constructor functions

C<T> c Create an c empty container named C container type name, such as, is the vector T element type, for example int , string . Suitable for all containers
C c(c2) Create a copy of the container c2 c c2 c , and must have the same container type and hold elements of the same type. Suitable for all containers

C c{a,b,c...}

C c={a,b,c ...}

C initializes the copy of the element in the initialization list. The element type in the list must be compatible with the element type of C, and for the array type, the number of elements in the list must be equal to

or less than the size of the array, any missing elements are initialized with values.

C c(n) Creates a n container that has an initialization element c . Only for sequential containers
C c(n, t) Create a container with an n t element of one c , where the value must be a value of the element type of the t container type C , or a value that can be converted to that type. Only for sequential containers
C c(b, e) Creates a container c where an element is a copy of an iterator b and an e element within the indicated range. Suitable for all containers

There are two ways to create a container as a copy of another container:

    • Copy the entire container directly, and the type and element type of the two containers must match;
    • Copies the range of elements specified by the iterator, does not require the same container type, and the element type can be different as long as it can be converted to each other.

If the element is a built-in type or a class type with a default constructor, how can you provide only the container size, and you must display the specified initial value if the element does not have a default constructor.

When an array initializes a class type, the class type is required by the default constructor, and the array type can be copied or assigned, but requires the same initial value type and container type, with the same element type and size.

Assignment operation

C1 = C2; C2 is assigned to C1, and if the two containers are of different sizes, they are the same size as the right container if they are assigned. Array allows assignment, but objects on both sides of the left and right must have the same type.

C1 = {A,b,c}; The elements in the C1 are replaced with the elements in the list, and the array does not support assign and the value list for assignment (because both sides may be different sizes).

Assignment-related operations cause internal iterators, references, and pointers to be invalidated on the left-hand side of the container, except for array and string, which does not invalidate the container's iterators, references, and pointers.

Sequential containers can use assign to assign values from a different but compatible type, or to assign a value from a sub-sequence of a container.

Seq.assign (b,e);//seq replaced by elements from B to E

Seq.assign (LI);//seq replace with elements in the initialization list

Seq.assign (n,t);//seq replaced by n elements with a value of t

swap function :

A.swap (b); A and B Exchange

Swap (A, b); A and B Exchange

In addition to array, swap Exchange two container content operation is very fast, because he did not exchange the elements themselves, but instead exchanged the data structure inside the container. Therefore, it is guaranteed to be completed in constant time.

Therefore, iterators, references, and pointers that point to the container outside of string will not expire after the swap, except that the container they belong to has changed.

Attention. Earlier versions had only a member function version of Swap, with the new version of two, but the swap for non-member functions was important for generic programming, and it was a good practice to unify the non-member version of swap.

Other functions

c.size () returns the number of elements in container C . The return type is c::size_type; (forward_list not supported)

c.max_size () returns the maximum number of elements that container C can hold, with a return type of C::size_type

c.empty () Returns a Boolean value that marks whether the container size is 0

C.erase (args) removes the element specified by args

c.clear () deletes all the elements in container C . return void

C.insert (args) copies the elements in args to C

c.begin () returns an iterator that points to the first element of container C

c.end () returns an iterator that points to the next position of the last element of container C

c.rbegin () returns an inverse iterator that points to the last element of container C

c.rend () returns an inverse iterator that points to the position in front of the first element of container C

c.crbegin () returns a const reverse iterator that points to the last element of container C

c.crend () returns a const reverse iterator that points to the position in front of the first element of container C

Functions that begin with C are introduced by the new C + + standard to support auto with begin and end. When auto is used in conjunction with begin and end, the obtained iterator type is dependent on the container type, and C begins with Const_iterator.

! = and = = are supported for each container, and relational operators (>, >=, <, <=) are supported in all containers except unordered containers. So when comparing containers, use! = and = = as much as possible.

Add elements (array does not support these operations):

Push_back (t);//applies to all sequential containers

Push_front (t);//For list and deque only

Insert (p,t);//Inserts an element in front of the iterator p and returns an iterator to the newly added element

Insert (P,N,T)//inserts n T elements in front of the iterator p, returns void

Insert (P,B,E)//Inserts an element between iterators B and E in front of the iterator P

You can also insert an initialization list insert (P,li), and insert an LI initialization list in front of the iterator p.

Methods for adding new standards

Emplace ();//corresponds to insert () function

Emplace_back (t);//function corresponding to push_back ()

Emplace_front (t);//function corresponding to Push_front ()

Emplace is not a copy element, but a constructor that invokes parameters passed to the element type constructs the element directly in the container's memory.

Forward_list has its own proprietary version of INSERT and Emplace;forward_list does not support push_back and emplace_back;

Functions that access elements in the container back (), front (), at (), and subscript operations return all references.

If you want the subscript to be legal, you can use at (), which checks the bounds. Out-of-bounds throws a Out_of_range exception.

Delete element (array does not support these operations):

C.pop_back ();//forward_list does not support this method and returns void

C.pop_front ()///only for vector and deque containers, return void

C.erase (P);//delete the element referred to by P and return to the next position

C.erase (b,e);//delete the element between the iterator B and E, and return to the next position

C.clear ();//delete all elements, return void

Make sure that the element exists before deleting it.

Special Forward_list Operation

Forward_list is a one-way list, so adding or removing elements above it is done by changing the elements after the given element.

c.push_front () insert element at beginning
c.pop_front () Delete the opening element
c.insert_after (POS, elem) Inserts an element after the POS, returning the position of the new element
c.insert_after (POS, N, elem) inserts n elements after POS elem, returning the position of the first new element
c.insert_after (POS, Begin, end) Inserts an element after POS [begin, end], returning the position of the first new element
c.insert_after (POS, initiallist) inserts a initiallist after POS, returning the position of the first new element
c.emplace_after (pos, args ...) insert args after Pos ... element that returns the position of the first new element
c.emplace_front (args ...) insert element at the beginning of args ..., no return value
c.erase_after (POS) Delete the element after POS
c.erase_after (begin, end) remove elements between (begin, end)

Before_begin returns a first-forward (off-the-beginning) iterator. This iterator allows us to add or remove elements after the linked list is affected by elements that do not exist before the element.

Size operation

C.size ();//Returns the number of elements within a container

C.max_size (0;//returns the maximum number of elements the container can hold

C.empty ();

C.resize (n);//Adjust the length of the container so that it can hold n elements, if n<c.size (), delete too many, else add new elements with value initialization; class types need to provide a default constructor

C.resize (n,t);//Adjust the length of the container so that it can hold n elements, and the newly added element is initialized to T

Summary 1: Container operations may be iterator invalidation:

When you add elements to a container,

If the container is a vector and a string, and the storage space is reassigned, the iterator to the container is pointed to. Pointers and references are invalidated, and if the storage space is reassigned, the iterator, pointer, and reference to the element that precedes the insertion position are valid and then invalidated;

In the case of deque, a position other than the insertion end invalidates the iterator, pointer, and reference, which invalidates the iterator at the end of the insertion;

If it is list and forward_list, it will work.

When you remove an element from a container,

For lists and forward_list, iterators, pointers, and references that point to other places are valid;

In the case of deque, the removal of the end point invalidates the iterator, pointer, and reference, and the iterator, pointer, and reference elsewhere are valid, but when deleted as an element, the trailing iterator is invalidated;

If the container is a vector and a string, the iterator, pointer, and reference to the element that precedes the deleted element are still valid, and the trailing iterator is invalidated;

Therefore, do not save the tail iterator, adding and deleting elements often invalidates the trailing iterator;

The following are examples of iterator invalidation and workarounds:

1 #include <iostream> 2 #include <map> 3 using namespace std; 4  5 typedef map<int, int> Map, 6 typedef map<int, Int>::iterator MapIt; 7  8 void print (map &m) 9 { Ten     MapIt it;11 for     (it = M.begin (); it = M.end (); it++)     {cout         << it->second << ""; 14< c6/>}15     cout << endl;17}18 void Deletevaluefrommap (Map &m, int n = 5) {MapIt it;22 for     (i t = M.begin (); It! = M.end (); it++) (         0 = = it->second% n)             , {m.erase (it),         }28     }29}30 int main () 32 {     Map m;34     int i = 0;35 for     (i = 0; i <; i++)         [m[i] = i;38     }39 +     print (m); 4 1     deletevaluefrommap (m);//program crashes with a     return of 0;45}

       Run the above program, the results of the program crashes, what is the reason? Originally, for the associated container map,  m.erase (IT), it will not work, and for the loop of it++, naturally there will be a problem ah. What about that? and see:

  1 #include <iostream> 2 #include <map> 3 using namespace std;  4 5 typedef map<int, int> map;  6 typedef map<int, Int>::iterator MapIt; 7 8 void print (Map &m) 9 {ten MapIt it; one for (it = M.begin (); it = M.end (); it++) {Cou T << it->second << ""; cout << Endl; Deletevaluefrommap (Map &m, int n = 5) {MapIt it; MapIt tmp, and the IT = M.begin (); It! = M.end (); /* No longer self-increment */) (0 = = it->second% n) + (tmp = it++; M.erase ( TMP); {+-it++; +} +} (+) (+) P m; + int i = 0; for (i = 0; i < i++) (m) (m[i) = i; Deletevaluefrommap (m); Program OK in print (m); 0 return; 52} 53 Results: 54 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 55 1 2 3 4 6 7 8 9 11 12 13 14 16 17 18 19 56 57 58 59 60 61 of course, the above procedure can also continue to simplify As follows: #include <iostream> #include <map> the using namespace std; map<int typedef, int> map; map<int typedef, Int>::iterator MapIt; The &m void print (MAP), MapIt it; (it = M.begin (); it = M.end (); it++) UT << it->second << ""; cout << Endl;  Bayi} The Deletevaluefrommap (Map &m, int n = 5) of the "the" "MapIt" (it = m.begin);         /* No more self-increment * *) (0 = = it->second% n), m.erase (it++); 91} 92  Else-----it++ {94}-------98 int main () {101 Map m;102 int i = 0;103 for (i = 0; i <; i++) 104 {M[i] = i;106}107 108 print (m); 109 DELETEVALUEFR Ommap (M); Program ok111 print (m); 113 return 0;114}115 result OK.

Note that the 90th line above M.erase (it++), this sentence will not occur when the iterator fails. Because it++, an iterator that precedes it is returned.

The growth of vectors

Vector and string allocate more space per allocation space than required

Capacity () can tell us how many elements a container can hold without expanding memory
Reserve () allows us to inform the container how many elements it should be ready to save.
Container size Management operations:
Shrink_to_fit can only be used for Vector,string,deque
Capacity,reserve can only be used for vector,string
C.shrink_to_fit () reduces capacity () to the same size as size (), which can be ignored in the actual implementation, so it does not necessarily return space
C.capacity () The number of elements that C can hold without reallocating memory space
C.reserve (n) allocates at least n elements of memory space, N if <=capacity (), then the reserve does nothing; n is larger than the current capacity to allocate space.
C.size () The number of elements in the container is not the same as the capacity;

The allocation strategy used by most vectors is to double the current capacity capacity each time it needs to allocate memory space;
This is also uncertain, should be specific problems specific analysis.

By raising the push_back to create a vector of n elements in an initially empty vector, it takes no more than a constant number of n times.

C + + Base container

Related Article

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.