Day 31 C++ STL常用算法(下)

文章目錄

  • 常用拷貝和替換算法
      • copy——容器內指定范圍的元素拷貝到另一容器中
          • 函數原型
          • 注意——利用copy算法在拷貝時,目標容器要提前開辟空間
          • 示例
      • replace——將容器內指定范圍的第一個舊元素修改為新元素
          • 函數原型
          • 注意——replace只會替換區間內滿足條件的第一個舊元素
          • 示例
      • replace_if——在指定范圍內將所有舊元素修改為新元素
          • 函數原型
          • 注意——replace會替換區間內滿足條件的所有舊元素
      • swap——互換兩個容器的元素
          • 函數原型
          • 注意——swap交換容器時,注意交換的容器要同種類型
            • 類型要匹配
            • 容器的狀態
            • 迭代器的失效
            • 容器的大小和內存開銷
            • 異常安全性
          • 示例
  • 常用算術生成算法
      • 注意——算術生成算法屬于小型算法,使用時包含的頭文件為 `#include <numeric>`
      • accumulate—— 計算區間內容器元素累計總和
          • 函數原型
          • 注意——如果容器為空,而且沒有提供起始值參數,則調用accumulate函數會導致未定義行為
          • 示例
      • fill——用于將指定范圍內的元素都設置為給定的值
          • 函數原型
          • 注意——fill函數會將指點范圍內所有元素都填充為給定的值,原本已的值會被覆蓋。
          • 示例
  • 常用集合算法
      • set_intersection——求兩個容器的交集
          • 函數原型
          • 總結
      • set_union——求兩個集合的并集
          • 函數原型
          • 總結(和set_intersection差不多)
          • 示例
      • set_difference——求兩個集合的差集
          • 函數原型
          • 總結(都差不多)

常用拷貝和替換算法

copy——容器內指定范圍的元素拷貝到另一容器中

函數原型
  • copy(iterator beg, iterator end, iterator dest);

    // 按值查找元素,找到返回指定位置迭代器,找不到返回結束迭代器位置

    // beg 開始迭代器

    // end 結束迭代器

    // dest 目標起始迭代器

注意——利用copy算法在拷貝時,目標容器要提前開辟空間
示例
#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> source {1, 2, 3, 4, 5};std::vector<int> destination(5);  // 提前開辟目標容器空間std::copy(source.begin(), source.end(), destination.begin());// 輸出目標容器中的內容for (auto i : destination) {std::cout << i << " ";}std::cout << std::endl;return 0;
}

輸出結果為:1 2 3 4 5

在上面的示例中,我們首先創建了一個源容器source,其中包含了一些整數。然后,我們創建了一個與源容器相同大小的目標容器destination,并且提前開辟了空間。

接下來,我們使用std::copy算法將源容器中的元素拷貝到目標容器中。通過傳遞源容器的迭代器source.begin()和source.end()以及目標容器的起始迭代器destination.begin()作為參數,實現了拷貝操作。

最后,遍歷目標容器,并打印其中的元素

replace——將容器內指定范圍的第一個舊元素修改為新元素

函數原型
  • replace(iterator beg, iterator end, oldvalue, newvalue);

    // 將區間內舊元素 替換成 新元素

    // beg 開始迭代器

    // end 結束迭代器

    // oldvalue 舊元素

    // newvalue 新元素

注意——replace只會替換區間內滿足條件的第一個舊元素
示例
#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> vec {1, 2, 3, 4, 5};std::replace(vec.begin(), vec.end(), 3, 9);// 輸出修改后的容器內容for (auto i : vec) {std::cout << i << " ";}std::cout << std::endl;return 0;
}

輸出結果為:
1 2 9 4 5

在上面的示例中,我們首先創建了一個整數向量vec,其中包含了一些整數。然后,我們使用std::replace算法將容器中的舊元素3替換為新元素9。

通過傳遞容器的起始迭代器vec.begin()和結束迭代器vec.end()作為參數,以及要替換的舊元素3和新元素9,實現了替換操作。

最后,我們遍歷容器,并打印其中的元素,可以看到被替換的元素已經被修改為新元素。

replace_if——在指定范圍內將所有舊元素修改為新元素

函數原型
  • **replace_if(iterator beg, iterator end, _pred, newvalue); **

    // 按條件替換元素,滿足條件的替換成指定元素

    // beg 開始迭代器

    // end 結束迭代器

    // _pred 謂詞,謂詞函數是一個返回布爾值的函數,用于確定元素是否滿足某個條件。

    // 注意謂語是返回bool的仿函數,是謂詞,是一個類,不是函數,但是可以當函數用
    // 因此可以利用仿函數靈活篩選滿足的條件

    // newvalue 替換的新元素

注意——replace會替換區間內滿足條件的所有舊元素

示例:

#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> vec {1, 2, 3, 4, 5};std::replace_if(vec.begin(), vec.end(), [](int num){ return num == 3; }, 9);// 輸出修改后的容器內容for (auto i : vec) {std::cout << i << " ";}std::cout << std::endl;return 0;
}

輸出結果為:
1 2 9 4 5

在這個示例中,我們使用了一個匿名的lambda函數作為謂詞函數來判斷元素是否需要被替換。lambda函數接受一個整數參數num,并返回一個bool值,判斷這個整數是否等于3。如果等于3,則將其替換為新元素9。

通過使用lambda函數作為謂詞函數,我們可以自定義替換的條件。在上述示例中,我們使用等于3的元素作為替換的條件。

需要注意的是,replace_if函數只會替換滿足條件的第一個元素,如果想要替換所有滿足條件的元素,可以考慮使用std::replace_copy_if或自定義循環進行處理。

swap——互換兩個容器的元素

函數原型
  • swap(container c1, container c2);

    // 互換兩個容器的元素

    // c1容器1

    // c2容器2

注意——swap交換容器時,注意交換的容器要同種類型

交換不同類型的容器,將會導致編譯錯誤。

類型要匹配

要交換的容器類型要相同,或者滿足可以進行隱式轉換的條件。例如,兩個 std::vector<int> 可以直接交換,但是 std::vector<int>std::vector<double> 之間不能直接交換。

容器的狀態

交換容器時,要確保容器處于有效狀態,即它們不應被移動、釋放或銷毀。否則,交換操作可能會導致未定義行為。

迭代器的失效

交換容器后,原來容器中的迭代器將會失效。如果有其他依賴于這些迭代器的代碼,則需要謹慎處理,避免使用失效的迭代器。

容器的大小和內存開銷

交換容器實際上是交換了它們的內部數據結構,這意味著會涉及到元素的復制或移動操作。如果容器的大小較大,交換操作可能會帶來顯著的內存開銷和性能損失。

異常安全性

交換容器可能會引發異常,因此在交換操作之前,要考慮異常安全性,采取適當的措施來處理異常,以確保程序能夠正常執行。

示例
#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> vec1 {1, 2, 3};std::vector<int> vec2 {4, 5, 6};swap(vec1, vec2);// 輸出交換后的vec1std::cout << "vec1: ";for (auto i : vec1) {std::cout << i << " ";}std::cout << std::endl;// 輸出交換后的vec2std::cout << "vec2: ";for (auto i : vec2) {std::cout << i << " ";}std::cout << std::endl;return 0;
}

輸出結果為:
vec1: 4 5 6
vec2: 1 2 3

在這個示例中,我們創建了兩個vector類型的容器vec1和vec2。
然后,通過調用swap函數來交換這兩個容器的元素。最
終,vec1中的元素變成了4, 5, 6,vec2中的元素變成了1, 2, 3。

常用算術生成算法

注意——算術生成算法屬于小型算法,使用時包含的頭文件為 #include <numeric>

accumulate—— 計算區間內容器元素累計總和

函數原型
  • accumulate(iterator beg, iterator end, value);

    // 計算容器元素累計總和

    // beg 開始迭代器

    // end 結束迭代器

    // value 起始值
    //起始值value是可選的,如果不提供該參數,那么默認起始值將是容器中的第一個元素的值。(看下面例子)

注意——如果容器為空,而且沒有提供起始值參數,則調用accumulate函數會導致未定義行為

所以,在使用accumulate函數時,建議在累加之前檢查容器是否非空,或者提供一個明確的起始值參數。

示例
#include <iostream>
#include <vector>
#include <numeric>int main() {std::vector<int> vec {1, 2, 3, 4, 5};int sum = std::accumulate(vec.begin(), vec.end());std::cout << "Sum: " << sum << std::endl;return 0;
}

輸出結果為:
Sum: 15

在這個示例中,我們調用了accumulate函數來計算容器vec中元素的累計總和,但沒有提供起始值參數。由于沒有指定起始值,accumulate函數會使用容器中的第一個元素作為起始值進行累加運算。

因此,根據示例中的容器vec,累計總和仍然是15。

fill——用于將指定范圍內的元素都設置為給定的值

函數原型
  • fill(iterator beg, iterator end, value);

    // 向容器中填充元素

    // beg 開始迭代器

    // end 結束迭代器

    // value 填充的值

注意——fill函數會將指點范圍內所有元素都填充為給定的值,原本已的值會被覆蓋。
示例
#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> vec {1, 2, 3, 4, 5};std::fill(vec.begin(), vec.end(), 10);// 輸出填充后的向量std::cout << "Filled Vector: ";for (auto i : vec) {std::cout << i << " ";}std::cout << std::endl;return 0;
}

輸出結果為:

Filled Vector: 10 10 10 10 10
在這個示例中,我們有一個包含初始值的向量vec,其中包含了數字1到5。然后,我們使用fill函數將容器vec中的所有元素都填充為10。

最終的輸出結果顯示,原本向量中的元素已經被覆蓋,全部變成了10, 10, 10, 10, 10。

因此,需要注意,在使用fill函數時,如果你希望保留原有元素的值,只填充指定范圍內的部分元素,可以使用更具靈活性的方法,如迭代器和算法結合使用來實現部分填充。

常用集合算法

set_intersection——求兩個容器的交集

set_intersection 函數通常用于計算兩個有序集合的交集。
但是,它實際上可以用于任何支持隨機訪問的序列容器,而不僅限于集合。

函數原型
  • set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
    // beg1 容器1開始迭代器
    // end1 容器1結束迭代器
    // beg2 容器2開始迭代器
    // end2 容器2結束迭代器
    // dest 目標容器開始迭代器
總結
  • 求交集的兩個集合必須是有序序列
  • 目標容器開辟空間需要從兩個容器中取小值
  • set_intersection返回值既是交集中最后一個元素的位置

示例:

#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> vec1 {1, 2, 3, 4, 5};std::vector<int> vec2 {3, 4, 5, 6, 7};std::vector<int> intersection(std::min(vec1.size(), vec2.size()));auto it = std::set_intersection(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), intersection.begin());// 輸出交集中的元素std::cout << "Intersection: ";for (auto i = intersection.begin(); i != it; ++i) {std::cout << *i << " ";}std::cout << std::endl;return 0;
}

輸出結果為:
Intersection: 3 4 5

在這個示例中,我們有兩個有序的向量vec1和vec2,分別包含了不同的整數。我們需要找出這兩個向量的交集。

首先,我們創建了一個目標容器intersection,它的大小為兩個輸入容器中較小的那個。

然后,使用set_intersection函數將兩個輸入容器中的交集復制到目標容器intersection中。set_intersection函數接受五個參數,分別是兩個輸入容器的起始和結束迭代器,以及目標容器的起始迭代器。這樣,交集中的元素就會復制到目標容器中。

最后,我們遍歷目標容器中的元素,并輸出交集中的值。

set_union——求兩個集合的并集

函數原型
  • set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);

    // beg1 容器1開始迭代器
    // end1 容器1結束迭代器
    // beg2 容器2開始迭代器
    // end2 容器2結束迭代器
    // dest 目標容器開始迭代器

總結(和set_intersection差不多)
  • 求并集的兩個集合必須的有序序列
  • 目標容器開辟空間需要兩個容器相加
  • set_union返回值既是并集中最后一個元素的位置
示例
#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> vec1 {1, 2, 3, 4, 5};std::vector<int> vec2 {3, 4, 5, 6, 7};std::vector<int> unionSet(vec1.size() + vec2.size());auto it = std::set_union(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), unionSet.begin());// 輸出并集中的元素std::cout << "Union: ";for (auto i = unionSet.begin(); i != it; ++i) {std::cout << *i << " ";}std::cout << std::endl;return 0;
}

輸出結果為:
Union: 1 2 3 4 5 6 7

在這個示例中,我們有兩個有序的向量vec1和vec2,分別包含了不同的整數。我們需要找出這兩個向量的并集。

首先,我們創建了一個目標容器unionSet,它的大小為兩個輸入容器的總大小。

然后,使用set_union函數將兩個輸入容器中的并集復制到目標容器unionSet中。
set_union函數接受五個參數,分別是兩個輸入容器的起始和結束迭代器,以及目標容器的起始迭代器。這樣,并集中的元素就會復制到目標容器中。

最后,我們遍歷目標容器中的元素,并輸出并集中的值。

set_difference——求兩個集合的差集

函數原型
  • set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);

    // beg1 容器1開始迭代器
    // end1 容器1結束迭代器
    // beg2 容器2開始迭代器
    // end2 容器2結束迭代器
    // dest 目標容器開始迭代器

總結(都差不多)
  • 求差集的兩個集合必須的有序序列
  • 目標容器開辟空間需要從兩個容器取較大值
  • set_difference返回值既是差集中最后一個元素的位置

示例:

#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> vec1 {1, 2, 3, 4, 5};std::vector<int> vec2 {3, 4, 5, 6, 7};std::vector<int> difference(std::max(vec1.size(), vec2.size()));auto it = std::set_difference(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), difference.begin());// 輸出差集中的元素std::cout << "Difference: ";for (auto i = difference.begin(); i != it; ++i) {std::cout << *i << " ";}std::cout << std::endl;return 0;
}

輸出結果為:
Difference: 1 2

在這個示例中,我們有兩個有序的向量vec1和vec2,分別包含了不同的整數。我們需要找出這兩個向量的差集。

首先,我們創建了一個目標容器difference,它的大小為兩個輸入容器中較大的那個。

然后,使用set_difference函數將兩個輸入容器中的差集復制到目標容器difference中。
set_difference函數接受五個參數,分別是兩個輸入容器的起始和結束迭代器,以及目標容器的起始迭代器。這樣,差集中的元素就會復制到目標容器中。

最后,我們遍歷目標容器中的元素,并輸出差集中的值。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/40945.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/40945.shtml
英文地址,請注明出處:http://en.pswp.cn/news/40945.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

cve-2016-7193:wwlib 模塊堆數據結構溢出

簡介 漏洞編號&#xff1a;cve-2016-7193漏洞類型&#xff1a;堆溢出軟件名稱&#xff1a;Office模塊名稱&#xff1a;wwlib歷史漏洞&#xff1a;較多影響的版本 攻擊利用&#xff1a;APT 攻擊利器-Word 漏洞 CVE-2016-7193 原理揭秘 操作環境 系統&#xff1a;Win10 1607軟…

C++ 動態內存

C 動態內存 C 程序中的內存分為兩個部分&#xff1a; 棧&#xff1a;在函數內部聲明的所有變量都將占用棧內存堆&#xff1a;這是程序中未使用的內存&#xff0c;在程序運行時可用于動態分配內存 很多時候&#xff0c;無法提前預知需要多少內存來存儲某個定義變量中的特定信…

【Docker報錯】docker拉取鏡像時報錯:no such host

報錯信息 [rootSoft soft]# docker pull mysql Using default tag: latest Error response from daemon: Head "https://registry-1.docker.io/v2/library/mysql/manifests/latest": dial tcp: lookup registry-1.docker.io on 192.168.80.2:53: no such host解決方法…

3D模型格式轉換工具如何與Parasolid集成?

概述 HOOPS Exchange包括一個 Parasolid 連接器&#xff0c;它允許 Parasolid 開發人員輕松地將 CAD 數據導入到活動的 Parasolid 會話中。如果源數據基于 Parasolid&#xff08;NX、Solid Edge 或 SolidWorks&#xff09;&#xff0c;則數據將按原樣導入。 這意味著您可以假…

主數據管理案例-某政務

1、 背景介紹及難點分析 近年來&#xff0c;我國在大數據發展方面持續發力&#xff0c;取得了明顯成效。但也要看到&#xff0c;目前我國大數據發展還存在“孤島化”“碎片化”等問題&#xff0c;無序參與過度與創新參與不足并存&#xff0c;導致大數據資源配置統籌不&#xff…

【C++】list容器

1.list基本概念 2.list構造函數 #include <iostream> using namespace std;#include<list> //鏈表list容器構造函數//輸出list鏈表 void printList(const list<int>& L) {for (list<int>::const_iterator it L.begin(); it ! L.end(); it){cout &…

STM32入門學習之定時器PWM輸出

1.脈沖寬度調制PWM(Pulse Width Modulation)是利用微處理器的數字輸出來對模擬電路進行控制的一種非常有效的技術。PWM可以理解為高低電平的占空比&#xff0c;即輸出高電平時間與低電平時間的比值。PWM的應用是否廣泛&#xff0c;比如在步進電機的控制中&#xff0c;可以通過P…

【MySQL系列】-回表、覆蓋索引真的懂嗎

【MySQL系列】-回表、覆蓋索引真的懂嗎 文章目錄 【MySQL系列】-回表、覆蓋索引真的懂嗎一、MYSQL索引結構1.1 索引的概念1.2 索引的特點1.3 索引的優點1.4 索引的缺點 二、B-Tree與BTree2.1 B-Tree2.2 BTree2.3 B-Tree 與BTree樹的區別2.4 那么為什么InnoDB的主鍵最好要搞成有…

記一次 .NET 某外貿ERP 內存暴漲分析

一&#xff1a;背景 1. 講故事 上周有位朋友找到我&#xff0c;說他的 API 被多次調用后出現了內存暴漲&#xff0c;讓我幫忙看下是怎么回事&#xff1f;看樣子是有些擔心&#xff0c;但也不是特別擔心&#xff0c;那既然找到我&#xff0c;就給他分析一下吧。 二&#xff1…

【軟件測試】接口測試工具APIpost

說實話&#xff0c;了解APIpost是因為&#xff0c;我的所有接口相關的文章下&#xff0c;都有該APIpost水軍的評論&#xff0c;無非就是APIpost是中文版的postman&#xff0c;有多么多么好用&#xff0c;雖然咱也還不是什么啥網紅&#xff0c;但是不知會一聲就亂在評論區打廣告…

【力扣每日一題】2023.8.14 合并二叉樹

目錄 題目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代碼&#xff1a; 題目&#xff1a; 示例&#xff1a; 分析&#xff1a; 給我們合并兩棵二叉樹&#xff0c;合并的方式就是把對應位置的節點的值相加&#xff0c;最后把合并后的二叉樹的根節點返回出去。 這類二…

You have docker-compose v1 installed, but we require Docker Compose v2.

curl -SL https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose chmod x /usr/local/bin/docker-compose docker-compose --version

一文看盡R-CNN、Fast R-CNN、Faster R-CNN、YOLO、SSD詳解

一文看盡R-CNN、Fast R-CNN、Faster R-CNN、YOLO、SSD詳解 以下六篇文章總結詳細&#xff1a; 1. 一文讀懂目標檢測&#xff1a;R-CNN、Fast R-CNN、Faster R-CNN、YOLO、SSD 2. 【深度學習】R-CNN 論文解讀及個人理解 3、R-CNN論文詳解 4、一文讀懂Faster RCNN 5、學一百遍都…

JAVA基礎知識(六)——異常處理

異常 一、異常概述與異常體系結構二、常見異常三、異常處理機制一&#xff1a;try-catch-finally四、異常處理機制二&#xff1a;throws五、手動拋出異常&#xff1a;throw六、用戶自定義異常類七、開發中如何選擇使用try-catch-finally還是使用throws八、如何看待代碼中的編譯…

goland插件推薦Rider UI Theme Pack

推薦一個goland配色插件Rider UI Theme Pack&#xff0c;里面自帶visual assist配色&#xff0c;配色截圖如下&#xff1a; 直接在plugins里面進行搜索或者在插件home page下載后進行安裝&#xff0c; 然后按照下圖進行設置即可。 此插件還適用于Jetbrains旗下的Clion和Pycharm…

WX1860- ngbe-1.2.5 xdp程序在路由模式下,使用iperf工具測試數據包不轉發,用jmeter可以

本地驗證時重定向iperf包有出現calltrace錯誤&#xff0c;經推斷&#xff0c;系統PAGE_SIZE<8k時可能出現&#xff08;getconf PAGE_SIZE指令可查看&#xff09;&#xff0c;按下圖將ngbe_main.c的2350行ngbe_rx_bufsz改為ngbe_rx_pg_size可修復。其次&#xff0c;需要將加載…

鴻蒙3.1 基于Token的訪問控制

介紹 代碼路徑:security_access_token: ATM(AccessTokenManager)是OpenHarmony上基于AccessToken構建的統一的應用權限管理能力。 ATM(AccessTokenManager)是OpenHarmony上基于AccessToken構建的統一的應用權限管理能力。 應用的Accesstoken信息主要包括應用身份標識APPID、…

什么是游戲出海運營?

游戲出海運營&#xff0c;也稱為游戲海外運營&#xff0c;是指將原本面向國內市場的游戲產品拓展到國際市場&#xff0c;以在海外地區推廣、發行、運營游戲的過程。這涵蓋了從市場調研、產品適應性優化、本地化翻譯、推廣營銷、社區互動到客戶支持等一系列策略和活動&#xff0…

阿里云對象存儲服務OSS

1、引依賴 <dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.15.1</version> </dependency> <dependency><groupId>javax.xml.bind</groupId><artifa…

Mocha and Red and Blue

一、題目 題面翻譯 給定長為 n n n 的僅由 R \texttt{R} R、 B \texttt{B} B、 ? \texttt{?} ? 組成的字符串 S S S&#xff0c;請你在 ? \texttt{?} ? 處填入 R \texttt{R} R 或 B \texttt{B} B&#xff0c;使得相鄰位置字符相同的數量最少。 譯者 ajthreac 題…