最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++從序列容器中刪除元素的四種方法

 更新時間:2025年03月24日 11:16:14   作者:Lion 萊恩呀  
刪除元素的方法在序列容器和關聯(lián)容器之間是非常不同的,在序列容器中,vector 和 string 是最常用的,但這里也會介紹 deque 和 list 以供全面了解,盡管在一般情況下可能不會使用它們,本文將詳細給大家介紹一下C++從序列容器中刪除元素的四種方法,需要的朋友可以參考下

一、簡介

本文討論從集合中刪除元素的STL算法。從C++集合中刪除一個元素可能不復雜,也可能有點復雜。

刪除元素的方法在序列容器和關聯(lián)容器之間是非常不同的。在序列容器中,vector 和 string 是最常用的。但這里也會介紹 deque 和 list 以供全面了解,盡管在一般情況下可能不會使用它們。

至少有四種方法可以指定從任何容器中刪除哪些值:

  1. 在給定位置(或在兩個給定位置之間)刪除元素;
  2. 刪除等于某個值的元素;
  3. 刪除滿足某個謂詞的元素
  4. 以及刪除重復項。

下面來看看如何在STL序列容器中實現(xiàn)這四種命令。

二、移除給定位置的元素

這是最簡單的方法。如果是一個序列容器,可以通過調(diào)用erase。比如:

c.erase(position);

要移除由迭代器firstlast組成的子范圍中的元素,可以這么調(diào)用:

c.erase(first, last);

與STL中迭代器表示的所有范圍一樣,子范圍包括first,而不包括last。last指向“past-the-end”元素,類似于容器的結束迭代器。

注意,對于vector和string,所有指向被移除對象所在位置和之后元素的迭代器都無效。因為所有這些元素都被erase函數(shù)調(diào)用移除了。

對于deque來說,會有一點點不同:參考cppreference.com,所有迭代器和引用都無效,除非被刪除的元素位于容器的末尾或開頭,在這種情況下,只有迭代器和對被刪除元素的引用無效。

  • 如果刪除的元素位于deque的中間位置,則所有指向該元素以及之后位置的迭代器和引用都會失效。
  • 如果刪除的是末尾元素,那么僅僅指向這個末尾元素的迭代器和引用會失效,其余保持有效。
  • 如果刪除的是開頭元素,同樣只有指向這個開頭元素的迭代器和引用會失效。

erase很簡單,只是熱身。下面還有復雜的,接著閱讀學習吧。

三、移除與某個值相等的元素

3.1、序列容器vector、deque、string

這些容器沒有刪除值的方法,因此需要使用std::remove算法。該算法取一個要刪除的范圍和一個值,并上移所有要保留的元素。

例如,在這個整數(shù)范圍內(nèi)調(diào)用std::remove并帶值42,會有以下行為:

注意,在范圍末尾剩下的元素的值是未指定的。盡管有些實現(xiàn)可以將最初位于集合末尾的元素保留下來,但這是不可靠的。

要記住,在STL的設計中,算法只與迭代器交互,而不直接與容器交互,因此容器并不知道算法的效果。例如,它的size并沒有縮小。

為了有效地從集合中刪除元素,需要使用在本文前面講到的erase方法。為此,要注意到std::remove返回一個迭代器,該迭代器指向不應被刪除的元素范圍內(nèi)的“past-the-end”元素。即,要刪除的元素位于std::remove返回的迭代器定義的范圍和集合的末尾。

因此,要有效地從vector、deque或string對象中刪除值,可以這樣寫:

v.erase(std::remove(begin(v), end(v), 42), end(v));

3.2、封裝成模板方法

這是C++的習慣用法,如果在代碼中遇到它,必須知道。但是,坦白地講,不覺得用這么多代碼來表達這么簡單的事情有點多嗎?難道不喜歡像下面這樣寫嗎?

v.remove(42);
// or
v.erase(42);

也可以給它添加一些重載來操作deque和string對象:

template<typename T>
void erase(std::deque<T>& deque, T const& value)
{
    deque.erase(std::remove(begin(deque), end(deque), value), end(deque));
}

void erase(std::string& string, char letter)
{
    string.erase(std::remove(begin(string), end(string), letter), end(string));
}

非常建議實現(xiàn)這些輔助函數(shù),特別是對于最常用的vector。這可以避免標準習慣用法所帶來的迭代器的糾纏。

甚至在C++標準中,就有學者提出了一個增加這種泛型函數(shù)的建議。很遺憾的是,它還沒有在C++ 17中實現(xiàn)。

3.3、list的remove成員函數(shù)

為了全面起見,這里提一下要從list中刪除一個元素,有一個叫做remove的方法,例如:

l.remove(42);

由于它不提供隨機訪問迭代器,在列表上使用std::remove算法會使列表變得比現(xiàn)在更慢。

四、刪除滿足謂詞的元素

前面已經(jīng)看到了如何從序列容器中刪除所有等于某個值的元素,比如42。那么,如何移除滿足謂詞func的元素?其實,這完全一樣,只是需要使用 remove_if 而不是 remove。

所以只需要替換:

  • removeremove_if
  • 42為func。
std::remove_if(begin(string), end(string), func)

和上一節(jié)一樣。依然建議編寫一個名為erase_if的自由函數(shù),以避免大量迭代器的出現(xiàn);并且list同樣有一個名為remove_if的成員方法。因此,為了遵循“不要重復”的原則和避免文章篇幅過長,這里不再對remove_if進行更多討論。

五、從序列容器中刪除重復項

從序列容器中刪除重復項的STL算法是std::unique。但是要注意!unique只刪除相鄰的重復項,而不刪除整個集合中的重復項。它具有線性復雜度。

除此之外,unique和remove非常相似。它只壓縮集合的元素,而不能改變?nèi)萜鞅旧韘ize。因此,需要在容器上調(diào)用erase才能有效地刪除重復項:

vector.erase(std::unique(begin(v), end(v)), end(v));

remove一樣,封裝一個方便的函數(shù)是必要的:

template<typename T>
void unique(std::vector<T>& vector)
{
    vector.erase(std::unique(begin(vector), end(vector)), end(vector));
}

template<typename T>
void unique(std::deque<T>& deque)
{
    deque.erase(std::unique(begin(deque), end(deque)), end(deque));
}

void unique(std::string& string)
{
    string.erase(std::unique(begin(string), end(string)), end(string));
}

remove類似,std::list有一個unique的成員方法。

六、總結

這就是C++中從序列容器中刪除元素的方法。

在C++中,從序列容器中刪除元素的方法多種多樣,每種方法都有其適用的場景和使用方式。

  1. 移除給定位置的元素:可以使用erase方法,通過指定要刪除的元素位置或者給定范圍的迭代器來實現(xiàn)。

  2. 移除與某個值相等的元素:對于vector、dequestring等序列容器,可以使用std::remove算法,并結合erase方法來刪除指定值的元素;或者封裝成模板函數(shù)來簡化操作。

  3. 刪除滿足謂詞的元素:使用std::remove_if算法結合erase方法,可以刪除滿足指定謂詞條件的元素。

  4. 從序列容器中刪除重復項:利用std::unique算法可以刪除相鄰的重復項,但需要注意該算法只刪除相鄰的重復項,并且不能改變?nèi)萜鞯拇笮?,需要配?code>erase方法來實現(xiàn)刪除整個容器中的重復項。

以上就是C++從序列容器中刪除元素的四種方法的詳細內(nèi)容,更多關于C++序列容器刪除元素的資料請關注腳本之家其它相關文章!

相關文章

  • C++ STL標準庫std::vector的使用詳解

    C++ STL標準庫std::vector的使用詳解

    vector 是表示可以改變大小的數(shù)組的序列容器,本文主要介紹了C++ STL標準庫std::vector的使用詳解,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C語言模式實現(xiàn)C++繼承和多態(tài)的實例代碼

    C語言模式實現(xiàn)C++繼承和多態(tài)的實例代碼

    本篇文章主要介紹了C語言模式實現(xiàn)C++繼承和多態(tài)的實例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • c++學習之構造函數(shù)

    c++學習之構造函數(shù)

    類多么重要我就不多說了,只講講學習,因為個人認為類的學習無論從概念的理解還是實際代碼的編寫相對其他C兼容向的代碼都是比較有難度的, 對于以前學C 的人來說這才是真正的新概念和內(nèi)容,STL其實還比較好理解,不就是一個更大的函數(shù)庫和代碼可以使用嘛。
    2015-06-06
  • C語言實現(xiàn)打印九九乘法表的四種方式小結

    C語言實現(xiàn)打印九九乘法表的四種方式小結

    這篇文章主要為大家介紹了C語言實現(xiàn)打印九九乘法表的四種方式,文中的示例代碼講解詳細,簡潔易懂,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-07-07
  • C++中const char*、char const*、char * const三者的區(qū)別

    C++中const char*、char const*、char * const三者的區(qū)別

    這篇文章主要介紹了C++中const char*、char const*、char * const三者的區(qū)別,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • C語言中break與continue的用法和區(qū)別詳解

    C語言中break與continue的用法和區(qū)別詳解

    當我們使用while或for循環(huán)時,如果想提前結束循環(huán)(在不滿足結束條件的情況下結束循環(huán)),可以使用break或continue關鍵字,這篇文章主要給大家介紹了關于C語言中break與continue的用法和區(qū)別的相關資料,需要的朋友可以參考下
    2021-10-10
  • 設計模式中的備忘錄模式解析及相關C++實例應用

    設計模式中的備忘錄模式解析及相關C++實例應用

    這篇文章主要介紹了設計模式中的備忘錄模式解析及相關C++實例應用,備忘錄模式也經(jīng)常被用來在命令模式中維護可以撤銷(Undo)操作的狀態(tài),需要的朋友可以參考下
    2016-03-03
  • 使用C/C++調(diào)用libcurl調(diào)試消息的方式

    使用C/C++調(diào)用libcurl調(diào)試消息的方式

    在使用 C/C++ 調(diào)用 libcurl 進行 HTTP 請求時,有時我們需要查看請求的/應答消息的內(nèi)容(包括請求頭和請求體)以方便調(diào)試,libcurl 提供了多種方法來捕獲和輸出這些信息,本文介紹具體的使用方式,需要的朋友可以參考下
    2025-02-02
  • C++?sqlite3數(shù)據(jù)庫配置使用教程

    C++?sqlite3數(shù)據(jù)庫配置使用教程

    SQLite 是一種嵌入式的關系型數(shù)據(jù)庫管理系統(tǒng),它是一個開源項目,已經(jīng)被廣泛應用于各種應用程序和操作系統(tǒng)中,這篇文章主要介紹了C++?sqlite3數(shù)據(jù)庫配置使用,需要的朋友可以參考下
    2023-08-08
  • 基于結構體與指針的詳解

    基于結構體與指針的詳解

    本篇文章是對結構體與指針進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05

最新評論

灵石县| 岚皋县| 南开区| 鹤山市| 赣榆县| 义乌市| 丽水市| 金华市| 松溪县| 丽江市| 武宁县| 内黄县| 蕲春县| 金湖县| 梅河口市| 武胜县| 合水县| 台湾省| 什邡市| 婺源县| 买车| 濮阳市| 景德镇市| 新绛县| 福州市| 友谊县| 青川县| 深水埗区| 永德县| 科技| 东明县| 蒙自县| 屏边| 临武县| 庄河市| 泌阳县| 永福县| 常熟市| 武隆县| 宜宾市| 甘洛县|