C++中的vector

1. 簡介

在c++中,vector是一個十分有用的容器
作用:它能夠像容器一樣存放各種類型的對象,簡單地說,vector是一個能夠存放任意類型動態數組,能夠增加和壓縮數據。vector在C++標準模板庫中的部分內容,它是一個多功能的,能夠操作多種數據結構和算法的模板類函數庫

2. 使用注意

1、如果你要表示的向量長度較長(需要爲向量內部保存很多數),容易導致內存泄漏,而且效率會很低;

2、Vector作爲函數的參數或者返回值時,需要注意它的寫法:

double Distance(vector<int>&a, vector<int>&b)   // 其中的 “&” 絕對不能少!!!

3. 基本操作

3.1 頭文件

#include <vector>

3.2 創建vector對象

vector<int> v1;         // vec是一個空int類型的vector對象,執行默認初始化
vector<int> v2(v1);     // v2包含有v1所有元素的副本
vector<int> v2 = v1;    // 等價於上面這條語句
vector<int> v3(n, val); // v3包含了n個int類型值爲val的元素
vector<int> v4(n);      // v4包含了n個重複地執行了值初始化的對象
vector<int> v5 {1, 2, 3}// v5是一個含有3個int類型的vector,其中每個元素被賦予相應的初始值
vector<int> v5 = {1, 2, 3}// 與上面語句等價

3.3 尾部插入元素 push_back()

vec.push_back(1);

3.4 尾部刪除元素 pop_back()

vec.pop_back();

3.5 使用下標訪問元素[]

cout << vec[0] << endl;		// 記住下標是從0開始的。

3.6 使用at()方法訪問

cout << vec.at(0) << endl;	// 使用at方法訪問,如果vector爲空,會拋出異常,下標法則不會(效率更高)

3.7 使用迭代器訪問元素

vector<int>::iterator it;
for(it=vec.begin(); it!=vec.end(); it++)
cout << *it << endl;

3.8 插入元素 insert()

vec.insert(vec.begin()+i, a);	// 在第i+1個元素前面插入a;

3.9 刪除元素 erase()

vec.erase(vec.begin()+2);		// 刪除第3個元素
vec.erase(vec.begin()+i, vec.end()+j);	// 刪除區間[i,j-1];區間從0開始

注意:size() 表示vector實際存儲元素個數,capacity() 表示vector容量大小,即分配的存儲空間的大小。舉例記憶:一間房間有100個座位(capacity),當前只坐了40人(size)。

3.10 vectors實際存儲元素個數 size()

vec.size();

3.11 vectors容量大小 capacity()

vec.capacity();

3.12 清空 clear()

vec.clear();

3.13 使用 reverse() 將元素翻轉

#include <algorithm>
reverse(vec.begin(), vec.end());	// 將元素翻轉,即逆序排列
// (在vector中,如果一個函數中需要兩個迭代器,一般後一個都不包含) ? 沒看懂

3.14 swap() 交換 vector

vector<int> a(3, 100);	// three ints with a value of 100
vector<int> b(5, 100);  // five ints with a value of 200
a.swap(b);              // swap two vectors

3.15 sort() 排序

#include <algorithm>
sort(vec.begin(),vec.end());	// 默認是按升序排列,即從小到大

// 可以通過重寫排序比較函數按照降序比較,如下定義排序比較函數:
bool Comp(const int &a,const int &b) {
    return a>b;
}
// 調用時:sort(vec.begin(),vec.end(),Comp); 這樣就降序排序。 

注意:vector提供了兩個方法 resize()reserve() 分別對 size()capacity() 進行操作.
Reference:C++基礎篇 – vector的resize函數和reserve函數

3.16 改變vector的大小 resize()

vector<int> vec;
vec.resize(5);	   // 將空vector數組大小更改爲5
vec.resize(8, 35); // 將vec數組大小更改爲8,並將新增加的元素,初始化爲指定值35
for (int i=0;i<vec.size();i++)
    std::cout << ' ' << vec[i];
// 結果爲:0 0 0 0 0 35 35 35
1、resize方法被用來改變vector的大小,即vector中元素的數量,我們可以說,resize方法改變了容器的大小,且創建了容器中的對象;

2、如果resize中所指定的n小於vector中當前的元素數量,則會刪除vector中多於n的元素,使vector得大小變爲n;

3、如果所指定的n大於vector中當前的元素數量,則會在vector當前的尾部插入適量的元素,使得vector的大小變爲n,在這裏,如果爲resize方法指定了第二個參數,則會把後插入的元素值初始化爲該指定值,如果沒有爲resize指定第二個參數,則會把新插入的元素初始化爲默認的初始值;

4、如果resize所指定的n不僅大於vector中當前的元素數量,還大於vector當前的capacity容量值時,則會自動爲vector重新分配存儲空間;

3.17 改變vector容量的大小 reserve()

#include <iostream>
#include <vector>
using namespace std;
int main() {
	vector<int> vect;
	vect.reserve(5);
 
	vect.push_back(1);
	vect.push_back(2);
	vect.push_back(3);
	vect.push_back(4);
 
	cout << vect.size() << endl;
	cout << vect.capacity() << endl;
 
	vect.push_back(5);                               
	vect.push_back(6);    // 插入兩個元素,此時vect的大小大於之前分配的容量5
	
	cout << "size1 = " << vect.size() << endl; 
	cout << "capacity1 = " << vect.capacity() << endl;
 
	vect.push_back(7);
	vect.push_back(8);    // 在插入兩個元素,和上面的結果進行對比,會有意外收穫
	cout << "size1_1 = " << vect.size() << endl; 
	cout << "capacity1_1 = " << vect.capacity() << endl;
 
	vect.reserve(3);      // 當程序執行到此處時,vect的容量大小一定是大於3的
 
	cout << "size2 = " << vect.size() << endl;
	cout << "capacity2 = " << vect.capacity() << endl;
 
	vect.reserve(12);
 
	cout << "size3 = " << vect.size() << endl;
	cout << "capacity3 = " << vect.capacity() << endl;
	return 0;
}
/**輸出結果
4
5
size1 = 6
capacity1 = 10
size1_1 = 8
capacity1_1 = 10
size2 = 8
capacity2 = 10
size3 = 8
capacity3 = 12
*/
1、reserve方法被用來重新分配vector的容量大小;

2、只有當所申請的容量大小n大於vector的當前容量時,纔會重新爲vector分配存儲空間;

3、reserve方法對於vector的大小(即size)沒有任何影響;

4.一維數組的使用

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
int main() {
    vector<int> a;			 // 創建一個int類型的vector數組 a
    a.push_back(1);	
    a.push_back(2); 		 // 把1和2壓入vector
    cout << a[0] << endl;	 // 下標法訪問數組,輸出爲1
    cout << a.at(1) << endl; // at法訪問數組,輸出爲2
    // at和下標法的區別是,如果vector爲空,調at會拋出異常,而operator[]索引的行爲爲定義
    
    // 使用迭代器訪問數組元素
    for(vector<int>::iterator it = a.begin(); it != a.end(); it++)
        cout << *it << endl;
}

5.二維數組的使用

這裏簡單敘述一下C++ 構建二維動態數組

int **p;
p = new int*[10];    // 注意,int*[10]表示一個有10個元素的指針數組
for (int i = 0; i < 10; ++i)
    p[i] = new int[5];

1. 初始化

(1)利用Vector的push_back函數

vector<vector<int> > vec;

vector<int> a;
a.push_back(1);
a.push_back(2);
a.push_back(3);

vector<int> b;
b.push_back(4);
b.push_back(5);
b.push_back(6);

vec.push_back(a);
vec.push_back(b);

(2)先定義好二維數組結構,再直接賦值

// 得到一個5行3列的數組
// 由vector實現的二維數組,可以通過resize()的形式改變行、列值
int i, j;
vector<vector<int> > array(5);
for (i = 0; i < array.size(); i++)
    array[i].resize(3);

for(i = 0; i < array.size(); i++)
    for (j = 0; j < array[0].size();j++)
        array[i][j] = (i+1)*(j+1);

2. 遍歷

(1)利用迭代器

void reverse_with_iterator(vector<vector<int>> vec) {
    if (vec.empty()) {
        cout << "The vector is empty!" << endl;
        return;
    }

    vector<int>::iterator it;
    vector<vector<int>>::iterator iter;
    vector<int> vec_tmp;

    cout << "Use iterator : " << endl;
    for(iter = vec.begin(); iter != vec.end(); iter++) {
        vec_tmp = *iter;
        for(it = vec_tmp.begin(); it != vec_tmp.end(); it++)
            cout << *it << " ";
        cout << endl;
    }
}

(2)得到行、列大小,利用下標進行遍歷

void reverse_with_index(vector<vector<int>> vec) {
    if (vec.empty()) {
        cout << "The vector is empty!" << endl;
        return;
    }

    int i,j;
    cout << "Use index : " << endl;
    for (i = 0; i < vec.size(); i++) {		// 注意,當內層每個vector沒有存滿時,這個樣會出錯
        for(j = 0; j < vec[0].size(); j++)
            cout << vec[i][j] << " ";
        cout << endl;
    }
}

注意: vector的元素不僅僅可以是int,double,string,還可以是結構體,但是要注意:結構體要定義爲全局的,否則會出錯。

#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;
}

6. begin()end()front()back()區別

  • begin()

函數原型:

iterator begin();
const_iterator begin();

功能:返回一個當前vector容器中起始元素的迭代器

  • end()

函數原型:

iterator end();
const_iterator end();

功能:返回一個當前vector容器中末尾元素的迭代器

  • front()

函數原型:

reference front();
const_reference front();

功能: 返回當前vector容器中起始元素的引用

  • back()

函數原型:

reference back();
const_reference back();

功能: 返回當前vector容器中末尾元素的引用

例題


#include <iostream>
#include <vector>
using namespace std;
int main() {
	vector<char> v1;
	vector<char>::iterator iter1;
	vector<char>::iterator iter2;
	v1.push_back('m');
	v1.push_back('n');
	v1.push_back('o');
	v1.push_back('p');
 
	cout << "v1.front() = " << v1.front() << endl;
	cout << "v1.back() = " << v1.back() << endl;
 
	iter1 = v1.begin();
	cout << *iter1 << endl;
	iter2 = v1.end()-1; // 注意v1.end()指向的是最後一個元素的下一個位置,所以訪問最後一個元素
                        // 的正確操作爲:v1.end() - 1;
	cout << *iter2 << endl;
	return 0;
}

/* 
最後輸出結果:
v1.front() = m
v1.back() = p
m
p
*/

7. resize()reserve()

8. Reference

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章