Use of the vector of the STL

Source: Internet
Author: User
Tags arrays constant constructor
Use of the vector of the STL

Getting started with the first part

Vectors can be used instead of arrays in C, or CArray in MFC, from many explanatory documents or online comments, and generally agree that vectors should be used more efficiently and with exceptional security. And vectors are the default containers recommended by STL, unless you know you have special needs, using vectors that do not meet your needs, such as requiring containers to be efficiently inserted and removed at head and tail, or efficiently removed and inserted in any location, Then you might use deque or list more appropriately.

Vectors are contiguous memory containers, in other words, when standards require all standard libraries to be implemented, the memory of elements in a vector must be contiguous. So the time complexity for insertions and deletions is very high, because when you delete or INSERT, you need to move the element, that is, the copy of the element.

The internal implementation of vectors generally needs to use the placement new, so the efficiency is very high, because many times, as long as we are used to get, we can save a lot of memory allocation overhead. and the use of vectors, elements can have no default constructor, but need to copy the existence of the constructor, which is not possible with the use of CArray.

principle of Use:

1, try to use vectors instead of C-style arrays or carray;

2, try to use algorithms instead of hand-written loops;

3, try to use the function of vector itself instead of other generic algorithms;

Vector interface is easy to understand and use, here are some examples to illustrate the use of vectors.

1, filled vector

If we want to populate the vector with the contents of the original array, there are many ways. Let's take a few methods of learning vectors.

For example we have array int v1[10] = {0,1,0,0,3,0,0,4,4,4};

initialization Mode 1:

Vector<int> v2 (10); Initializing a size of 10 avoids the constant allocation of memory when the array is dynamically growing

V2.reserve (10);//ditto, just use one of them.

for (int i=0; i<10; i++)

{

V2.push_back (V1[i]);//Add an element

}

initialization Mode 2:

Vector<int> v3 (&v1[0],&v1[9]);//The element pointer of the original array can be used as an iterator

initialization mode 3:

Vector<int> v4;

V4.reserve (10);

V4.insert (V4.begin (), &v1[0], &v[9]);

initialization Mode 4:

Vector<int> v5 (10);

Copy (V5.begin (), &v1[0], &v1[9]);

The element pointer of the original array can be used as an iterator.

principle: Use reserve as much as possible to reduce the number of unnecessary memory allocations.

principle: Try to use empty instead of size () ==0 to determine if the container is empty

It's possible that we need to insert the appropriate element in the vector.

Vector<int>::iterator i = Find (V1.begin (), V1.end (), 3);

if (i! = V1.end ())

{

V1.insert (i, 6);

}

2, traversing vector

For example there are vector<int> v1;

void print (int i)

{

cout << i << Endl;

}

Mode 1:

for (int i=0; i<v1.size (); i++)

{

Print (V1[i]);

}

This is the way we are most familiar with, but not good enough to write concise enough. And for other containers that do not have random iterators, this is impossible.

Mode 2:

typedef vector<int>:: iterator Vintiterator;

Vintiterator end = V1.begin ();

For (Vintiterator i=v1.begin (); I! = end; ++i)

{

Print (*i);

}

Note: It is advantageous to calculate end first, because it is not necessary to repeat the calculation of the End,vector end () every time, so caching it first can improve efficiency. When writing algorithms, try to use! = to compare iterators, because < does not have this operator for many non-random iterators.

But this kind of way is also more cumbersome to write.

Mode 3:

For_each (V1.begin (), V1.end (), print);

Using algorithms is a lot easier to write.

When using algorithms, you can use function objects, such as

Class OutPut

{

Public

void operator () (double i)

{

Std::cout << i;

}

}

For_each (V1.begin (), V1.end (), OutPut);

Delete in 3,vector

Delete the specified element

Vector<double> v1;

.... Initialize code

Vector<double>:: Iterator i = Find (V1.begin (), V1.end (), 3.0);

if (i! = V1.end ())

{

V1.erase (i);

}

Does this really delete the specified element? No. In fact, only the internal elements have been moved, the time complexity of the deletion of vectors is very high. So when choosing a container, if you need to insert and delete elements frequently in the middle, choosing a vector will affect efficiency.

Note: An INSERT or delete operation invalidates the iterator.

principle: Delete elements using Erase-remove idioms

V1.erase (Remove (V1.begin (), V1.end (), 3.0), v1.end ());

whether the 4,vector is empty

When judging if the container is empty, use empty () instead of size () for 0 inspection, because empty is more efficient time complexity is constant time, and size () time complexity is not constant time.

Principle: Use empty to determine if the standard container is empty

Find in 5,vector

Principle: Try to replace the common algorithm with the standard container's own algorithm.

But Vector does not have many of its own algorithms, but the list has a remove, remove_if,sort,reverse and other algorithms.

Find

Find_if

6, using switching techniques to correct excess capacity

Vector<int> v1;

... Initialize V1

... Delete all the elements in the V1

But this time V1 memory capacity is not 0, or a large piece of memory is not released, if you want to empty

Use V1.reserve (0) to reach the target, because reserve can only enlarge the memory capacity and cannot be reduced.

Vector<int> v2;

V2.swap (v1);

This is the time to really reduce the memory capacity to a minimum.

6, off-topic: Using Algorithms and other tricks

principle: Do not use auto_ptr as a template parameter to build the container, this will produce unexpected traps, because the copy of auto_ptr has special semantics

principle: Avoid using VECTOR<BOOL>, because it cannot be used as a standard container

Copy

Find_if

For_each

principle: Try to use interval member functions instead of their single-element parameter sibling member functions

Interval construction

Interval Delete

Interval Assignment

Interval insertion

principle: The copy operation of the elements in the container is lightweight and correct, the copy is the basic way of the container in the STL, the element is added to the container, and the element in the container is no longer the original element, so if the pointer is added to the container, The object that the pointer refers to must be deleted before the container leaves the scope.

void Fun ()

{

Vector<object*> v1;

...//insert operation

For (vector<object*>:: Iterator i = V1.begin (); I! = V1.end (); ++i)

{

Delete *i;

}

}

principle: Note for vectors, any insert delete operation will invalidate the iterator. So be careful.

The second part uses the error discussion

Vector semantics are often misunderstood, so the use of errors often occurs

1, Case one

Can you find the following problem?

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.