C++vector How to use

Source: Internet
Author: User

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 this 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 file: #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 includes n typeName type element with value 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 full value);

Second, value initialization
1> assumes that no element initialization is specified, and the standard library provides itself with an initialization value for value initialization.
2> assumes that the saved formula contains the elements of the class type of the constructor, which the standard library initializes with the constructor of that type.
3> assumes that an element of a class type without constructors is saved, and 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? A data with a value of T, 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 size returns the value of the size_type corresponding to the vector class definition. 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 () infer if the vector is empty
4. V[n] Returns the element with position N in V
5. V.insert (pointer,number, content) inserts the contents of a number in the position pointed to by the 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 () Deletes the end element of the container and does not return the element.
7.v.erase (POINTER1,POINTER2) removes the element pointer1 to the middle of the Pointer2, which contains pointer1.
When an element is removed from the vector, the subsequent elements of this position need to move forward one position, although the current iterator position does not have its own active add 1,
However, because the element may be moved forward in sequence, it is equivalent to the iterator's own initiative pointing to the next position.
8. V1==v2 infers whether V1 is equal to V2.
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> It is only possible to access the Vector<typename>::const_iterator type of pointer.
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. 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)


Beginner C + + program apes may think that vector subscript operations can be added to the element, in fact, otherwise:

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 the ability to index with subscript operators. When assigning by subscript, 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 are able to grow themselves to accommodate the data you put in by simply not exceeding their maximum size. (To know this maximum, just call the member function called Max_size.) For vectors and strings, it is assumed that a lot of other space is needed to grow in size like realloc thought. The vector container supports random access, so in order to improve efficiency, it is implemented internally using dynamic arrays. When you request a specific size by reserve (), it always increases its internal buffer by exponential bounds. When you add an insert or push_back, such as an operation of an element, assuming that the dynamic array of memory is not enough, it is necessary to dynamically allocate the current size of 1.5~2 times the new memory area, and then copy the contents of the original array past. Therefore, in the ordinary case, its access to the same speed as the general array, only in another allocation occurs, its performance will decline. 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 size before the operation. For vector containers, assuming that there is 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 sub-capacity expansion operations, resulting in inefficient.

The reserve member function allows you to minimize the number of times another allocation 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. Suppose you want to know how much memory is not occupied in a vector or string, you must subtract size () from capacity (). Assuming that size and capacity return the same value, there is no space left in the container, and the next insertion (through insert or push_back, etc.) raises the previous allocation step.
(3) Resize (container::size_type N) forcibly changes the container to accommodate n elements. After calling resize, size will return N. Assuming N is less than the current size, the elements at the end of the container are destroyed. Assuming that n is greater than the current size, the new default constructed element is added to the container trailer. Assuming N is greater than the current capacity, another allocation 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 is generally forced to be allocated again and again, as capacity needs to be added. (assuming that n is less than the current capacity, the vector ignores it, the call does nothing, and the string may reduce its capacity to size () and the large number in N, but the size of the string does not change.) In my experience, using the 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 simple introduction indicates that only the elements need to be plugged in and the container's capacity is insufficient to occur again and again (including the original memory allocations and recoveries that they maintain, the copying and destruction of objects and the invalidation of iterators, pointers, and references). Therefore, the key to avoid another allocation is to use reserve as soon as possible to set the capacity of the container 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 allocations again during the loop. (10 This number is nothing strange.) Remember that vectors tend to double the capacity when another allocation occurs, 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 happen again in the loop.

The relationship between size and capacity allows us to predict when insertions will cause a vector or string to run again, and to predict when insertions will invalidate iterators, pointers, and references in the container. For example, given this code,

http://www.fjzzled.com/hzjdyyyyjs/95.html

http://www.fjzzled.com/hzjdyyyyjs/94.html

http://www.sjys365.com/smzl/2999.html

http://www.sjys365.com/smzl/2998.html


string S;
...
if (S.size () < s.capacity ()) {
S.push_back (' x ');
}
The push_back call does not invalidate the iterator, pointer, or reference that points to the string, because the capacity of the string is guaranteed to be greater than its size. Assuming that you are not running Push_back, the code makes an insert anywhere in the string, and we can still guarantee that no more allocations occur during the insertion, but 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 string will be invalidated.

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 last out in today's container. In that case, just like the vector code above, you just reserve an appropriate amount of space in advance. Another situation is to keep the maximum space you may need, and then, once you're done with all the data, trim out whatever extra capacity you have.

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

There is a way to reduce it from its previous maximum capacity to the capacity it now needs. This method of reducing capacity is often referred to as "Shrinking to fit" (shrink to fit). This 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 vector's copy constructor allocates only the memory required for the copied elements, so this temporary vector has no excess capacity. Then we let the temporary vector and the Ivec exchange data, then we are finished, Ivec only have a temporary variable of the trimmed capacity, and this temporary variable holds the previous in Ivec in the unused excess capacity. 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 self-destructor when tmp exits {} */

V. Behavior of Vector memory management member functions test
C + + STL vector is widely used, but the memory of its management model has been a variety of push, the following example code test to understand its memory management methods, test code such as the following:

#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 with a container capacity of 16
/* VS2005/8 capacity growth is not doubled, such as
9 Element Capacity 9
10 Elements Capacity 13 */

/* Test Effective Special Swap swap () in STL */
cout << "The size of the current vector is:" << 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 a 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 vectors

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 data referred to by the index IDX, assuming that IDX is out of bounds and 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> ()
Destroys all data and frees up memory.

http://www.5678520.com/kaiwangdian/130.html

http://www.5678520.com/kaiwangdian/129.html

http://www.5678520.com/kaiwangdian/128.html

http://www.5678520.com/kaiwangdian/127.html

http://www.5678520.com/kaiwangdian/126.html

http://www.lianzhiwei.com/News/389/20122116.html

http://www.lianzhiwei.com/News/389/20122115.html

http://www.lianzhiwei.com/News/389/20122114.html

http://www.lianzhiwei.com/News/389/20122113.html

http://www.lianzhiwei.com/News/389/20122112.html


C++vector How to use

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.