Dowemo

This article mainly introduces c + +, a vector is a very useful container, and a summary of this container.

c + + vector

C + + built-in array support container, but it doesn't support the semantics of container abstractions. To solve this problem, we implement such a class. In standard c + +, the container vector ( vector ) is implemented. Container vector is also a class template.

Standard library vector types use the required header files: # include <vector>. Vector is a class template. Not a data type, vector <> is a data type. The storage space of the vector is continuous, and list isn't a continuous storage.

, definition and initialization

A vector <> v1; the default is null, so the following assignment is the wrong [ 0 ] = 5;
Vector <> v2 ( v1 ); or v2 = v1; or vector <typename> v2 ( v1. Begin ( ), v1. End ( ) ); v2 is a copy of v1, if ( ) is expanded to v1. Size ( )> ( ) is expanded to v1. Size ( ).
A vector <typename> v3 ( n, I ); v3 contains a typename type element with n values I
A vector <typename> v4 ( n ); v4 contains an element with n values 0
Int a [ 4 ] = % 7B0, 1, 2, 3, 3 % referrals; vector <int> v5 ( a, a + servicecontroller ); v5 's size is 5 and v5 is initialized to a 5 value. The next pointer points to the next position of the end element that will be copied.
Vector <> v6 ( v5 ); v6 is a copy of v5
A vector <type> identifier ( maximum, initial, and all values );

,.

1> if no element initialization is specified, the standard library provides an initialization value to initialize itself.
2> if you saved an element of the class type that contains a constructor, the standard library uses the constructor of that type.
3> if you save an element of a class type that doesn't have a co & tructor, the standard library generates an object with an initial value, using this object to initialize values.

, the most important operation of vector objects

1. V. Push_back ( t ) adds a value of t at the end of the container, with the size of the container larger.
Another list has the push front ( ) function, which is inserted at the front end and the following element subscript increases in turn.
2. V. Size ( ) retur & the number of data in a container, and size retur & 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 ( ) determines whether the vector is null.
4. V [ n ] retur & the element in v.
Inserts the content of content to the position at which the pointer points in v. Number. Insert ( pointer. Content ).
Also v. Insert ( pointer, content ), v. Insert ( pointer, a [ 2 ], a [ 4 ] ) to add a [ 2 ] to three elements of a [ 4 ].
6. V. Pop_back ( ) removes the end element of the container without returning back to the element.
7. V. Erase ( pointer1, pointer2 ) deletes the elements of pointer1 to the middle of pointer2 ( including pointer1 ).
After deleting an element in the vector, the elements later in this position need to move a position, although the current iterator position isn't 1.
But as the subsequent elements move forward, it's equivalent to the next position of the iterator.
8. V1 = = v2 determines if v1 is equal to v2.
9. =, <, <=,>,> = keep these operators mean.
10. Vector <>:: iterator p = v1. Begin ( ); p initialize point to the fi t element of v1. A value that * p points to the element.
For const vector <>, you can access only the pointer to the vector <typename>:: const iterator.
11. P = v1. End ( ); p points to the next location of the last element of v1.
12. V. Clear ( ) deletes all elements in the container. 12. v. clear ( ) deletes all elements in the container.
Functional algorithms in # include <algorithm>
Search algorithm: find ( ), search ( ), count ( ), find_if ( ), search_if ( ), count_if ( ), ( ), ( ), ( )
Sorting sorting: sort ( ), merge ( )
Delete algorithm: unique ( ), remove ( )
Generate and mutation: generate ( ), fill ( ), transformation ( ), copy ( ), copy ( ), copy ( )
Relationship algorithm: equal ( ), min ( ), max ( )
Sort ( v1. Begin ( ), vi. Begin ( ) + v1. Size/2 ); sorting on elements of v1.
List <>:: iterator pmiddle = find ( clist. Begin ( ), clist. End ( ), a ( ) ); find the fi & t occurrence of the checked content; otherwise, the end ( ) is returned.
Vector <typename>:: size_type x; vector <typename> type, can be used to loop as for ( int I )
Programmers with c + + might think that the subscript operation of a vector can add elements, in fact:
Vector <> ivec;//empty vector
For <>:: size_type ix = 0; ix! = 10; + + ix
Ivec [ ix ] = ix;//disaster: ivec has no elements
The above procedure attempts to insert 10 new elements in ivec, and the element value is 0 to 9. However, here ivec is an empty vector object, and the subscript can only be used to obtain an existing element.
The correct writing of this loop should be:
For <>:: size_type ix = 0; ix! = 10; + + ix
Ivec. Push_back ( ix );//ok: add new element with value ix.
Warning: must be an existing element to index with a subscript operator. No elements are added when assigning an assignment through a subscript operation. Can only be used to understand the existing elements.

, memory management and efficiency

1. Use the reserve ( ) function to set capacity size in advance to avoid excessive capacity expansion operations resulting in inefficient efficiency.
One of the most compelling features of stl containers is that they can automatically grow to fit the data that you put into your data, as long as they aren't. To know this maximum, simply call the member function called max size. For vector and string, if more space is needed, increase the size in a similar realloc idea. The vector container supports random access, so it's implemented internally with dynamic arrays in order to improve efficiency. Always increase the internal buffer by the exponential boundary when applying the reserve ( ) to apply the specific size. When adding an element to an insert or push back, if the dynamic array memory isn't enough, dynamically reassign a new memory area of 1. 5 ~ 2 times the current size, and copy the contents of the original array to the past. So, in general, its access speed is similar to the general array, and the performance of the is reduced. Just as the code above tells you that. When the pop back operation is made, capacity doesn't decrease because the element in the vector container decreases and the size before the operation is maintained. For a vector container, if you've a large amount of data to push back, you should use the reserve ( ) function to set its capacity size in advance, otherwise the.
The reserve member function allows you to minimize the number of times you've to do that, so you can avoid the overhead of real allocation and the iterator pointer/reference failure. But before I explain why reserve can do so, let me briefly introduce the four related member functions sometimes confusing. In standard containers, only vector and string provide all of these functions.
( 1 ) the size ( ) tells you how many elements in your container. It doesn't tell you how much memory the container has allocated for it.
( 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 block of memory, not as many elements as possible. If you want to know how much memory there isn't occupied by a vector or string, you must subtract the size ( ) from capacity ( ). If size and capacity return the same value, there's no remaining space in the container, and the next insert ( via insert or push back ) will throw the above.
( 3 ) resize ( container:: size_type n ) forced the container to hold the n element. After the resize is called, 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, the newly constructed element is added to the end of the container. If n is greater than the current capacity, a redistribution occurs before the element is joined.
( 4 ) reserve ( container:: size_type n ) forces the container to change its capacity to at least n, and the provided n is less than the current size. This is generally forced to because capacity needs increased. ( if n is less than the current capacity, the vector ignores it, which doesn't do anything, string may reduce its capacity to size ( ) and n, but the size of the string doesn't change. In my experience, using reserve to trim extra capacity from one string is generally less than using"swap skills", which is the subject of terms 17. )
This profile indicates that there will be a redistribution when an element needs to be inserted and the container isn't capable of being plugged in, including the original memory allocation and recycling that they maintain, the copying and destructo & of objects, and the of the object. So the key to avoid redistribution is to use reserve as soon as possible to set the capacity of the container as large as possible, preferably after the container is constructed.
For example, suppose you want to create a vector <> that holds 1 1000 values. Don't use 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 during the loop. ( 10, there's nothing strange. Remember that the vector generally doubles the capacity when the occurs, and 1000 equals 210. )
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 won't happen in the loop.
The relationship between size and capacity allows us to predict when the insertion will cause a vector or string to be reassigned, and it can predict when I. For example, given this code,


string s;


...


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


s.push_back('x');


}





A call to push back doesn't cause an iterator, pointer, or reference to the string to fail because the capacity of the string is greater than its size. If you don't execute push back, the code makes an insert at any location in the string, and we can still guarantee that no redistribution occurs during the I.
Back to this clause, usually two cases use reserve to avoid unnecessary redistribution. The first available is when you're accurate or about how many elements will eventually appear in the container. In that case, like the vector code above, you simply reserve the appropriate amount of space. The second situation is to keep the maximum space you might need, and then, once you add full data, trim any extra capacity.
2. Use swap techniques to trim the vector excess space/memory.
There's a way to reduce it from the maximum capacity to the capacity it needs now. Doing so is often referred to as""( shrink to fit ). This method requires only one statement: Vector <> ( ivec ). Swap ( ivec ).
An expression vector <> ( ivec ) establishes a temporary vector that's a copy of the ivec: The copy constructor of the vector did this job. However, the copy constructor of the vector only allocates the memory required by the copied element, so this temporary vector doesn't have redundant capacity. And then we let the temporary vector and ivec exchange data, so we've done that, and ivec only has a fixed size of the temporary variable, and this temporary variable holds. At this point ( end of this statement ), the temporary vector is destroyed so that the memory used before ivec is released, and the.
3. The memory occupied by the stl vector is freed by the swap method.


template <class T> void ClearVector( vector<T>& v )


{ 


 vector<T>vtTemp;


 vtTemp.swap( v );


}





As if


 vector<int> v ;


 nums.push_back(1);


 nums.push_back(3);


 nums.push_back(2);


 nums.push_back(4);


 vector<int>().swap(v); 


/* 或者v.swap(vector<int>()); */


/*或者{ std::vector<int> tmp = v; v.swap(tmp); };//加大括号{ }是让tmp退出{ }时自动析构*/







, the behavior test of vector memory management member function

The c + + stl vector is widely used, but the management model for its memory has a variety of guesses, and the following code tests are used to unde & tand how their memory is managed, as follows:


#include <iostream>


#include <vector>


using namespace std;


int main()


{


vector<int> iVec;


cout <<"容器 大小为:" <<iVec.size() <<endl;


cout <<"容器 容量为:" <<iVec.capacity() <<endl;//1个元素, 容器容量为1


iVec.push_back(1);


cout <<"容器 大小为:" <<iVec.size() <<endl;


cout <<"容器 容量为:" <<iVec.capacity() <<endl;//2个元素, 容器容量为2


iVec.push_back(2);


cout <<"容器 大小为:" <<iVec.size() <<endl;


cout <<"容器 容量为:" <<iVec.capacity() <<endl;//3个元素, 容器容量为4


iVec.push_back(3);


cout <<"容器 大小为:" <<iVec.size() <<endl;


cout <<"容器 容量为:" <<iVec.capacity() <<endl;//4个元素, 容器容量为4


iVec.push_back(4);


iVec.push_back(5);


cout <<"容器 大小为:" <<iVec.size() <<endl;


cout <<"容器 容量为:" <<iVec.capacity() <<endl;//5个元素, 容器容量为8


iVec.push_back(6);


cout <<"容器 大小为:" <<iVec.size() <<endl;


cout <<"容器 容量为:" <<iVec.capacity() <<endl;//6个元素, 容器容量为8


iVec.push_back(7);


cout <<"容器 大小为:" <<iVec.size() <<endl;


cout <<"容器 容量为:" <<iVec.capacity() <<endl;//7个元素, 容器容量为8


iVec.push_back(8);


cout <<"容器 大小为:" <<iVec.size() <<endl;


cout <<"容器 容量为:" <<iVec.capacity() <<endl;//8个元素, 容器容量为8


iVec.push_back(9);


cout <<"容器 大小为:" <<iVec.size() <<endl;


cout <<"容器 容量为:" <<iVec.capacity() <<endl;//9个元素, 容器容量为16


/* vs2005/8 容量增长不是翻倍的,如 


 9个元素 容量9 


 10个元素 容量13 */


/* 测试effective stl中的特殊的交换 swap() */


cout <<"当前vector 的大小为:" <<iVec.size() <<endl;


cout <<"当前vector 的容量为:" <<iVec.capacity() <<endl;


vector<int>(iVec).swap(iVec);


cout <<"临时的vector<int>对象 的大小为:" <<(vector<int>(iVec)).size() <<endl;


cout <<"临时的vector<int>对象 的容量为:" <<(vector<int>(iVec)).capacity() <<endl;


cout <<"交换后,当前vector 的大小为:" <<iVec.size() <<endl;


cout <<"交换后,当前vector 的容量为:" <<iVec.capacity() <<endl;


return 0;


}







, the other member function of the vector.

C. Assign ( beg, end ).
Assign data in [ beg; end ) intervals to c.
C. Assign ( n, 20 ).
Assign an n copy to c.
C. At ( debugge ).
A out of range is thrown if the is out of range and the range is raised.
C. Back ( ).
Return to the last data and don't check that the data exists.
C. Front ( ).
Back to the ground.
Get_allocator
To return a copy using the co & tructor.
C. Rbegin ( ).
Back to the first data in a reverse queue.
C. Rend ( ).
Returns the next position of the last data in a reverse queue.
C. ~ vector <> ( ).
Destroy all data and release memory.

The following is a supplement to other users:

1, basic operation

( 1 ) header file # include <vector>.

( 2 ) the vector object is created, vector <> vec;

( 3 ) the tail I ert number: Vec. Push_back ( a ).

( 4 ) use a subscript access element, <<vec [ 0 ] <<endl; remember that subscript starts with 0.

( 5 ) using the iterator to access the element.


vector<int>::iterator it;


for(it=vec.begin();it!=vec.end();it++)


 cout<<*it<<endl;







( 6 ) I & ert an element: Vec. Insert ( e. G. Begin ( ) + I, a ); inserts a before I + 1 elements.

( 7 ) delete the element: Vec. Erase ( e. Begin ( ) + 2 ); delete 3 elements.

Vec. Erase ( e. G. Begin ( ) + I, vec, end ( ) + j ); delete interval [ I, j-1 ]; interval from 0.

( 8 ) vector size: vec, size ( );

( 9 ) empty: vec. Clear ( ).

2, the element of the vector can't only make int, double, string, or structure, but note: The structure is defined as global; otherwise, there will be an error. Here's a short code:


#include<stdio.h>


#include<algorithm>


#include<vector>


#include<iostream>


using namespace std;



typedef struct rect


{


 int id;


 int length;


 int width;



  //对于向量元素是结构体的,可在结构体内部定义比较函数,下面按照id,length,width升序排序。


  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 ) flip the element with reverse: Header file # include <algorithm>

Reve e ( e. Begin ( ), vec. End ( ) ); ( in vector, if two iterators are required in a function.

Always don't include.

( 2 ) sort with sort: # include <algorithm>,

Sort ( e. Begin ( ), vec. End ( ) ); ( default is in ascending order, ).

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

Define sort comparison functio &:


bool Comp(const int &a,const int &b)


{


 return a>b;


}






Call: sort ( e. Begin ( ), vec. End ( ), comp, and so on, in order to sort.

http://www. Jb51. net/article/44234. Htm.




Copyright © 2011 Dowemo All rights reserved.    Creative Commons   AboutUs