C Pramer5th第十章泛型演算法

2021-09-25 04:01:18 字數 4058 閱讀 9684

一般情況下,演算法並不直接操作容器,而是遍歷由兩個迭代器指定的乙個元素範圍來進行操作。

以下演算法包含在 algorithm 標頭檔案中,幷包含此定義

vectorvec;
下面是演算法格式及內容:

find(vec.begin(), vec.end(), num);					//返回在vec中第乙個與定值相等的元素的迭代器
//唯讀演算法

equal(vec.cbegin(), vec.cend(), vet.cbegin()); //比較vec中範圍內和vet以迭代器cbegin() 開始的元素,返回 true或false

//注意:使用fill演算法時,必須確保序列原大小至少不大於我們演算法寫入的元素數目

fill(vec.begin(), vec.end(), num); //將給定的num值賦予輸入序列中的 每個元素

//注意:不能在空容器上呼叫fill_n

fill_n(vec.begin(), vec.size(), 0); //將所有元素重置為 0

//注意:傳遞給copy的目的序列至少要包含於輸入序列一樣多的元素  其中,copy也可以針對內建陣列的拷貝

copy(vec.begin(), vec.end(), vet.begin()); //將vec中的元素拷貝至vet.begin()之後開始的位置

copy(begin(a1),end(a1),a2); //a1、a2都為內建陣列

replace(vec.begin(), vec.end(), num1, num2);		//從vec中尋找num1將其替換為num2

replace_copy(vec.begin(), vec.end(),back_inserter(ivec), num1, num2); //ivec包含vec的乙份拷貝,不過將原來vec中值為num1的元素在ivec中都變為num2

count(vec.begin(), vec.end(), num);					//返回定值在序列**現的次數
sort(vec.begin(), vec.end());						//按照從小到大的順序排序

sort(vec.begin(), vec.end(), f); //f 為二元謂語,即接受兩個形參的函式,此表示式意思為:按照 f 的方式進行排序

//此處的 f 通常為外在的比較,如字串的大小長度

stable_sort(vec.begin(), vec.end(), f); //按照 f 進行排序,再進行內部的大小比較,如:按照字母大小進行比較,或按照數字大小進行比較

//若沒有重複單詞,則返回尾後迭代器

unique(vec.begin(), vec.end()); //將相鄰的重複項「消除」,即將相同的保留乙個,其餘的放在所有不同的後面,具體的儲存形式根據編譯器不同而不同。返回的迭代器為指向最後乙個不重複元素之後的位置

unique_copy(vet.begin(), vet.end(), vec.begin()) ; //表示將不重複的部分拷貝到以vec中,且起始位置為begin()

//注意:此處的 f 的返回值為bool型別或者能夠轉換成bool型別的基本型別

partition(vec.begin(), vec.end(), f); //f 是乙個一元謂詞,即接受乙個形參的函式,此表示式的意思為:滿足 f 條件的放在容器的前半部分,不滿足的放在後半部分。 返回乙個迭代器,指向最後乙個使謂詞為true的元素之後的位置

//此處的 f 與 stale_sort 類似,也是表示外在的比較

stable_partition(vec.begin(), vec.end(), f); //先按照 f 進行比較,再進行內部比較

find_if(vec.begin(), vec.end(), f);			//返回乙個迭代器,指向第乙個滿足 f 的元素,這裡的 f 為一元謂語 且 f 的返回型別為 bool 型別
for_each(vec.begin(), vec.end(), f);				//對序列中的每個物件呼叫此謂語,此處的謂語 f 為一元謂語
count_if(vet.begin(), vet.end(), f);				//返回乙個計數值,表示序列範圍內使謂語 f 為真的個數 f 為 一元謂語 其中謂語 f 的返回型別為bool
以下為在 numeric 標頭檔案中的演算法:

唯讀演算法

//注意:此演算法計算順序為 先將序列中的元素轉化為 w 的型別,再進行加法運算

accumulate(vec.begin(), vec.end(), w); //將序列中的元素進行求和

lamaba表示式

[capture list] ( parameter ) -> return type  			//格式
//其中捕獲列表

auto f = ; //設方式

f(); //呼叫方式

注意:lamaba表示式不能有預設形參,且實參和形參型別必須匹配,且數量永遠相等

預設情況下,從 lamaba 生成的類都包含乙個對應該 lamaba 所捕獲的變數的資料成員。類似,任何普通類的資料成語,lamaba 的資料成員也在 lamaba 物件建立時被初始化。

可變 lamaba 表示式

auot f =  () mutable ;		//在引數列表首加上關鍵字 mutable
返回值

預設情況下,如果乙個 lamaba 體包含 return 之外的任何語句,則編譯器假定此 lamaba 返回 void.當想要定義返回型別時,必須使用尾置返回型別。

[ ] ( ) -> ;    		//箭頭後面表示尾置返回型別
引數繫結

標準庫bind函式

標頭檔案#include可以稱作函式介面卡

形式:

auto newcallable = bind ( callable, arg_list );			//newcallable 為函式  callable 也為函式 當呼叫newcallable 時,會進行呼叫 callable
例項:

//其中w、a 會傳遞給_1、_2 的引數

auto f1 = bind( f, _1, _2, s); //其中s 單獨的引數,類似於lamaba 的捕獲列表中的引數

cout << f1(w, a);

arg_list系列名字定義在placeholders命名空間中,而這個命名空間本身定義在std命名空間中,為了使用這個名字,兩個命名空間都要寫。placeholders也定義在標頭檔案functional中。

using std::placeholders::_1;		//使用using 宣告

using namespace std::placeholders; //使用using 直接將整個命名空間進行共享

預設情況下,bind 的那些不是佔位符的引數被拷貝到bind 返回的可呼叫物件中。

如果我們希望傳遞給bind 乙個物件而又不拷貝它,就必須使用標準庫ref函式。例如:

fer_each(words.begin(), words.end(), bind(print, ref(os), _1, ' '));		//ref返回乙個物件,包含給定的引用,此物件是可以拷貝的。
標準庫中cref函式生成乙個儲存const引用的類。refcref都定義在標頭檔案functional

第十章 泛型演算法

特殊迭代器 插入迭代器 被繫結到乙個容器上,可用來向容器插入元素 流迭代器 被繫結到輸入 輸出流上,可用來遍歷所關聯io流 反向迭代器 向後而不是向前移動,除了forward list,容器都擁有它 移動迭代器 不是拷貝其中的元素,而是移動它們 插入迭代器操作 it t 在it指定的當前位置插入t,...

c primer 筆記,第十章(泛型演算法)

accumulate第三個三處所傳的儲值的型別必須定義了 運算子,例如 將空串當作乙個字面值傳給第三個引數是不可以的 會導致編譯錯誤,const char 上並沒有定義 運算子 string sum accumulate v.cbegin v.cend string上定義了 運算子 string s...

c primer 第十章泛型演算法lambda

謂詞是乙個呼叫表示式,其返回結果是乙個能用做條件的值。標準庫演算法為此分為兩類 1 一元謂詞 意味著只能接受單一引數 2 二元謂詞 意味著他們有兩個引數 接受謂詞的演算法對輸入序列中的元素呼叫謂詞。因此元素型別必須能轉換為謂詞的引數型別。以sort和isshorter舉例 eg bool issho...