【STL】函數對象+常用算法

文章目錄

  • STL- 函數對象
    • 函數對象
      • 函數對象使用
    • 謂詞
      • 一元謂詞
      • 二元謂詞
      • 內建函數對象
        • 算術仿函數
        • 關系仿函數
  • STL- 常用算法
    • 常用遍歷算法
      • for_each
      • transform
    • 常用查找算法
      • find
      • find_if
      • adjacent_find
      • binary_search
      • count
      • count_if
    • 常用排序算法
      • sort
      • random_shuffle
      • merge
      • reverse
    • 常用拷貝和替換算法
      • copy
      • replace
      • replace_if
      • swap
    • 常用算術生成算法
      • accumulate
      • fill
    • 常用集合算法
      • set_intersection
      • set_union
      • set_difference

STL- 函數對象

函數對象

重載函數調用操作符的類,其對象常稱為函數對象
函數對象使用重載的()時,行為類似函數調用,也叫仿函數

本質:函數對象(仿函數)是一個,不是一個函數

函數對象使用

特點:

  • 函數對象在使用時,可以像普通函數那樣調用, 可以有參數,可以有返回值
  • 函數對象超出普通函數的概念,函數對象可以有自己的狀態
  • 函數對象可以作為參數傳遞
#include <string>//1、函數對象在使用時,可以像普通函數那樣調用, 可以有參數,可以有返回值
class MyAdd{
public :int operator()(int v1,int v2){return v1 + v2;}
};void test01(){MyAdd myAdd;cout << myAdd(10, 10) << endl;
}//2、函數對象可以有自己的狀態
class MyPrint{
public:MyPrint(){count = 0;}void operator()(string test){cout << test << endl;count++; //統計使用次數}int count; //內部自己的狀態
};
void test02(){MyPrint myPrint;myPrint("hello world");myPrint("hello world");myPrint("hello world");cout << "myPrint調用次數為: " << myPrint.count << endl;
}//3、函數對象可以作為參數傳遞
void doPrint(MyPrint &mp , string test){mp(test);
}void test03(){MyPrint myPrint;doPrint(myPrint, "Hello C++");
}

總結:
仿函數寫法非常靈活,可以作為參數進行傳遞。

謂詞

返回bool類型的仿函數稱為謂詞
如果operator()接受一個參數,那么叫做一元謂詞
如果operator()接受兩個參數,那么叫做二元謂詞

一元謂詞

#include <vector>
#include <algorithm>//1.一元謂詞
struct GreaterFive{bool operator()(int val) {return val > 5;}
};void test01() {vector<int> v;for (int i = 0; i < 10; i++){v.push_back(i);}vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive());if (it == v.end()) {cout << "沒找到!" << endl;}else {cout << "找到:" << *it << endl;}
}

總結:參數只有一個的謂詞,稱為一元謂詞

二元謂詞

#include <vector>
#include <algorithm>
//二元謂詞
class MyCompare{
public:bool operator()(int num1, int num2){return num1 > num2;}
};void test01(){vector<int> v;v.push_back(10);v.push_back(40);v.push_back(20);v.push_back(30);v.push_back(50);//默認從小到大sort(v.begin(), v.end());for (vector<int>::iterator it = v.begin(); it != v.end(); it++){cout << *it << " ";}cout << endl;cout << "----------------------------" << endl;//使用函數對象改變算法策略,排序從大到小sort(v.begin(), v.end(), MyCompare());for (vector<int>::iterator it = v.begin(); it != v.end(); it++){cout << *it << " ";}cout << endl;
}

總結:參數只有兩個的謂詞,稱為二元謂詞

內建函數對象

STL內建了一些函數對象

分類:

  • 算術仿函數
  • 關系仿函數
  • 邏輯仿函數(了解即可)

用法:

  • 這些仿函數所產生的對象,用法和一般函數完全相同
  • 使用內建函數對象,需要引入頭文件 #include<functional>
算術仿函數

功能描述:

  • 實現四則運算
  • 其中negate是一元運算,其他都是二元運算

仿函數原型:

  • template<class T> T plus<T> //加法仿函數
  • template<class T> T minus<T> //減法仿函數
  • template<class T> T multiplies<T> //乘法仿函數
  • template<class T> T divides<T> //除法仿函數
  • template<class T> T modulus<T> //取模仿函數
  • template<class T> T negate<T> //取反仿函數
#include <functional>
//negate
void test01(){negate<int> n;cout << n(50) << endl;
}//plus
void test02(){plus<int> p;cout << p(10, 20) << endl;
}

總結:使用內建函數對象時,需要引入頭文件 #include <functional>

關系仿函數

實現關系對比

仿函數原型:

  • template<class T> bool equal_to<T> //等于
  • template<class T> bool not_equal_to<T> //不等于
  • template<class T> bool greater<T> //大于
  • template<class T> bool greater_equal<T> //大于等于
  • template<class T> bool less<T> //小于
  • template<class T> bool less_equal<T> //小于等于
#include <functional>
#include <vector>
#include <algorithm>class MyCompare{
public:bool operator()(int v1,int v2){return v1 > v2;}
};
void test01(){vector<int> v;v.push_back(10);v.push_back(30);v.push_back(50);v.push_back(40);v.push_back(20);for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {cout << *it << " ";}cout << endl;//自己實現仿函數//sort(v.begin(), v.end(), MyCompare());//STL內建仿函數  大于仿函數sort(v.begin(), v.end(), greater<int>());for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {cout << *it << " ";}cout << endl;
}

總結:關系仿函數中最常用的就是greater<>大于

STL- 常用算法

算法主要是由頭文件<algorithm> <functional> <numeric>組成。

  • <algorithm>是所有STL頭文件中最大的一個,范圍涉及到比較、 交換、查找、遍歷操作、復制、修改等等
  • <numeric>體積很小,只包括幾個在序列上面進行簡單數學運算的模板函數
  • <functional>定義了一些模板類,用以聲明函數對象。

常用遍歷算法

算法簡介:

  • for_each //遍歷容器
  • transform //搬運容器到另一個容器中

for_each

實現遍歷容器

函數原型:

  • for_each(iterator beg, iterator end, _func);
  // 遍歷算法 遍歷容器元素// beg 開始迭代器// end 結束迭代器// _func 函數或者函數對象`

示例:

#include <algorithm>
#include <vector>//普通函數
void print01(int val) {cout << val << " ";
}
//函數對象
class print02 {public:void operator()(int val) {cout << val << " ";}
};//for_each算法基本用法
void test01() {vector<int> v;for (int i = 0; i < 10; i++) {v.push_back(i);}//遍歷算法for_each(v.begin(), v.end(), print01);cout << endl;for_each(v.begin(), v.end(), print02());cout << endl;
}

總結:for_each在實際開發中是最常用遍歷算法,需要熟練掌握

transform

搬運容器到另一個容器中

函數原型:

  • transform(iterator beg1, iterator end1, iterator beg2, _func);
//beg1 源容器開始迭代器
//end1 源容器結束迭代器
//beg2 目標容器開始迭代器
//_func 函數或者函數對象
#include<vector>
#include<algorithm>//常用遍歷算法  搬運 transformclass TransForm{
public:int operator()(int val){return val;}};class MyPrint{
public:void operator()(int val){cout << val << " ";}
};void test01(){vector<int>v;for (int i = 0; i < 10; i++){v.push_back(i);}vector<int>vTarget; //目標容器vTarget.resize(v.size()); // 目標容器需要提前開辟空間transform(v.begin(), v.end(), vTarget.begin(), TransForm());for_each(vTarget.begin(), vTarget.end(), MyPrint());
}

總結: 搬運的目標容器必須要提前開辟空間,否則無法正常搬運

常用查找算法

算法簡介:

  • find //查找元素
  • find_if //按條件查找元素
  • adjacent_find //查找相鄰重復元素
  • binary_search //二分查找法
  • count //統計元素個數
  • count_if //按條件統計元素個數

find

查找指定元素,找到返回指定元素的迭代器,找不到返回結束迭代器end()

函數原型:

  • find(iterator beg, iterator end, value);
  // 按值查找元素,找到返回指定位置迭代器,找不到返回結束迭代器位置// beg 開始迭代器// end 結束迭代器// value 查找的元素
#include <algorithm>
#include <vector>
#include <string>
void test01() {vector<int> v;for (int i = 0; i < 10; i++) {v.push_back(i + 1);}//查找容器中是否有 5 這個元素vector<int>::iterator it = find(v.begin(), v.end(), 5);if (it == v.end()) {cout << "沒有找到!" << endl;}else {cout << "找到:" << *it << endl;}
}class Person {
public:Person(string name, int age) {this->m_Name = name;this->m_Age = age;}//重載==bool operator==(const Person& p) {if (this->m_Name == p.m_Name && this->m_Age == p.m_Age) {return true;}return false;}public:string m_Name;int m_Age;
};void test02() {vector<Person> v;//創建數據Person p1("aaa", 10);Person p2("bbb", 20);Person p3("ccc", 30);Person p4("ddd", 40);v.push_back(p1);v.push_back(p2);v.push_back(p3);v.push_back(p4);vector<Person>::iterator it = find(v.begin(), v.end(), p2);if (it == v.end()) {cout << "沒有找到!" << endl;}else {cout << "找到姓名:" << it->m_Name << " 年齡: " << it->m_Age << endl;}
}

總結: 利用find可以在容器中找指定的元素,返回值是迭代器

find_if

按條件查找元素

函數原型:

  • find_if(iterator beg, iterator end, _Pred);
  // 按值查找元素,找到返回指定位置迭代器,找不到返回結束迭代器位置// beg 開始迭代器// end 結束迭代器// _Pred 函數或者謂詞(返回bool類型的仿函數)
#include <algorithm>
#include <vector>
#include <string>//內置數據類型
class GreaterFive{
public:bool operator()(int val){return val > 5;}
};void test01() {vector<int> v;for (int i = 0; i < 10; i++) {v.push_back(i + 1);}vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive());if (it == v.end()) {cout << "沒有找到!" << endl;}else {cout << "找到大于5的數字:" << *it << endl;}
}//自定義數據類型
class Person {
public:Person(string name, int age){this->m_Name = name;this->m_Age = age;}
public:string m_Name;int m_Age;
};class Greater20{
public:bool operator()(Person &p){return p.m_Age > 20;}};void test02() {vector<Person> v;//創建數據Person p1("aaa", 10);Person p2("bbb", 20);Person p3("ccc", 30);Person p4("ddd", 40);v.push_back(p1);v.push_back(p2);v.push_back(p3);v.push_back(p4);vector<Person>::iterator it = find_if(v.begin(), v.end(), Greater20());if (it == v.end()){cout << "沒有找到!" << endl;}else{cout << "找到姓名:" << it->m_Name << " 年齡: " << it->m_Age << endl;}
}

總結:find_if按條件查找使查找更加靈活,提供的仿函數可以改變不同的策略

adjacent_find

查找相鄰重復元素

函數原型:

  • adjacent_find(iterator beg, iterator end);
  // 查找相鄰重復元素,返回相鄰元素的第一個位置的迭代器// beg 開始迭代器// end 結束迭代器
#include <algorithm>
#include <vector>void test01(){vector<int> v;v.push_back(1);v.push_back(2);v.push_back(5);v.push_back(2);v.push_back(4);v.push_back(4);v.push_back(3);//查找相鄰重復元素vector<int>::iterator it = adjacent_find(v.begin(), v.end());if (it == v.end()) {cout << "找不到!" << endl;} else {cout << "找到相鄰重復元素為:" << *it << endl;}
}

總結:面試題中如果出現查找相鄰重復元素,記得用STL中的adjacent_find算法

binary_search

  • 查找指定元素是否存在

函數原型:

  • bool binary_search(iterator beg, iterator end, value);
  // 查找指定的元素,查到 返回true  否則false// 注意: 在**無序序列中不可用**// beg 開始迭代器// end 結束迭代器// value 查找的元素

示例:

#include <algorithm>
#include <vector>void test01(){vector<int>v;for (int i = 0; i < 10; i++){v.push_back(i);}//二分查找bool ret = binary_search(v.begin(), v.end(),2);if (ret){cout << "找到了" << endl;}else{cout << "未找到" << endl;}
}

總結:二分查找法查找效率很高,值得注意的是查找的容器中元素必須的有序序列

count

統計元素個數

函數原型:

  • count(iterator beg, iterator end, value);
  // 統計元素出現次數// beg 開始迭代器// end 結束迭代器// value 統計的元素
#include <algorithm>
#include <vector>//內置數據類型
void test01(){vector<int> v;v.push_back(1);v.push_back(2);v.push_back(4);v.push_back(5);v.push_back(3);v.push_back(4);v.push_back(4);int num = count(v.begin(), v.end(), 4);cout << "4的個數為: " << num << endl;
}//自定義數據類型
class Person
{
public:Person(string name, int age){this->m_Name = name;this->m_Age = age;}bool operator==(const Person & p){if (this->m_Age == p.m_Age){return true;}else{return false;}}string m_Name;int m_Age;
};void test02(){vector<Person> v;Person p1("劉備", 35);Person p2("關羽", 35);Person p3("張飛", 35);Person p4("趙云", 30);Person p5("曹操", 25);v.push_back(p1);v.push_back(p2);v.push_back(p3);v.push_back(p4);v.push_back(p5);Person p("諸葛亮",35);int num = count(v.begin(), v.end(), p);cout << "num = " << num << endl;
}

總結: 統計自定義數據類型時候,需要配合重載 operator==

count_if

按條件統計元素個數

函數原型:

  • count_if(iterator beg, iterator end, _Pred);
  // 按條件統計元素出現次數// beg 開始迭代器// end 結束迭代器// _Pred 謂詞
#include <algorithm>
#include <vector>class Greater4{
public:bool operator()(int val){return val >= 4;}
};//內置數據類型
void test01(){vector<int> v;v.push_back(1);v.push_back(2);v.push_back(4);v.push_back(5);v.push_back(3);v.push_back(4);v.push_back(4);int num = count_if(v.begin(), v.end(), Greater4());cout << "大于4的個數為: " << num << endl;
}//自定義數據類型
class Person{
public:Person(string name, int age){this->m_Name = name;this->m_Age = age;}string m_Name;int m_Age;
};class AgeLess35{
public:bool operator()(const Person &p){return p.m_Age < 35;}
};
void test02(){vector<Person> v;Person p1("劉備", 35);Person p2("關羽", 35);Person p3("張飛", 35);Person p4("趙云", 30);Person p5("曹操", 25);v.push_back(p1);v.push_back(p2);v.push_back(p3);v.push_back(p4);v.push_back(p5);int num = count_if(v.begin(), v.end(), AgeLess35());cout << "小于35歲的個數:" << num << endl;
}

**總結:**按值統計用count,按條件統計用count_if

常用排序算法

算法簡介:

  • sort //對容器內元素進行排序
  • random_shuffle //洗牌 指定范圍內的元素隨機調整次序
  • merge // 容器元素合并,并存儲到另一容器中
  • reverse // 反轉指定范圍的元素

sort

對容器內元素進行排序

函數原型:

  • sort(iterator beg, iterator end, _Pred);
  // 按值查找元素,找到返回指定位置迭代器,找不到返回結束迭代器位置//  beg    開始迭代器//  end    結束迭代器// _Pred  謂詞
#include <algorithm>
#include <vector>void myPrint(int val){cout << val << " ";
}void test01() {vector<int> v;v.push_back(10);v.push_back(30);v.push_back(50);v.push_back(20);v.push_back(40);//sort默認從小到大排序sort(v.begin(), v.end());for_each(v.begin(), v.end(), myPrint);cout << endl;//從大到小排序sort(v.begin(), v.end(), greater<int>());for_each(v.begin(), v.end(), myPrint);cout << endl;
}

總結:sort屬于開發中最常用的算法之一,需熟練掌握

random_shuffle

  • 洗牌 指定范圍內的元素隨機調整次序

函數原型:

  • random_shuffle(iterator beg, iterator end);
  // 指定范圍內的元素隨機調整次序// beg 開始迭代器// end 結束迭代器
#include <algorithm>
#include <vector>
#include <ctime>class myPrint{
public:void operator()(int val){cout << val << " ";}
};void test01(){srand((unsigned int)time(NULL));vector<int> v;for(int i = 0 ; i < 10;i++){v.push_back(i);}for_each(v.begin(), v.end(), myPrint());cout << endl;//打亂順序random_shuffle(v.begin(), v.end());for_each(v.begin(), v.end(), myPrint());cout << endl;
}

總結random_shuffle洗牌算法比較實用,使用時記得加隨機數種子

merge

兩個容器元素合并,并存儲到另一容器中

函數原型:

  • merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
  // 容器元素合并,并存儲到另一容器中// 注意: 兩個容器必須是**有序的**// beg1   容器1開始迭代器// end1   容器1結束迭代器// beg2   容器2開始迭代器// end2   容器2結束迭代器// dest    目標容器開始迭代器
#include <algorithm>
#include <vector>class myPrint{
public:void operator()(int val){cout << val << " ";}
};void test01(){vector<int> v1;vector<int> v2;for (int i = 0; i < 10 ; i++) {v1.push_back(i);v2.push_back(i + 1);}vector<int> vtarget;//目標容器需要提前開辟空間vtarget.resize(v1.size() + v2.size());//合并  需要兩個有序序列merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vtarget.begin());for_each(vtarget.begin(), vtarget.end(), myPrint());cout << endl;
}

總結merge合并的兩個容器必須的有序序列

reverse

  • 將容器內元素進行反轉

函數原型:

  • reverse(iterator beg, iterator end);
  // 反轉指定范圍的元素// beg 開始迭代器// end 結束迭代器
#include <algorithm>
#include <vector>class myPrint{
public:void operator()(int val){cout << val << " ";}
};void test01(){vector<int> v;v.push_back(10);v.push_back(30);v.push_back(50);v.push_back(20);v.push_back(40);cout << "反轉前: " << endl;for_each(v.begin(), v.end(), myPrint());cout << endl;cout << "反轉后: " << endl;reverse(v.begin(), v.end());for_each(v.begin(), v.end(), myPrint());cout << endl;
}

總結:reverse反轉區間內元素,面試題可能涉及到

常用拷貝和替換算法

  • 掌握常用的拷貝和替換算法

算法簡介:

  • copy // 容器內指定范圍的元素拷貝到另一容器中
  • replace // 將容器內指定范圍的舊元素修改為新元素
  • replace_if // 容器內指定范圍滿足條件的元素替換為新元素
  • swap // 互換兩個容器的元素

copy

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

函數原型:

  • copy(iterator beg, iterator end, iterator dest);
  // 按值查找元素,找到返回指定位置迭代器,找不到返回結束迭代器位置// beg  開始迭代器// end  結束迭代器// dest 目標起始迭代器
#include <algorithm>
#include <vector>class myPrint{
public:void operator()(int val){cout << val << " ";}
};void test01(){vector<int> v1;for (int i = 0; i < 10; i++) {v1.push_back(i + 1);}vector<int> v2;v2.resize(v1.size());copy(v1.begin(), v1.end(), v2.begin());for_each(v2.begin(), v2.end(), myPrint());cout << endl;
}

總結:利用copy算法在拷貝時,目標容器記得提前開辟空間

replace

將容器內指定范圍的舊元素修改為新元素

函數原型:

  • replace(iterator beg, iterator end, oldvalue, newvalue);
  // 將區間內舊元素 替換成 新元素// beg 開始迭代器// end 結束迭代器// oldvalue 舊元素// newvalue 新元素
#include <algorithm>
#include <vector>class myPrint{
public:void operator()(int val){cout << val << " ";}
};void test01(){vector<int> v;v.push_back(20);v.push_back(30);v.push_back(20);v.push_back(40);v.push_back(50);v.push_back(10);v.push_back(20);cout << "替換前:" << endl;for_each(v.begin(), v.end(), myPrint());cout << endl;//將容器中的20 替換成 2000cout << "替換后:" << endl;replace(v.begin(), v.end(), 20,2000);for_each(v.begin(), v.end(), myPrint());cout << endl;
}

總結:replace會替換區間內滿足條件的元素

replace_if

將區間內滿足條件的元素,替換成指定元素

函數原型:

  • replace_if(iterator beg, iterator end, _pred, newvalue);
  // 按條件替換元素,滿足條件的替換成指定元素// beg 開始迭代器// end 結束迭代器// _pred 謂詞// newvalue 替換的新元素
#include <algorithm>
#include <vector>class myPrint{
public:void operator()(int val){cout << val << " ";}
};class ReplaceGreater30{
public:bool operator()(int val){return val >= 30;}};void test01(){vector<int> v;v.push_back(20);v.push_back(30);v.push_back(20);v.push_back(40);v.push_back(50);v.push_back(10);v.push_back(20);cout << "替換前:" << endl;for_each(v.begin(), v.end(), myPrint());cout << endl;//將容器中大于等于的30 替換成 3000cout << "替換后:" << endl;replace_if(v.begin(), v.end(), ReplaceGreater30(), 3000);for_each(v.begin(), v.end(), myPrint());cout << endl;
}

總結:replace_if按條件查找,可以利用仿函數靈活篩選滿足的條件

swap

互換兩個容器的元素

函數原型:

  • swap(container c1, container c2);
  // 互換兩個容器的元素// c1容器1// c2容器2

示例:

#include <algorithm>
#include <vector>class myPrint{
public:void operator()(int val){cout << val << " ";}
};void test01(){vector<int> v1;vector<int> v2;for (int i = 0; i < 10; i++) {v1.push_back(i);v2.push_back(i+100);}cout << "交換前: " << endl;for_each(v1.begin(), v1.end(), myPrint());cout << endl;for_each(v2.begin(), v2.end(), myPrint());cout << endl;cout << "交換后: " << endl;swap(v1, v2);for_each(v1.begin(), v1.end(), myPrint());cout << endl;for_each(v2.begin(), v2.end(), myPrint());cout << endl;
}

總結:swap交換容器時,注意交換的容器要同種類型

常用算術生成算法

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

算法簡介:

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

  • fill // 向容器中添加元素

accumulate

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

函數原型:

  • accumulate(iterator beg, iterator end, value);
  // 計算容器元素累計總和// beg 開始迭代器// end 結束迭代器// value 起始值

示例:

#include <numeric>
#include <vector>
void test01(){vector<int> v;for (int i = 0; i <= 100; i++) {v.push_back(i);}int total = accumulate(v.begin(), v.end(), 0);cout << "total = " << total << endl;
}

總結:accumulate使用時頭文件注意是 numeric,這個算法很實用

fill

向容器中填充指定的元素

函數原型:

  • fill(iterator beg, iterator end, value);
  // 向容器中填充元素// beg 開始迭代器// end 結束迭代器// value 填充的值
#include <numeric>
#include <vector>
#include <algorithm>class myPrint{
public:void operator()(int val){cout << val << " ";}
};void test01(){vector<int> v;v.resize(10);//填充fill(v.begin(), v.end(), 100);for_each(v.begin(), v.end(), myPrint());cout << endl;
}

總結:利用fill可以將容器區間內元素填充為 指定的值

常用集合算法

算法簡介:

  • set_intersection // 求兩個容器的交集

  • set_union // 求兩個容器的并集

  • set_difference // 求兩個容器的差集

set_intersection

求兩個容器的交集

注意:兩個集合必須是有序序列

函數原型:

  • set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
// 求兩個集合的交集// beg1 容器1開始迭代器// end1 容器1結束迭代器// beg2 容器2開始迭代器// end2 容器2結束迭代器// dest 目標容器開始迭代器
#include <vector>
#include <algorithm>class myPrint{
public:void operator()(int val){cout << val << " ";}
};void test01(){vector<int> v1;vector<int> v2;for (int i = 0; i < 10; i++){v1.push_back(i);v2.push_back(i+5);}vector<int> vTarget;//取兩個里面較小的值給目標容器開辟空間vTarget.resize(min(v1.size(), v2.size()));//返回目標容器的最后一個元素的迭代器地址vector<int>::iterator itEnd = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());for_each(vTarget.begin(), itEnd, myPrint());cout << endl;
}

總結:

  • 求交集的兩個集合必須的有序序列
  • 目標容器開辟空間需要從兩個容器中取小值
  • 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 目標容器開始迭代器
#include <vector>
#include <algorithm>class myPrint{
public:void operator()(int val){cout << val << " ";}
};void test01(){vector<int> v1;vector<int> v2;for (int i = 0; i < 10; i++) {v1.push_back(i);v2.push_back(i+5);}vector<int> vTarget;//取兩個容器的和給目標容器開辟空間vTarget.resize(v1.size() + v2.size());//返回目標容器的最后一個元素的迭代器地址vector<int>::iterator itEnd = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());for_each(vTarget.begin(), itEnd, myPrint());cout << endl;
}

總結:

  • 求并集的兩個集合必須的有序序列
  • 目標容器開辟空間需要兩個容器相加
  • 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 目標容器開始迭代器
#include <vector>
#include <algorithm>class myPrint{
public:void operator()(int val){cout << val << " ";}
};void test01(){vector<int> v1;vector<int> v2;for (int i = 0; i < 10; i++) {v1.push_back(i);v2.push_back(i+5);}vector<int> vTarget;//取兩個里面較大的值給目標容器開辟空間vTarget.resize( max(v1.size() , v2.size()));//返回目標容器的最后一個元素的迭代器地址cout << "v1與v2的差集為: " << endl;vector<int>::iterator itEnd = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());for_each(vTarget.begin(), itEnd, myPrint());cout << endl;cout << "v2與v1的差集為: " << endl;itEnd = set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), vTarget.begin());for_each(vTarget.begin(), itEnd, myPrint());cout << endl;
}

總結:

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

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

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

相關文章

[JVM] JVM內存調優

&#x1f338;個人主頁:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;?熱門專欄: &#x1f9ca; Java基本語法(97平均質量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection與…

Spring Boot 從Socket 到Netty網絡編程(下):Netty基本開發與改進【心跳、粘包與拆包、閑置連接】

上一篇&#xff1a;《Spring Boot 從Socket 到Netty網絡編程&#xff08;上&#xff09;&#xff1a;SOCKET 基本開發&#xff08;BIO&#xff09;與改進(NIO)》 前言 前文中我們簡單介紹了基于Socket的BIO&#xff08;阻塞式&#xff09;與NIO&#xff08;非阻塞式&#xff0…

python編寫賽博朋克風格天氣查詢程序

工具介紹 這個天氣查詢工具是一個基于 Python 的桌面應用程序,使用了tkinter庫來創建圖形用戶界面(GUI),并通過requests庫調用 Open - Meteo API 獲取天氣數據。它具有賽博朋克風格的界面設計,提供了當前天氣信息、15 天天氣預報以及詳細的天氣數據展示,同時還包含溫度趨…

從二叉樹到 STL:揭開 set 容器的本質與用法

前言&#xff1a; 上次介紹完二叉搜索樹后&#xff0c;更新中斷了一段時間&#xff0c;先向大家致歉。最近學習狀態有些起伏&#xff0c;但我正在努力調整&#xff0c;相信很快會恢復節奏。今天我們繼續深入探討——關聯容器&#xff0c;它在算法和工程中都非常常見和重要。 1…

uv管理spaCy語言模型

本文記錄如何在使用uv管理python項目dependencies時&#xff0c;把spaCy的模型也納入其中. spaCy 一、spaCy簡介 spaCy是一個開源的自然語言處理&#xff08;NLP&#xff09;庫&#xff0c;它主要用于處理文本數據。它支持多種語言&#xff0c;包括英語、中文等。它是由Expl…

python執行測試用例,allure報亂碼且未成功生成報告

allure執行測試用例時顯示亂碼&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;?&#xfffd;&#xfffd;&#xfffd;&#xfffd;?&#xfffd;&#xfffd;&#xfffd;??&#xfffd;&#xfffd;&#xfffd;?&#xfffd;&am…

Rust 學習筆記:Box<T>

Rust 學習筆記&#xff1a;Box Rust 學習筆記&#xff1a;Box<T\>Box\<T> 簡介使用 Box\<T\> 在堆上存儲數據啟用帶有 box 的遞歸類型關于 cons 列表的介紹計算非遞歸類型的大小使用 Box\<T\> 獲取大小已知的遞歸類型 Rust 學習筆記&#xff1a;Box<…

英語寫作中“不少于(小于)”no less than替代no fewer than的用法

no less than 1 liter of water&#xff0c;no fewer than 100 people 是我們的傳統用法。現代英語有一個有趣的現象&#xff0c;就是less 代替fewer 形容可數名詞&#xff0c;例如&#xff1a; Do you have 10 courses each week? No. We have less. 顯然按嚴格語法應該是…

競品分析六大步驟

一、引言 在產品打磨、市場推廣或戰略定位過程中&#xff0c;我們常常會面臨一個關鍵任務——競品分析。一份系統的競品分析不僅能幫助我們知己知彼&#xff0c;優化產品策略&#xff0c;更能成為決策層制定方向的重要依據。競品分析到底該怎么做&#xff1f;今天我將結合自己的…

【Java Web】9.Maven高級

&#x1f4d8;博客主頁&#xff1a;程序員葵安 &#x1faf6;感謝大家點贊&#x1f44d;&#x1f3fb;收藏?評論?&#x1f3fb; 文章目錄 一、分模塊設計與開發 1.1 介紹 1.2 實踐 二、繼承與聚合 2.1 繼承 繼承關系 版本鎖定 2.2 聚合 2.3 繼承與聚合對比 三、…

MySQL 全量、增量備份與恢復

一.MySQL 數據庫備份概述 備份的主要目的是災難恢復&#xff0c;備份還可以測試應用、回滾數據修改、查詢歷史數據、審計等。之前已經學習過如何安裝 MySQL&#xff0c;本小節將從生產運維的角度了解備份恢復的分類與方法。 1 數據備份的重要性 在企業中數據的價值至關…

第六個微信小程序:教師工具集

源于工作需要&#xff0c;下面開始。 安裝及使用 | Taro 文檔 vscode 代碼管理 git 輔助 開發技術如上&#xff1a; 1.開始創建模板 taro4.1.1 $ taro init teachers-tools 2.用vsocde開始吧。 選擇 第二個文件夾找一。 (base) PS D:\react\teachers-tools> pnpm…

Linux 里 su 和 sudo 命令這兩個有什么不一樣?

《小菜狗 Linux 操作系統快速入門筆記》目錄&#xff1a; 《小菜狗 Linux 操作系統快速入門筆記》&#xff08;01.0&#xff09;文章導航目錄【實時更新】 Linux 是一個多用戶的操作系統。在 Linux 中&#xff0c;理論上來說&#xff0c;我們可以創建無數個用戶&#xff0c;但…

Elastic 獲得 AWS 教育 ISV 合作伙伴資質,進一步增強教育解決方案產品組合

作者&#xff1a;來自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通過搜索 AI 和云創新推動教育領域的數字化轉型。 我們非常高興地宣布&#xff0c;Elastic 已獲得 AWS 教育 ISV 合作伙伴資質。這一重要認證表明&#xff0c;Elastic 作為 …

服務器被攻擊了怎么辦

可以上一個高防IP或者AI云防護都是可以的。&#xff08;有效防御CC、APl接口、http、tcp、WEB應用掃描/爬蟲、SYN、WAF、DDOS、UDP、入侵、滲透、SQL注入、XSS跨站腳本攻擊、遠程惡意代碼執行、session fixation、Webshell攻擊、惡意請求&#xff0c;惡意掃描、暴力破解、CSRF等…

【學習筆記】Circuit Tracing: Revealing Computational Graphs in Language Models

Circuit Tracing: Revealing Computational Graphs in Language Models 替代模型(Replacement Model)&#xff1a;用更多的可解釋的特征來替代transformer模型的神經元。 歸因圖(Attribution Graph)&#xff1a;展示特征之間的相互影響&#xff0c;能夠追蹤模型生成輸出時所采用…

靈活控制,modbus tcp轉ethernetip的 多功能水處理方案

油田自動化和先進的油氣行業軟件為油氣公司帶來了諸多益處。其中包括&#xff1a; 1.自動化可以消除多余的步驟、減少人為錯誤并降低運行設備所需的能量&#xff0c;從而降低成本。 2.油天然氣行業不斷追求高水平生產。自動化可以更輕松地減少計劃外停機時間&#xff0c;從而…

是否存在路徑(FIFOBB算法)

題目描述 一個具有 n 個頂點e條邊的無向圖&#xff0c;該圖頂點的編號依次為0到n-1且不存在頂點與自身相連的邊。請使用FIFOBB算法編寫程序&#xff0c;確定是否存在從頂點 source到頂點 destination的路徑。 輸入 第一行兩個整數&#xff0c;分別表示n 和 e 的值&#xff08;1…

windows VeraCrypt – 磁盤加密工具

下載鏈接&#xff1a;夸克網盤分享 VeraCrypt一款跨平臺(Windows/Mac/Linux)的磁盤加密工具&#xff0c;提供多層級數據保護方案&#xff1a;虛擬加密盤&#xff1a;在文件中創建可掛載的加密虛擬磁盤全設備加密&#xff1a;支持分區/USB/硬盤等存儲設備的全盤加密系統盤加密&…

客戶體驗數據使用的三種視角——場景視角

當企業收集到大量的客戶體驗數據之后&#xff0c;應該如何應用&#xff1f;有哪些主要的使用場景和分析視角&#xff1f;體驗家團隊通過三篇文章&#xff0c;陸續介紹三種體驗數據的使用場景&#xff0c;以幫助企業更有效地利用體驗數據進行改進。 01 宏觀層次的“旅程視角” …