1. 程式人生 > 其它 >C++ STL vector刪除元素的幾種方式

C++ STL vector刪除元素的幾種方式

轉載於:C++ STL vector刪除元素的幾種方式(超級詳細) (biancheng.net)

前面提到,無論是向現有 vector 容器中訪問元素、新增元素還是插入元素,都只能藉助 vector 模板類提供的成員函式,但刪除 vector 容器的元素例外,完成此操作除了可以藉助本身提供的成員函式,還可以藉助一些全域性函式。

基於不同場景的需要,刪除 vecotr 容器的元素,可以使用表 1 中所示的函式(或者函式組合)。

表 1 刪除 vector 容器元素的幾種方式
函式功能
pop_back() 刪除 vector 容器中最後一個元素,該容器的大小(size)會減 1,但容量(capacity)不會發生改變。
erase(pos) 刪除 vector 容器中 pos 迭代器指定位置處的元素,並返回指向被刪除元素下一個位置元素的迭代器。該容器的大小(size)會減 1,但容量(capacity)不會發生改變。
swap(beg)、pop_back() 先呼叫 swap() 函式交換要刪除的目標元素和容器最後一個元素的位置,然後使用 pop_back() 刪除該目標元素。
erase(beg,end) 刪除 vector 容器中位於迭代器 [beg,end)指定區域內的所有元素,並返回指向被刪除區域下一個位置元素的迭代器。該容器的大小(size)會減小,但容量(capacity)不會發生改變。
remove() 刪除容器中所有和指定元素值相等的元素,並返回指向最後一個元素下一個位置的迭代器。值得一提的是,呼叫該函式不會改變容器的大小和容量。
clear() 刪除 vector 容器中所有的元素,使其變成空的 vector 容器。該函式會改變 vector 的大小(變為 0),但不是改變其容量。

下面就表 1 中羅列的這些函式,一一講解它們的具體用法。

pop_back()成員函式的用法非常簡單,它不需要傳入任何的引數,也沒有返回值。舉個例子
#include <vector>
#include <iostream>
using namespace std;

int main()
{
    vector<int>demo{ 1,2,3,4,5 };
    demo.pop_back();
    //輸出 dmeo 容器新的size
    cout << "size is :" << demo.size() << endl;
    //輸出 demo 容器新的容量
    cout << "capacity is :" << demo.capacity() << endl;
    for (int i = 0; i < demo.size(); i++) {
        cout << demo[i] << " ";
    }
    return 0;
}

  


執行結果為:

size is :4
capacity is :5
1 2 3 4

可以發現,相比原 demo 容器,新的 demo 容器刪除了最後一個元素 5,容器的大小減了 1,但容量沒變。

如果想刪除 vector 容器中指定位置處的元素,可以使用erase()成員函式,該函式的語法格式為:

iterator erase (pos);

其中,pos 為指定被刪除元素位置的迭代器,同時該函式會返回一個指向刪除元素所在位置下一個位置的迭代器。

下面的例子演示了 erase() 函式的具體用法:
#include <vector>
#include <iostream>
using namespace std;

int main()
{
    vector<int>demo{ 1,2,3,4,5 };
    auto iter = demo.erase(demo.begin() + 1);//刪除元素 2
    //輸出 dmeo 容器新的size
    cout << "size is :" << demo.size() << endl;
    //輸出 demo 容器新的容量
    cout << "capacity is :" << demo.capacity() << endl;
    for (int i = 0; i < demo.size(); i++) {
        cout << demo[i] << " ";
    }
    //iter迭代器指向元素 3
    cout << endl << *iter << endl;
    return 0;
}

執行結果為:

size is :4
capacity is :5
1 3 4 5
3

通過結果不能看出,erase() 函式在刪除元素時,會將刪除位置後續的元素陸續前移,並將容器的大小減 1。

另外,如果不在意容器中元素的排列順序,可以結合swap()和pop_back()函式,同樣可以實現刪除容器中指定位置元素的目的。

注意,swap() 函式在標頭檔案<algorithm><utility>中都有定義,使用時引入其中一個即可。

例如:
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
    vector<int>demo{ 1,2,3,4,5 };
    //交換要刪除元素和最後一個元素的位置
    swap(*(std::begin(demo)+1),*(std::end(demo)-1));//等同於 swap(demo[1],demo[4])
   
    //交換位置後的demo容器
    for (int i = 0; i < demo.size(); i++) {
        cout << demo[i] << " ";
    }
    demo.pop_back();
    cout << endl << "size is :" << demo.size() << endl;
    cout << "capacity is :" << demo.capacity() << endl;
    //輸出demo 容器中剩餘的元素
    for (int i = 0; i < demo.size(); i++) {
        cout << demo[i] << " ";
    }
    return 0;
}

執行結果為:

1 5 3 4 2
size is :4
capacity is :5
1 5 3 4


當然,除了刪除容器中單個元素,還可以刪除容器中某個指定區域內的所有元素,同樣可以使用erase()成員函式實現。該函式有 2 種基本格式,前面介紹了一種,這裡使用另一種:

iterator erase (iterator first, iterator last);

其中 first 和 last 是指定被刪除元素區域的迭代器,同時該函式會返回指向此區域之後一個位置的迭代器。

舉個例子:
#include <vector>
#include <iostream>
using namespace std;

int main()
{
    std::vector<int> demo{ 1,2,3,4,5 };
    //刪除 2、3
    auto iter = demo.erase(demo.begin()+1, demo.end() - 2);
    cout << "size is :" << demo.size() << endl;
    cout << "capacity is :" << demo.capacity() << endl;

    for (int i = 0; i < demo.size(); i++) {
        cout << demo[i] << " ";
    }
    return 0;
}

執行結果為:

size is :3
capacity is :5
1 4 5

可以看到,和刪除單個元素一樣,刪除指定區域內的元素時,也會將該區域後續的元素前移,並縮小容器的大小。

如果要刪除容器中和指定元素值相同的所有元素,可以使用remove()函式,該函式定義在<algorithm>標頭檔案中。例如:
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
    vector<int>demo{ 1,3,3,4,3,5 };
    //交換要刪除元素和最後一個元素的位置
    auto iter = std::remove(demo.begin(), demo.end(), 3);

    cout << "size is :" << demo.size() << endl;
    cout << "capacity is :" << demo.capacity() << endl;
    //輸出剩餘的元素
    for (auto first = demo.begin(); first < iter;++first) {
        cout << *first << " ";
    }
    return 0;
}

執行結果為:

size is :6
capacity is :6
1 4 5

注意,在對容器執行完 remove() 函式之後,由於該函式並沒有改變容器原來的大小和容量,因此無法使用之前的方法遍歷容器,而是需要向程式中那樣,藉助 remove() 返回的迭代器完成正確的遍歷。

remove() 的實現原理是,在遍歷容器中的元素時,一旦遇到目標元素,就做上標記,然後繼續遍歷,直到找到一個非目標元素,即用此元素將最先做標記的位置覆蓋掉,同時將此非目標元素所在的位置也做上標記,等待找到新的非目標元素將其覆蓋。因此,如果將上面程式中 demo 容器的元素全部輸出,得到的結果為1 4 5 4 3 5

另外還可以看到,既然通過 remove() 函式刪除掉 demo 容器中的多個指定元素,該容器的大小和容量都沒有改變,其剩餘位置還保留了之前儲存的元素。我們可以使用 erase() 成員函式刪掉這些 "無用" 的元素。

比如,修改上面的程式:
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
    vector<int>demo{ 1,3,3,4,3,5 };
    //交換要刪除元素和最後一個元素的位置
    auto iter = std::remove(demo.begin(), demo.end(), 3);
    demo.erase(iter, demo.end());
    cout << "size is :" << demo.size() << endl;
    cout << "capacity is :" << demo.capacity() << endl;
    //輸出剩餘的元素
    for (int i = 0; i < demo.size();i++) {
        cout << demo[i] << " ";
    }
    return 0;
}

執行結果為:

size is :3
capacity is :6
1 4 5

remove()用於刪除容器中指定元素時,常和 erase() 成員函式搭配使用。


如果想刪除容器中所有的元素,則可以使用clear()成員函式,例如:
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
    vector<int>demo{ 1,3,3,4,3,5 };
    //交換要刪除元素和最後一個元素的位置
    demo.clear();
    cout << "size is :" << demo.size() << endl;
    cout << "capacity is :" << demo.capacity() << endl;
    return 0;
}

執行結果為:

size is :0
capacity is :6