C++學習筆記(十六):對vector進行更多的操作——泛型演算法

來源:互聯網
上載者:User

標籤:泛型演算法   c++   vector   

先強調一下,這裡的泛型演算法實際不光光是對vector的操作,對於“順序容器”均可以。

但是什麼是順序容器:

我們都知道,容器就是一些特定類型對象的集合。而順序容器為程式員提供了控制元素儲存和訪問的能力。這種容器的一個顯著的特徵,就是容器中元素的順序不依賴於元素的值,而是與加入容器時的位置有關。常見的順序容器有vector、deque(雙端隊列)、list(雙向鏈表)、forward_list(單向鏈表)、array(固定大小數組)、string。


瞭解了順序容器,現在以vector為例,做下文的說明。

順序容器本身只定義了很少的操作,這些操作我在前面的部落格(點這裡)也有寫過。比如添加、刪除元素,訪問元素、獲得迭代器等。但是現實中,我們使用者肯定希望有更多的操作供自己使用,比如尋找、替換、刪除特定元素,重新排列元素等。為了實現上面的功能,程式員可能需要寫一大段代碼來將其實現。

為瞭解決這個問題,增加對於vector的操作種類,標準庫給出了一組“泛型演算法(generic algorithm)”。稱其“演算法”,是因為他們實現了一些經典演算法的公用介面,比如排序、搜尋。稱其為“泛型”,是因為他們可以用於不同類型的元素和多種容器類型。

 

下面講一下具體有哪些泛型演算法。

大多數的演算法都定義在標頭檔algorithm中,標準庫還在標頭檔numeric中定義了一組數值泛型演算法。一般情況下這些演算法並不直接操作容器,而是遍曆由兩個迭代器指定的一個元素範圍。

這些演算法大致可以分為下面幾類:

 

一、唯讀演算法

顧名思義,這種演算法唯讀取其輸入範圍內的元素,並不改變元素。

<1>find(vec.begin() , vec.end(), val)

在vec中搜尋val,返回第一個等於val的元素的迭代器。如果範圍內無匹配元素,則放回vec.end()。

<2>count(vec.begin() , vec.end(), val)

在vec中搜尋val,返回val在vec中出現的次數。

<3>accumulate(vec.begin() , vec.end(), val)

在vec中的元素求和,和的初始值設為val。val的類型決定了函數使用哪個加法運算子以及返回值類型。

<4>equal(vec1.begin() , vec1.end(), vec2.begin())

比較兩個vector是否相等,返回值為bool型。

 

二、寫容器元素演算法

<1>fill(vec.begin(), vec.end(), val)

將vec中的元素重設為val


<2>fill_n(dest , n , val)

將從dest開始的n個元素重設為val。這裡的dest是一個指向某個元素的迭代器。注意:這裡的vec不能是空的,如果是空,那麼上面的操作將會出現未知結果。

 

<3>back_inserter(vec)

向容器中添加元素的迭代器,故稱之為插入迭代器。通常來說,當我們通過迭代器來給容器賦值時,值被賦予迭代器指向的元素。而當我們通過一個插入迭代器賦值時,一個與賦值號右側值相等的元素被添加到容器中。back_inserter接收一個指向容器的引用,返回一個與該容器綁定的插入迭代器。當我們通過此迭代器賦值時,賦值運算子會調用push_back將一個具有給定值的元素添加到容器中。比如:

vector<int> vec;  //空向量

auto it = back_inserter(vec);  //通過它賦值會將元素添加到vec中

*it = 42;   //vec中現在有一個元素,值為42

我們常常使用back_inserter來建立迭代器,作為泛型演算法的目的位置使用。比如:

vector<int> vec;   //空向量

fill_n(back_inserter(vec), 10 ,0);  //添加10個元素到vec。

可以發現,前面說fill_n的vec不可為空,否則將會出現未知結果,而這裡back_inserter相當於給vec push_back 了10個位置,然後填充,故這裡的用法是可以的。

 

<4>copy(vec1.begin(), vec1.end(), vec2.begin())

將vec1中的內容拷貝到vec2中,故這裡要求vec2的長度必須要大於等於vec1的長度。

 

<5>replace(vec.begin(), vec.end(), val1 ,val2)

將vec中的所有val1都替換為val2。


<6>replace_copy(vec1.begin(), vec1.end(),vec2.begin(), val1 ,val2)

替換後vec1中的值並未改變,而是將vec1拷貝到vec2中,並將vec2中的所有val1都替換為val2。

 

三、排序

sort(vec.begin() , vec.end());

對vec中的內容按字典順序排序

四、刪除相同資料

unique(vec.begin(), vec.end());

將vec中重複的資料刪除,返回指向不重複地區之後一個位置的迭代器。值得注意的是這個刪除操作只是將vec中的資料清空,但是vec的大小不變。即假設原vec中有40個元素,其中重複的有5個,那麼經過unique操作後,這些重複元素重複的部分就不見了,vec中非空資料變成了35個,剩下的5個空間裡面的資料為空白。但是vec的size仍舊為40。要想真正的刪除這些元素,還需用到容器本身的操作,erase。

C++學習筆記(十六):對vector進行更多的操作——泛型演算法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.