Skip to content

[C++] STL 中的 vector 筆記

vectorC++ 標準模板函式庫Standard Template Library, STL)中的序列容器(Sequence Container),跟 Array 十分相似,但是可以在我們儲存更多元素的時候自動擴展空間,在寫程式時利用起來十分便利。

本篇筆記依現有常用的 vector 容器其寫法,做一個簡單的整理。以下依序介紹:

  • begin()
  • end()
  • size()
  • capacity()
  • empty()
  • front()
  • back()
  • push_back()
  • pop_back()
  • insert()
  • erase()
  • clear()

begin()

begin() 函式會返回一個指向 vector 開頭的迭代器,可以用來遍歷整個 vector。不過,等下一小節 end() 一同示範。

#include <iostream>
#include <vector>
using namespace std;


int main() {
    // Init
    vector<int> v;
    for (int i=0; i<10; i++) {
        v.push_back(i*10);
    }
    
    // begin
    vector<int>::iterator it = v.begin();
    cout << *it << endl;

    return 0;
}



Output:

0

由確實印出了 vector 中第一個元素的值可以確認,begin() 返回的迭代器確實指向 vector 的開頭。


end()

begin() 相對,end() 指向 vector 尾端(不是最後一項)。在遍歷中可以拿來當迴圈的結束點。

#include <iostream>
#include <vector>
using namespace std;


int main() {
    // Init
    vector<int> v;
    for (int i=0; i<10; i++) {
        v.push_back(i*10);
    }
    
    // begin
    vector<int>::iterator it = v.begin();
    
    // while
    while (it != v.end()) {
        cout << *it << endl;
        it++;
    }

    return 0;
}



Output:

0
10
20
30
40
50
60
70
80
90

size()

size() 顧名思義,就是拿來取 vector 長度的。

#include <iostream>
#include <vector>
using namespace std;


int main() {
    // Init
    vector<int> v;
    for (int i=0; i<10; i++) {
        v.push_back(i*10);
    }
    
    // size
    cout << "vector size: " << v.size() << endl;

    return 0;
}



Output:

vector size: 10

capacity()

capacity(),直翻的話就是容量,不過跟 size() 得到的值是不同的。size() 可以理解為當前 vector 的元素數量、capacity() 則是此vector 所預留的空間大小。

以下用個範例程式碼查看動態增加元素的變化。

#include <iostream>
#include <vector>
using namespace std;


int main() {
    // Init
    vector<int> v;

    for (int i=0; i<20; i++) {
        v.push_back(i*10);
        printf("v[%d]=%d, size=%lu, capacity=%lu\n", i, v[i], v.size(), v.capacity());
    }
    
    return 0;
}



Output:

v[0]=0, size=1, capacity=1
v[1]=10, size=2, capacity=2
v[2]=20, size=3, capacity=4
v[3]=30, size=4, capacity=4
v[4]=40, size=5, capacity=8
v[5]=50, size=6, capacity=8
v[6]=60, size=7, capacity=8
v[7]=70, size=8, capacity=8
v[8]=80, size=9, capacity=16
v[9]=90, size=10, capacity=16
v[10]=100, size=11, capacity=16
v[11]=110, size=12, capacity=16
v[12]=120, size=13, capacity=16
v[13]=130, size=14, capacity=16
v[14]=140, size=15, capacity=16
v[15]=150, size=16, capacity=16
v[16]=160, size=17, capacity=32
v[17]=170, size=18, capacity=32
v[18]=180, size=19, capacity=32
v[19]=190, size=20, capacity=32

可以發現,vector 真的是動態增加空間的。每次只要一儲存滿 vector,便會自動替我們擴展可用空間,非常便利。


empty()

empty() 非常單純,就是檢查 vector 是否為空。

#include <iostream>
#include <vector>
using namespace std;


int main() {
    // Init
    vector<int> v;
    cout << "Before push_back(): " << v.empty() << endl;

    for (int i=0; i<10; i++) {
        v.push_back(i*10);
    }

    cout << "After push_back(): " << v.empty() << endl;

    return 0;
}



Output:

Before push_back(): 1
After push_back(): 0

front()

回傳 vector 第一項的元素。

#include <iostream>
#include <vector>
using namespace std;


int main() {
    // Init
    vector<int> v;
    for (int i=0; i<10; i++) {
        v.push_back(i*10);
    }

    // front()
    cout << "front(): " << v.front() << endl;

    return 0;
}



Output:

front(): 0

back()

回傳 vector 最後一項的元素。

#include <iostream>
#include <vector>
using namespace std;


int main() {
    // Init
    vector<int> v;
    for (int i=0; i<10; i++) {
        v.push_back(i*10);
    }

    // back()
    cout << "back(): " << v.back() << endl;

    return 0;
}



Output:

back(): 90

push_back()

其實前面好像出現很多次了 … 我寫著寫著突然發現 XDDD

真的完全沒注意到這是後面才要寫的函式。

簡單來講,push_back() 可以讓我們在 vector 尾端添加新的值。

#include <iostream>
#include <vector>
using namespace std;


int main() {
    // Init
    vector<int> v;
    for (int i=0; i<3; i++) {
        v.push_back(i*10);
        cout << v[i] << endl;
    }

    // Divider
    cout << "============================" << endl;

    // push_back()
    v.push_back(1000);

    for (auto n: v) {
        cout << n << endl;
    }

    return 0;
}



Output:

0
10
20
============================
0
10
20
1000

pop_back()

push_back() 剛好相反,pop_back() 是刪除最後一項的元素。

#include <iostream>
#include <vector>
using namespace std;


int main() {
    // Init
    vector<int> v;
    for (int i=0; i<3; i++) {
        v.push_back(i*10);
        cout << v[i] << endl;
    }

    // Divider
    cout << "============================" << endl;

    // pop_back()
    v.pop_back();

    for (auto n: v) {
        cout << n << endl;
    }

    return 0;
}



Output:

0
10
20
============================
0
10

insert()

若是要在 vector 中插入新的元素,可以使用 insert() 來處理。insert() 函式的使用方法如下:

v.insert(position, n, val)
  • position: 插入元素的 index 值
  • n: 元素插入次數
  • val: 插入的元素值

以下看個簡單的範例:

#include <iostream>
#include <vector>
using namespace std;


int main() {
    // Init
    vector<int> v;
    for (int i=0; i<10; i++) {
        v.push_back(i*10);
        cout << v[i] << endl;
    }

    // Divider
    cout << "============================" << endl;

    // insert()
    v.insert(v.begin()+3, 5, 100);

    // Print
    for (auto n: v) {
        cout << n << endl;
    }

    return 0;
}



Output:

0
10
20
30
40
50
60
70
80
90
============================
0
10
20
100
100
100
100
100
30
40
50
60
70
80
90

可以發現在插入元素後,vector 內的元素多出了好幾個 100,這就是我們要的效果。


erase()

insert() 不同,erase() 是刪除元素,需要使用迭代器指定刪除的元素或位置,同時也會返回指向刪除元素下一元素的迭代器

簡單看個範例:

#include <iostream>
#include <vector>
using namespace std;


int main() {
    // Init
    vector<int> v;
    for (int i=0; i<10; i++) {
        v.push_back(i*10);
        cout << v[i] << " ";
    }
    cout << endl;

    // erase()
    vector<int>::iterator it;
    for (it=v.begin(); it!=v.end(); it++) {
        if (*it == 20) {
            it = v.erase(it);
        }
    }

    // Print
    for (auto n: v) {
        cout << n << " ";
    }
    cout << endl;

    return 0;
}



Output:

0 10 20 30 40 50 60 70 80 90 
0 10 30 40 50 60 70 80 90 

可以發現我們確實刪除了 20 這個元素。


clear()

clear() 可說是最單純的函式了,功能就是清空整個 vector。

#include <iostream>
#include <vector>
using namespace std;


int main() {
    // Init
    vector<int> v;
    for (int i=0; i<10; i++) {
        v.push_back(i*10);
        cout << v[i] << " ";
    }
    cout << endl;

    // clear()
    v.clear();

    // Print
    for (auto n: v) {
        cout << n << " ";
    }

    return 0;
}



Output:

0 10 20 30 40 50 60 70 80 90 

可以看出,我們只印出了當初將元素放入 vector 中的部分,在使用 clear() 清空 vector 後,我們便印不出任何元素了 —— 因為 vector 已經清空了。


References


Read More

Tags:

Leave a Reply