網站首頁 編程語言 正文
初識泛型算法
只讀算法
只讀取輸入范圍內的函數,不改變元素,find,accumula也是如此
(1)accumulate算法為求和算法,前兩個參數指出求和元素范圍,第三個是和的初值,例:
int sum=accumulate(v.begin(),v.end(),0)
(2)操作兩個序列的算法
equal算法,確定兩個序列是否保存相同的值,將第一個序列的每個元素和第二個序列中的每個元素進行比較,若相同返回true,否則返回false,接受三個參數,前兩個表示第一個序列的元素范圍,第三個表示第二個序列的首元素
equal(r1.begin(),r1.end(),r2.begin())
寫容器算法
(1)拷貝算法
向另一個目的位置迭代器指向的輸出序列中的元素寫入數據算法。此算法接受三個迭代器,前兩個表示一個舒服范圍,第三個表示目的序列的起始位置。copy返回目的迭代器的值。
int a1[] = { 0,1,2,3,4,5 };
int a2[sizeof(a1) / sizeof(*a1)];
auto ret = copy(begin(a1), end(a1), a2);
定制操作
lambda表達式
(1)定義
一個lambda表達式表示一個可調用的代碼單元,可理解為未命名的內聯函數
lambda表達式形式:
[capture list](parameter list) - > return type{function body}
可以忽略參數列表和返回類型,但必須永遠包含捕獲列表和函數體
auto f =[] {return 42}
調用: cout<<f()<<endl;
(2)向lambda傳遞參數
實參被用來初始化lambda的形參,lambda不能有默認參數
例:
//[](const string &a,const string &b){return a.size()<b.size()}
//調用
sort(w.begin(),w.end(),[](const string &a,const string &b){return a.size()<b.size()})
(3)使用捕獲列表
一個lambda通過將局部變量包含在其捕獲列表中指出將會使用這些變量,捕獲列表指引lambda在其內部包含訪問局部變量所需的全部信息
例如,找出第一個大于等于給定長度的單詞。
函數biggies實現
void biggies(vector<string> &words,vector<string>::size_type sz)
{
auto wc=find_if(words.begin(),words.end(),
[sz](const string &a){return a.size()>=sz});
}
lambda捕獲和返回
(1)值捕獲
與傳值參數類似,采用值捕獲的前提是變量可以拷貝,與參數不同,被捕獲的變量的值是在lambda創建時拷貝,而不是調用時拷貝
void fcun()
{
size_t v1=42;
auto f=[v1]{return v1;};
v1=0;
auto j=f();
}
由于被捕獲變量的值是在lambda創建時拷貝,因此隨后對其修改不會影響到lambda內對應的值,上述中j的值為42
(2)引用捕獲
void fcun()
{
size_t v1=42;
auto f=[&v1]{return v1;};
v1=0;
auto j=f(); //j為0,f2保存v1的引用,而非拷貝
}
(3)隱式捕獲
可以讓編譯器根據lambda體中的代碼推斷我們要使用哪些變量,此時應在捕獲列表中寫一個&或=,&表示采用捕獲引用,=表示采用值捕獲方式。
wc=find_if(w.begin(),w.end(),[=](const string &s){return s.size>=sz;});
(4)可變lambda
在值拷貝的情況下,lambda不會改變其值,若希望能夠改變被捕獲的變量的值,則在參數列表首加上mutable關鍵字。
void func()
{
size_t v1=42;
auto f=[vi]() mutable{return ++v1;};
v1=0;
auto j=f();
}
一個引用捕獲的變量能否可以修改依賴于此引用指向的是一個const還是非const類型
void fc()
{
const size_t v1 = 42;
auto f = [&v1]() mutable {return ++v1; };//無法修改v1
auto j = f();
cout << j << endl;
}
(5)指定lambda的返回類型
默認情況下,如果一個lambda體中包含return之外的任何語句,則編譯器假定此lambda返回void。
例如:將一個序列中負數替換為其絕對值
transform(v.begin(),v.end(),v.begin(),[](int i){return i<0?-i:i;})
transform接受三個參數,前兩個表示迭代器輸入序列,第三個表示迭代器目的位置。
上述中,我們無需指定返回類型,因此可以根據條件運算符的類型推斷出來。
若改寫成存在if語句,則存在錯誤
transform(v.begin(),v.end(),v.begin(),[](int i){if(i<0) return -i; else return i;})
編譯器發現存在return之外的語句,所以推斷其返回類型為void,而他卻返回了一個int
正確寫法:
transform(v.begin(),v.end(),v.begin(),
[](int i) ->int {if(i<0) return -i; else return i;})
再探迭代器
標準庫頭文件iterator中還定義了額外幾種迭代器,包括如下:
- 插入迭代器:綁定到一個容器上,向容器插入元素
- 流迭代器:綁定到輸入輸出流上,可以用來遍歷所關聯的IO流
- 反向迭代器:這些迭代器向后而不是向前移動,forwar_list不存在此迭代器
- 移動迭代器:移動元素專用
插入迭代器
例:
list<int> lst = { 1,2,3,4 };
list<int> lst2, lst3;
copy(lst.begin(), lst.end(), front_inserter(lst2));
copy(lst.begin(), lst.end(), inserter(lst3, lst3.begin()));
front_inserter總是插入容器的第一個元素之前,所以lst2中的元素順序為4,3,2,1,而lst3中的元素順序為1,2,3,4
iostream迭代器
istream_iterator讀取輸入流,ostream_iterator向一個輸出流寫數據。
(1)istream_iterator操作
創建流迭代器時,必須指定迭代器將要讀寫的對象類型,可以創建空的初始化迭代器,用作尾后值使用的迭代器,一旦關聯的流遇到文件尾或者IO錯誤,迭代器的值就與尾后迭代器相等。
例:讀取輸入數據保存到vector中
vector<int> v;
istream_iterator<int> it(cin);
istream_iterator<int> e;
while (it != e)
v.push_back(*it++); //或 v.push_back(it,e)
(2)使用算法操作流迭代器
例:
istream_iterator<int> it(cin);
istream_iterator<int> e;
cout << accumulate(it, e, 0) << endl;
(3)ostream_iterator操作
創建一個ostream_iterator時,可以提供第二參數,他是一個字符串,在輸出每個元素后都會打印此字符串,不允許空的或表示尾后的ostream_iterator
vector<int> v = { 1,2,3,4 };
ostream_iterator<int> out(cout, "@@");
for (auto e : v)
*out++ = e; //賦值語句實際上是將元素寫到cout,且*和++并不做任何事
cout << endl;
反向迭代器
反向迭代器就是在容器中尾元素向首元素反向移動的迭代器,遞增一個反向迭代器會向前移動一個元素,遞減一個迭代器會向后移動一個元素
將反向迭代器轉換為普通迭代器可使用reverse_iterator中的base成員函數來完成轉換
例:輸出最后一個單詞
string line = { "first,middle,last" };
auto r = find(line.rbegin(), line.rend(), ',');
cout << string(r.base(), line.end()) << endl;
原文鏈接:https://blog.csdn.net/weixin_42375706/article/details/125479265
相關推薦
- 2023-02-09 使用adb?or?fastboot命令進入高通的9008(edl)模式的兩種方法_Android
- 2022-04-04 Server is Started at port : 5500,但是卻不能打開網頁
- 2023-07-10 SpringBoot AOP+注解方式實現多數據源切換可能遇到的問題
- 2022-09-07 Go泛型應用工廠方法及泛型使用_Golang
- 2022-06-12 使用jquery實現別踩白塊小游戲的方法實例_jquery
- 2022-06-22 C語言樹與二叉樹基礎全刨析_C 語言
- 2022-06-14 C#實現FTP上傳文件的方法_C#教程
- 2022-08-27 關于pygame自定義窗口創建及相關操作指南_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支