簡述泛型演算法之 一認識演算法

2021-07-10 18:59:40 字數 3797 閱讀 7088

本章都是些stl演算法的使用,意思明確,**簡介,所以直接寫**,實踐一下各種演算法。

演算法永遠不會改變底層容器大小,智可能改變容器中儲存的元素,也可能移動元素,但不會直接新增或刪除元素;

除了insert iterator,過載了賦值運算子。但演算法自身永遠不會做這樣的操作;

//find count

vector

v1;

auto iter = find(v1.begin(), v1.end(), 6);

if (iter != v1.end()) else

auto iter = count(v.begin(), v.end(), 3);

cout

<< iter << endl;

唯讀演算法:只會讀取其輸入範圍中的元素,不會改變元素

對於唯讀演算法,最好呼叫cbegin()和cend();但如果需要用演算法返回的迭代器來改變元素,就需要用begin()和end()

vector

v;vector

v1;

vector

v2;

vector

vsa;

vector

vsb;

//accumulate

//演算法的第三個資料型別決定了呼叫那個加法運算子以及返回型別

//序列中的元素必須與第三個引數匹配,或者能轉換為第三個型別的引數

//equal

//1 equal利用迭代器完成操作,因此,可以利用不同型別的容器中的元素,只要保證能用==來比較兩個元素型別即可

//2 基於乙個重要的假設:第二個序列至少與第乙個序列一樣長;因此,如果想判斷兩個序列完全相等,必須先判斷size

//3 對於只接受單一迭代器表示第二個序列的演算法,都假定第二個序列至少與第乙個序列一樣長

; vector

char*> vs2;

cout

<< equal(vs1.cbegin(), vs1.cend(), vs2.cbegin()) << endl;

if (vs1.size() == vs2.size() &&

equal(vs1.cbegin(), vs1.cend(), vs2.cbegin())) else

}

小問題:如果兩個vector中儲存的都是const char* 不是string, equal會發生什麼?

解答:string類過載了==,可比較兩個字串長度是否向指向其中元素對應位是否相等。

而const char* 本質上是指標型別,用==比較指標物件,僅僅是比較的是位址是否相等,而不是比較其中的字元是否相同;因此,失去了使用equal的邏輯意義。

一些演算法會將新值賦予序列中的元素。當使用這些演算法時,確保原序列大小至少不小於要求演算法寫入的元素數目;

不論如何,演算法本身不會執行容器操作,演算法自身不可能改變容器大小。(除了inserter)

用到的自定義函式:

template

inline

void insertelement(t& v, int first, int last)

}template

inline

void printelement(const t& v, const

string& s = "")

for (const

auto & elem : v)

cout

<< endl;

}

具體演算法使用如下:

//fill 將給定序列賦予給定的值

//fill_n 將給定值賦給迭代器指向的元素開始的指定個元素

//該演算法假定寫入n個元素是安全的;

//copy

//replace

//replace_copy

; printelement(src);

//replace

replace(src.begin(), src.end(), 3, 9);

printelement(src); //直接修改源序列

//replace_copy

vector

dest2(src.size());

replace_copy(src.begin(), src.end(), dest2.begin(), 1, 3);

printelement(dest2);

//replace_copy back_inserter

vector

dest;

replace_copy(src.begin(), src.end(), back_inserter(dest), 1, 0);

printelement(src); //不直接修改源序列修改

printelement(dest); //把修改後的序列插入到dest中

}//reverse

//reverse_copy

//unique

//unique將相鄰的重複項「消除」, 返回乙個指向不重複值範圍的末尾迭代器;

//「消除」指的是用覆蓋相鄰的重複元素

; printelement(vs, "before sort");

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

printelement(vs, "after sort");

auto end_unique = unique(vs.begin(), vs.end()); //此時並沒有消除重複的元素

vs.erase(end_unique, vs.end());

printelement(vs, "after unique");

}

向演算法傳遞函式:

sort函式預設使用元素型別的《運算子排序,但有時還希望按照長度排序;長度相同時按再按照字典序排序,為了能按照長度排序,將使用sort的第二個版本。

此版本是過載過的,接受第三個引數,此引數是乙個謂詞(predicate):乙個可呼叫表示式,返回結果是乙個可以用作條件的值

ex1:按字典序重排word,消除重複元素;按長度重排,長度相同維持字典序

//自定義操作

bool isshorter(const

string& s1, const

string& s2)

vector

vs;

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

auto end_unique = unique(words.begin(), words.end());

words.erase(end_unique, words.end());

stable_sort(vs.begin(), vs.end(), isshorter); //向演算法傳遞函式引數

ex2:列印出長度大於等於5的元素

//自定義操作

bool longer_than_5(const

string& s)

auto end_partition = partition(vss.begin(), vss.end(), longer_than_5);

for (auto iter = vss.begin(); iter != end_partition; ++iter)

在上個例子中,如果要求演算法分割的長度大於等於n,此時,自定義函式無能為力,因為演算法只接受乙個函式引數。而長度n應該是程式中的變數,要想讓演算法能夠使用該變數,需要使用lambda表示式。

詳情見下篇文件簡述泛型演算法之 二lambda表示式

C Primer 泛型演算法簡述

重排容器元素的演算法 泛型演算法 大多數演算法都定義在標頭檔案algorithm中,標準庫的標頭檔案numeric中定義了一組數值型演算法。泛型演算法的作用是通過迭代器間接訪問容器,不會執行容器的操作,只執行在迭代器之上,迭代器可以做什麼,泛型演算法就可以做什麼。迭代器演算法不依賴於容器,但演算法依...

C 泛型演算法

標準庫並未給每個容器都定義成員函式來實現這些操作,而是定義了一組泛型演算法,稱他們為演算法是因為他們實現了一些經典演算法的公共介面,如排序和搜尋 稱他們為排序的是因為它們可以用於不同型別的元素和多種容器型別。大多數演算法都定義在標頭檔案algorithm中。標準庫還在標頭檔案numeric中定義了一...

C 泛型演算法

1 泛型演算法初始 標準庫演算法都是對乙個範圍內的元素進行操作 除了少數例外 並將此範圍稱為 輸入範圍 而且總是使用前兩個引數來表示次範圍,這兩個引數分別代表,要處理的首元素和尾元素之後位置的迭代器。1.1 唯讀演算法 只會讀取輸入範圍內的元素,而從不改變元素 find int sum accumu...