C++

Source: Internet
Author: User

Vectors is sequence containers representing arrays that can change in size.
Just like arrays, vectors use contiguous storage locations for their elements, which means this their elements can also be Accessed using offsets on regular pointers to its elements, and just as efficiently as in arrays. But unlike arrays, their size can change dynamically, with their storage being handled automatically by the container.
Internally, vectors use a dynamically allocated array to store their elements. This is an array of need to being reallocated in order to grow in size when new elements is inserted, which implies allocating a New array and moving all elements to it. This was a relatively expensive task in terms of processing time, and thus, vectors does not reallocate each time an element is added to the container.
Instead, vector containers may allocate some extra storage to accommodate for possible growth, and thus the container The actual capacity greater than the storage strictly needed to contain its elements (i.e., itssize). Libraries can implement different strategies for growth to balance between memory usage and reallocations , reallocations should only happen at logarithmically growing intervals of size so, the insertion of individual elemen TS at the end of the vector can is provided withamortized constant timeComplexity (Seepush_back).
Therefore, compared to arrays, vectors consume more memory on exchange for the ability to manage storage and grow Dynamica Lly in an efficient.

The C + + built-in array supports the container's mechanism, but it does not support the semantics of container abstraction. To solve this problem we implement such a class ourselves. in standard C + +, it is implemented with container vectors (vector). A container vector is also a class template. The standard library vector type uses the required header files: #include <vector>. a vector is a class template. is not a data type,vector<int> is a data type. The vector's storage space is contiguous, and the list is not stored continuously.

I. Definition and initialization

vector< typeName > v1; The default v1 is empty, so the following assignment is the wrong v1[0]=5;

Vector<typename>v2 (v1); or V2=V1, or vector<typename> v2 (V1.begin (), V1.end ()),//v2 is a copy of V1 if V1.size () >v2.size () is assigned v2.size ()

is expanded to V1.size ().

vector< typeName > V3 (n,i);//v3 a typeName type element with n values of I

vector< typeName > V4 (n); V4 contains n elements with a value of 0

int a[4]={0,1,2,3,3}; Vector<int> v5 (a,a+5); The size of//V5 is the 5 values that 5,V5 is initialized to a. The latter pointer points to the next position of the last element that will be copied.

Vector<int> V6 (V5);//v6 is a copy of V5.

vector< type > identifier (maximum capacity, initial all values);

Second, value initialization

1> If no element initialization is specified, the standard library provides itself with an initialization value for value initialization.

2> If you save an element of a class type that contains constructors, the standard library initializes with that type's constructor.

3> If you save an element of a class type that does not have a constructor, the standard library produces an object with an initial value initialized with this object.

Iii. the most important operations of vector objects

1. V.push_back (t)

At the end of the container, add a value of T, and the size of the container becomes larger.

In addition the list has the Push_front () function, which is inserted at the front end, and the following elements are incremented sequentially.

2. V.size ()

Returns the number of data in the container, and the size returns the value of the size_type defined by the corresponding vector class. V.resize (2*v.size) or

V.resize (2*v.size, 99)

Double the capacity of V (and initialize the value of the new element to 99)

3. V.empty ()

Determine if the vector is empty

4. V[n]

Returns an element of position N in V

5. V.insert (Pointer,number, content)

Inserts the contents of number content into the position pointed to by pointer in V.

and V. Insert (pointer, content), V.insert (Pointer,a[2],a[4]) inserts three elements of a[2] to a[4].

6. V.pop_back ()

Removes the end element of the container and does not return the element.

7.v.erase (Pointer1,pointer2)

Remove elements from the middle of Pointer1 to Pointer2 (including those referred to by Pointer1)

After removing an element from the vector, the elements in this position need to move forward one position, although the current iterator position does not automatically add 1,

But because the subsequent elements are moved forward in the same way, they are equivalent to the iterator's automatic pointing to the next position.

8. V1==v2

Determine if V1 and v2 are equal.

9.! =, <, <=, >, >=

Keep these operators in the habit of meaning.

Vector<typename>::iterator P=v1.begin ();

The P-Initial value points to the first element of the V1. *p the value of the pointed element.

For Const vector<typename> can only be accessed with pointers of type Vector<typename>::const_iterator.

One. P=v1.end ();

P points to the next position of the last element of the V1.

12.v.clear ()

Deletes all the elements in the container.

A functional algorithm in #include <algorithm>

Search algorithm: Find (), search (), count (), find_if (), search_if (), count_if ()

Sort by Category: sort (), merge ()

Delete algorithm: Unique (), remove ()

Generation and mutation: Generate (), fill (), Transformation (), copy ()

Relational algorithms: Equal (), Min (), Max ()

Sort (V1.begin (), Vi.begin () +V1.SIZE/2), ordering the first half of the V1

List<char>::iterator pmiddle =find (Clist.begin (), Clist.end (), ' A '), found returns the first occurrence of the checked content pointer, otherwise returns end ().

vector< typeName >::size_type x; vector< typeName > Type count, can be used for loops like for (int i)

Novice C + + programmers may think that vector subscript operations can add elements, but not:

Vector<int> Ivec; Empty vector

for (Vector<int>::size_type IX = 0; IX! = ten; ++ix)

Ivec[ix] = IX; Disaster:ivec has no elements

The above program attempts to insert 10 new elements into the Ivec, with the element values sequentially from 0 to 9 integers. However, here Ivec is an empty vector object, and the subscript can only be used to get an existing element.

The correct notation for this loop should be:

for (Vector<int>::size_type IX = 0; IX! = ten; ++ix)

Ivec.push_back (ix); Ok:adds new element with value IX

Warning: must be an existing element to be indexed with the subscript operator. When you assign a value by using the subscript operation, no element is added. Subscript operation is only possible for elements that are known to exist

Iv. Memory management and efficiency

1. Use the reserve () function to set the size of the capacity in advance to avoid multiple capacity expansion operations resulting in inefficiency.

One of the most admirable features about STL containers is that they can automatically grow to accommodate the data you put in as long as they don't exceed their maximum size. (To be aware of this maximum value, just call the name

The member function of the max_size. For vectors and strings, if more space is needed, it grows in size like realloc thought. The vector container supports random access, so in order to improve efficiency, it uses internal

The way the dynamic array is implemented. When you request a specific size by reserve (), it always increases its internal buffer by exponential bounds. When an add element such as insert or push_back is done, if

The dynamic array of memory is not enough, it is necessary to dynamically reallocate the current size of 1.5~2 times the new memory area, and then copy the contents of the original array past. So, in general, its access speed is the same as that of a general array, only in heavy

When a new allocation occurs, its performance will decrease. As the above code tells you. In the case of pop_back operation, the capacity does not decrease due to the decrease of the elements in the vector container, but also maintains the operation

Before the size. For a vector container, if there is a large amount of data to be push_back, the reserve () function should be used to set its capacity in advance, otherwise there will be many sub-capacity expansion operations, resulting in effective

Low rate.

The reserve member function allows you to minimize the number of re-allocations that must be made, thus avoiding the overhead of true allocations and invalidation of iterators/pointers/references. But before I explain why reserve can do that,

Let me briefly describe some of the four related member functions that are sometimes confusing. In a standard container, only the vector and string provide all of these functions.

(1) Size () tells you how many elements are in the container. It does not tell you how much memory the container allocates for the elements it holds.

(2) capacity () tells you how many elements the container can hold in the memory it has allocated. That's how many elements a container can hold in that memory, rather than how many elements it can hold. If you want to know a

There is not much memory in the vector or string, you must subtract size () from capacity (). If size and capacity return the same value, there is no space left in the container, and the next insertion (by

Insert or push_back, etc.) will cause the above reassignment step.

(3) Resize (container::size_type N) forcibly changes the container to accommodate n elements. After calling resize, size will return N. If n is less than the current size, the element at the end of the container is destroyed. If n is greater than

The current size, and the new default constructed element is added to the container trailer. If n is greater than the current capacity, redistribution occurs before the element is added.

(4) reserve (Container::size_type N) forces the container to change its capacity to at least N, providing n not less than the current size. This generally forces a redistribution, as capacity needs to be increased. (if n is less than

Current capacity, vector ignores it, this call does nothing, string may reduce its capacity to size () and n large number, but the size of the string does not change. In my experience, using the reserve to

Trimming excess capacity in string is generally not as good as using the "swap technique", which is the subject of clause 17. )

This profile indicates that redistribution occurs whenever there are elements that need to be plugged in and the capacity of the container is insufficient (including the raw memory allocations and recoveries they maintain, copy and destructor of objects, and iterators, pointers, and referenced

Failure). Therefore, the key to avoid redistribution is to use reserve as soon as possible to set the container capacity is large enough, preferably after the container is constructed immediately.

For example, suppose you want to create a vector<int> that holds 1-1000 values. Instead of using reserve, you can do it like this:

Vector<int> v;

for (int i = 1; I <=, ++i) v.push_back (i);

In most STL implementations, this code will cause 2 to 10 reallocation during the loop. (10 This number is nothing strange.) Remember that vectors tend to double the capacity at the time of redistribution, and 1000 is approximately equal to 210. )

To change the code to use reserve, we get this:

Vector<int> v;

V.reserve (1000);

for (int i = 1; I <=, ++i) v.push_back (i);

This does not occur in the loop redistribution.

The relationship between size and capacity allows us to predict when the insertion will cause a vector or string to be reassigned, and to predict when the insertion will cause iterators, pointers, and references in the container to be lost

Effect. For example, given this code,

string S; ...

if (S.size () < s.capacity ()) {

S.push_back (' x ');

The call to Push_back does not invalidate the iterator, pointer, or reference to the string, because the capacity of the string is guaranteed to be greater than its size. If the push_back is not executed, the code is anywhere in the string

With an insert, we can still guarantee that no redistribution occurs during the insertion, but consistent with the general rule that the iterator fails with the insertion of a string, all iterators/fingers from the insertion position to the end of the string

The PIN/reference will expire.

Back to the main thrust of this article, there are usually two cases where the reserve is used to avoid unnecessary redistribution. The first available case is when you know exactly or about how many elements will eventually appear in the container. In that case, you

Like the vector code above, you just reserve an appropriate amount of space in advance. The second case is to keep the maximum space you may need, and then, once you've added all the data, trim out any excess capacity.

2. Use "switching technique" to trim vector excess space/memory

There is a way to reduce it from the once-largest capacity to the capacity it now needs. This way of reducing capacity is often referred to as "Shrinking to fit" (shrink to fit). The method requires only one statement:

Vector<int> (Ivec). Swap (IVEC);

The expression vector<int> (Ivec) establishes a temporary vector, which is a copy of the Ivec: the copy constructor of the vector does the work. However, the copy constructor of the vector only assigns the copied elements to the required

Memory, so this temporary vector has no extra capacity. Then we let the temporary vector and the Ivec exchange data, and then we finished, Ivec only the trimmed capacity of the temporary variable, and this temporary variable holds the

The unused excess capacity that was once in the Ivec. Here (at the end of this statement), the temporary vector is destroyed, so the memory used by the previous Ivec is freed and shrunk to fit.

3. Use the Swap method to forcibly release the memory of the STL vector

template < class t> void Clearvector (vector<t>& v) {vector<t>vttemp; Vttemp.swap (v);     } such as Vector<int> V;     Nums.push_back (1);     Nums.push_back (3);     Nums.push_back (2);     Nums.push_back (4); Vector<int> (). Swap (v);

/* or V.swap (vector<int> ()); */

/* or {std::vector<int> tmp = V;   V.swap (TMP); }; The brace {} is automatically refactored when TMP exits {} */

V. Vector memory Management behavior test of member functions

The vector of C + + STL is very widely used, but the management model of its memory has been a lot of guesses, the following example code test to understand its memory management method, the test code is as follows:

#include <iostream> #include <vector> using namespace std;

int main () {vector<int> iVec; cout << "container size:" << ivec.size () << Endl; cout << "Container capacity:" << ivec.capacity () << Endl; 1 elements with a container capacity of 1

Ivec.push_back (1); cout << "container size:" << ivec.size () << Endl; cout << "Container capacity:" << ivec.capacity () << Endl; 2 elements with a container capacity of 2

Ivec.push_back (2); cout << "container size:" << ivec.size () << Endl; cout << "Container capacity:" << ivec.capacity () << Endl; 3 elements with a container capacity of 4

Ivec.push_back (3); cout << "container size:" << ivec.size () << Endl; cout << "Container capacity:" << ivec.capacity () << Endl; 4 Elements with a container capacity of 4

Ivec.push_back (4); Ivec.push_back (5); cout << "container size:" << ivec.size () << Endl; cout << "Container capacity:" << ivec.capacity () << Endl; 5 Elements with a container capacity of 8

Ivec.push_back (6); cout << "container size:" << ivec.size () << Endl; cout << "Container capacity:" << ivec.capacity () << Endl; 6 elements with a container capacity of 8

Ivec.push_back (7); cout << "container size:" << ivec.size () << Endl; cout << "Container capacity:" << ivec.capacity () << Endl; 7 elements with a container capacity of 8

Ivec.push_back (8); cout << "container size:" << ivec.size () << Endl; cout << "Container capacity:" << ivec.capacity () << Endl; 8 elements with a container capacity of 8

Ivec.push_back (9); cout << "container size:" << ivec.size () << Endl; cout << "Container capacity:" << ivec.capacity () << Endl; 9 elements, container capacity of */* VS2005/8 capacity growth is not doubled, such as 9 element capacity 9 10 element capacity 13 */

/* Test effective STL Special Swap Swap () */cout << "Current vector size:" << ivec.size () << Endl; cout << "Current vector capacity:" << ivec.capacity () << Endl; Vector<int> (IVEC). Swap (IVEC);

cout << "The size of the temporary vector<int> object is:" << (vector<int> (IVEC)). Size () << Endl; cout << "The capacity of the temporary Vector<int> object is:" << (vector<int> (IVEC)). Capacity () << Endl; cout << "After swapping, the current vector size is:" << ivec.size () << Endl; cout << "After swapping, the current vector capacity is:" << ivec.capacity () << Endl;

return 0; }

Vi. other member functions of the vector

C.assign (Beg,end)

Assigns the data in the [beg; end] Interval to C.

C.assign (N,elem)

Assigns a copy of n elem to C.

c.at (IDX)

Returns the index IDX refers to the data, if the IDX is out of bounds, throws Out_of_range.

C.back ()

Returns the last data without checking to see if the data exists. C.front ()

Returns a data back to the ground.

Get_allocator

Use the constructor to return a copy. C.rbegin ()

Returns the first data for a reverse queue.

C.rend ()

Returns the next position of the last data in a reverse queue.

c.~ Vector <Elem> ()

Destroy all data and free up memory

Any action that alters the length of the vector will invalidate an existing iterator.

C++

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.