C + + vector usage Summary _c language

Source: Internet
Author: User

C + + vector usage

The built-in array of C + + supports the mechanism of the container, but it does not support the semantics of container abstraction. To solve this problem, we implement such a class ourselves. in standard C + +, the container vectors (vector) are implemented. The container vector is also a class template.

The standard library vector type uses the required header file: #include <vector>. Vector is a class template. Not a data type,vector<int> is a data type. The vector's storage space is contiguous and the list is not continuously stored.

First, 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 extended to V1.size ().
vector< typeName > V3 (n,i)//v3 type elements containing n values of I
vector< typeName > V4 (n); V4 contains an element with n values of 0
int a[4]={0,1,2,3,3}; Vector<int> v5 (a,a+5); The size of//V5 is 5,V5 5 values initialized to a. The latter pointer points to the next position of the last element to be copied.
Vector<int> V6 (V5);//v6 is a copy of V5.
vector< type > identifier (maximum capacity, initial all values);

Second, the value initialization

1> If an element initializer is not specified, the standard library itself provides an initialization value for value initialization.
2> If the saved style contains elements of the class type of the constructor, the standard library initializes it with a constructor of that type.
3> if the saved type has no elements of the class type of the constructor, the standard library produces an object with an initial value, which is used to initialize the value.

Three, the most important operation of vector objects

1. V.push_back (t) adds a value of t at the end of the container, and the size of the container becomes larger.
Another list has the Push_front () function, which is inserted at the front end, and the following elements are enlarged in turn.
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) doubles the capacity of V (and initializes the value of the new element to 99)
3. V.empty () to determine whether the vector is empty
4. V[n] returns elements in V with position n
5. V.insert (Pointer,number) Inserts the contents of number content into the position pointed to pointer in V.
and V. Insert (pointer, content), V.insert (Pointer,a[2],a[4]) inserts a[2 to a[4] three elements.
6. V.pop_back () Deletes the end element of the container and does not return the element.
7.v.erase (pointer1,pointer2) deletes elements from Pointer1 to Pointer2, including Pointer1.
After an element is deleted from the vector, the elements after this position need to move one position forward, although the current iterator position does not automatically add 1,
However, because subsequent elements are moved forward in sequence, it is equivalent to the iterator's automatic pointing to the next position.
8. V1==V2 judge whether 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 element you are pointing to.
For const vector<typename> can only be accessed with a vector<typename>::const_iterator type of pointer.
P=v1.end (); P points to the next position of the last element of the V1.
12.v.clear () deletes all elements in the container. 12.v.clear () deletes all elements in the container.
The functional algorithm in #include <algorithm>
Search algorithm: Find (), search (), count (), find_if (), search_if (), count_if ()
Sorting sort: Sort (), merge ()
Delete algorithm: Unique (), remove ()
Generation and Variation: Generate (), fill (), Transformation (), copy ()
Relational algorithm: Equal (), Min (), Max ()
Sort (V1.begin (), Vi.begin () +v1.size/2); Sorting the first half of the V1
List<char>::iterator pmiddle =find (Clist.begin (), Clist.end (), ' A '); Find to return the contents of the search first occurrence of the pointer, otherwise return end ().
vector< typeName >::size_type x; vector< typeName > Type count, available for loops as for (int i)
Beginners C + + programmers may think that the vector's subscript operation can add elements, but it is not:
Vector<int> Ivec; Empty vector
for (Vector<int>::size_type IX = 0; IX!= ++ix)
Ivec[ix] = IX; Disaster:ivec has no elements
The above program attempts to insert 10 new elements in the Ivec, and the element values are integers of 0 to 9. However, this ivec is an empty vector object, and the subscript can only be used to get an existing element.
The correct notation for this cycle should be:
for (Vector<int>::size_type IX = 0; IX!= ++ix)
Ivec.push_back (ix); Ok:adds new element with value IX
Warning: Must be an existing element to index with the subscript operator. When an assignment is made through the subscript operation, no elements are added. Subscript operations only for elements that are known to exist

Iv. memory management and efficiency

1. Use the reserve () function to set the capacity in advance to avoid multiple capacity expansion operation resulting in inefficiencies.
One of the most admirable features of STL containers is that they can automatically grow enough to accommodate the data you put in, as long as they are not larger than their maximum size. (To know the maximum value, just call the member function named Max_size.) For vectors and strings, if more space is needed, the size is increased by a similar realloc thought. Vector containers support random access, so in order to improve efficiency, it is implemented internally using dynamic arrays. Always increase the internal buffer by exponential boundary when requesting a specific size through reserve (). When adding elements such as insert or push_back, if the dynamic array of memory is not enough, it is necessary to dynamically reassign the current size of the new memory area of 1.5~2 times, and then copy the contents of the original array to the past. Therefore, in general, its access speed is the same as the normal array, only when the redistribution occurs, its performance will decline. As the above code tells you. In the case of a pop_back operation, the capacity does not decrease as the element in the vector container decreases and the size of the operation is maintained. For vector containers, if you have a large amount of data to be push_back, you should use the reserve () function to set its capacity in advance, otherwise there will be many secondary capacity expansion operations, resulting in inefficiencies.
The reserve member function allows you to minimize the number of times that you have to reassign, so you can avoid the overhead of true allocations and the failure of iterators/pointers/references. But before I explain why reserve can do that, let me briefly introduce the four related member functions that are sometimes confusing. In a standard container, only vectors and strings provide all of these functions.
(1) Size () tells you how many elements there 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 already allocated. That's how many elements a container can hold in that block of memory, not how many elements it can hold. If you want to know how much memory is not occupied in a vector or string, you must subtract the size () from the capacity (). If size and capacity return the same value, there is no space left in the container, and the next insertion (via insert or push_back, etc.) causes the reallocation step above.
(3) Resize (container::size_type N) forces the container to accommodate n elements instead. When resize is invoked, the size returns N. If n is less than the current size, the elements of the container's tail are destroyed. If n is greater than the current size, the new default constructed element is added to the container's tail. If n is greater than the current capacity, redistribution occurs before the element is joined.
(4) The 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 reallocation because the capacity needs to be increased. (if n is less than the current capacity, the vector ignores it, the call does nothing, and a string may reduce its capacity to the size () and the number of large n, but the string does not have a change.) In my experience, using reserve to trim excess capacity from a string is generally not as good as using the "swap technique," which is the subject of clause 17. )
This profile represents the redistribution (including the raw memory allocations and recoveries that they maintain, the invalidation of objects ' copies and destructors, pointers, and references) whenever there are elements that need to be inserted and the container's capacity is low. So, the key to avoiding redistribution is to use reserve to set the capacity of the container as quickly as possible, preferably immediately after the container is constructed.
For example, suppose you want to create a vector<int> that holds a value of 1-1000. Without using reserve, you can do it like this:

Vector<int> v;
for (int i = 1; I <= 1000; ++i) v.push_back (i);

In most STL implementations, this code will cause 2 to 10 redistribution during the loop. (10 This number is nothing strange.) Remember that vectors usually double the capacity when redistribution occurs, and 1000 is about 210. )
To change the code to use reserve, we get this:

Vector<int> v;
V.reserve (1000);
for (int i = 1; I <= 1000; ++i) v.push_back (i);

This does not occur in the loop.
The relationship between size and capacity allows us to predict when the insertion will cause a vector or string to perform redistribution, and that it is possible to predict when the insertion will invalidate the iterator, pointer, and reference in the container. For example, given this code,

string S;
...
if (S.size () < s.capacity ()) {
S.push_back (' x ');
}

The

Push_back call does not invalidate an iterator, pointer, or reference in this string because the capacity of a string is guaranteed to be greater than its size. If it is not executing push_back, the code makes an insert at any point in string, we can still guarantee that no redistribution will occur during the insertion, but it is consistent with the general rule that the iterator fails when the string is inserted. All iterators/pointers/references from the insertion position to the end of a string are invalidated.
back to the main thrust of this article, there are usually two situations in which reserve is used to avoid unnecessary redistribution. The first available scenario is when you know exactly or approximately how many elements will eventually appear in the container. In that case, like the vector code above, you just reserve the right amount of space in advance. The second scenario is to keep the maximum space you may need, and then, once you've added all the data, trim any excess capacity.
       2. Use "Swap tips" to trim vector excess space/memory
      There is a way to reduce it from the once largest capacity to the capacity it needs now. This method of reducing capacity is often referred to as "shrink to fit". This method requires only one statement:vector<int> (IVEC). Swap (IVEC); The
Expression vector<int> (Ivec) creates a temporary vector, which is a copy of Ivec: Vector's copy constructor does the job. However, the vector's copy constructor allocates only the memory required by the copied elements, so this temporary vector has no extra capacity. Then we let the temp vector and Ivec exchange data, and we finished, Ivec only the trimmed capacity of the temporary variable, which holds the excess capacity that was once in Ivec. Here (at the end of this statement), the temporary vector is destroyed, thus releasing the memory previously used by the Ivec and shrinking to fit.
     3. To forcibly release the memory of an STL vector by using the Swap method

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); }; Add bracket {} is automatic destructor when TMP exits {}

V. Behavior testing of Vector memory management member functions

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

#include <iostream> #include <vector> using namespace std;
int main () {vector<int> ivec cout << "container size is:" << ivec.size () << Endl; cout << "Container capacity:" << ivec.capacity () << Endl;
1 elements, container capacity of 1 ivec.push_back (1);
cout << "Container size is:" << ivec.size () << Endl; cout << "Container capacity:" << ivec.capacity () << Endl;
2 elements, container capacity of 2 ivec.push_back (2);
cout << "Container size is:" << ivec.size () << Endl; cout << "Container capacity:" << ivec.capacity () << Endl;
3 elements, container capacity of 4 ivec.push_back (3);
cout << "Container size is:" << ivec.size () << Endl; cout << "Container capacity:" << ivec.capacity () << Endl;
4 elements, container capacity of 4 ivec.push_back (4);
Ivec.push_back (5);
cout << "Container size is:" << ivec.size () << Endl; cout << "Container capacity:" << ivec.capacity () << Endl;
5 elements, container capacity of 8 ivec.push_back (6);
cout << "Container size is:" << ivec.size () << Endl; cout &LT;&LT "Container capacity:" << ivec.capacity () << Endl;
6 elements, container capacity of 8 ivec.push_back (7);
cout << "Container size is:" << ivec.size () << Endl; cout << "Container capacity:" << ivec.capacity () << Endl;
7 elements, container capacity of 8 ivec.push_back (8);
cout << "Container size is:" << ivec.size () << Endl; cout << "Container capacity:" << ivec.capacity () << Endl;
8 elements, container capacity of 8 ivec.push_back (9);
cout << "Container size is:" << ivec.size () << Endl; cout << "Container capacity:" << ivec.capacity () << Endl; 9 elements, container capacity for/* VS2005/8 capacity growth is not doubled, such as 9 element capacity 9 10 element capacity 13/* Test effective STL Special Swap Swap () * * cout << "when
The size of the former vector is: "<< ivec.size () << Endl;"
cout << "Current vector capacity is:" << ivec.capacity () << Endl;
Vector<int> (Ivec). Swap (IVEC);
cout << "The size of the temporary vector<int> object is:" << (vector<int> (Ivec)). Size () << Endl; The capacity of the cout << "temporary vector<int> object is:" << (vector<int> (Ivec)).Capacity () << Endl;
cout << "After the exchange, the current vector size is:" << ivec.size () << Endl;
cout << "After the exchange, the current vector capacity is:" << ivec.capacity () << Endl;
return 0; }

Vi. other member functions of vectors

C.assign (Beg,end)
Assign the data in the [Beg end] interval to C.
C.assign (N,elem)
Assign a copy of n elem to C.
c.at (IDX)
Returns the data that the index IDX refers to, and throws the Out_of_range if the IDX crosses over.
C.back ()
Returns the last data and does not check if the data exists.
C.front ()
Returns a data to the ground.
Get_allocator
Returns a copy using the constructor.
C.rbegin ()
Returns the first data of a reverse queue.
C.rend ()
Returns the next position of the last data in a reverse queue.
c.~ Vector <Elem> ()
Destroys all data and frees up memory.

This is supplemented by other netizens:

1. Basic operation

(1) header file #include<vector>.

(2) Creating a Vector object,vector<int> VEC;

(3) Tail Insert number: Vec.push_back (a);

(4) Use subscript to access elements,cout<<vec[0]<<endl; remember that subscripts start at 0.

(5) Accessing elements using iterators.

Vector<int>::iterator it;
For (It=vec.begin (); It!=vec.end (); it++)
  cout<<*it<<endl;

(6) Insert element: Vec.insert (Vec.begin () +i,a); Insert a in front of the i+1 element;

(7) Delete element: Vec.erase (Vec.begin () +2); Delete 3rd element

Vec.erase (Vec.begin () +i,vec.end () +j); Delete interval [i,j-1]; interval starting from 0

(8) Vector size: vec.size ();

(9) Empty: Vec.clear ();

2, vector elements can not only make int,double,string, but also can be a structural body, but to note: The structure is defined as global, otherwise there will be errors. The following is a short program code:

#include <stdio.h>
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;

typedef struct RECT
{
 int id;
 int length;
 int width;

For vector elements that are structural, you can define comparison functions within the structure, sorted by Id,length,width ascending order.
bool operator< (const rect &a) Const
 {
  if (id!=a.id) return
   id<a.id;
  else
  {
   if (length!=a.length) return
    length<a.length;
   else return width<a.width;}}}
Rect;

int main ()
{
 vector<rect> vec;
 Rect Rect;
 rect.id=1;
 rect.length=2;
 rect.width=3;
 Vec.push_back (rect);
 Vector<rect>::iterator It=vec.begin ();
 cout<< (*it) .id<< ' << (*it) .length<< ' << (*it) .width<<endl; 

return 0;

}

3 algorithm

(1) Use reverse to flip the element: Requires a header file #include<algorithm>

Reverse (Vec.begin (), Vec.end ()); Flip the element (in vector, if two iterators are required in a function,

Usually the latter one is not included.)

(2) Use sort order: Need header file #include<algorithm>,

Sort (Vec.begin (), Vec.end ());(default is in ascending order, that is, from small to large.

You can compare the sort comparison functions by overriding them in descending order, as follows:

To define a sort comparison function:

Copy Code code as follows:

BOOL Comp (const int &A,CONST int &b)
{
Return a>b;
}

When called: Sort (Vec.begin (), Vec.end (), Comp), sorted in descending order.

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.