当前位置: 首页 > news >正文

C++语言之函数对象与算法

在 C++ 中,函数对象(Function Object)也叫仿函数(Functor),是一个类,这个类重载了()运算符。从概念上讲,它的行为类似于一个函数,可以像调用函数一样来调用这个类的对象。
 

例如,下面是一个简单的函数对象类:
        class Add {
        public:
            int operator()(int a, int b) {
                return a + b;
            }
        };

        int main()

        {

                //函数对象(仿函数)

                Add add;

                return 0;

        }

这个Add类就是一个函数对象。它重载了()运算符,使得该类的对象可以像函数一样被调用。


作用:为算法提供策略

谓词

返回值为bool类型的普通函数或仿函数都叫谓词


有一个参数叫一元谓词

有两个参数叫二元谓词

#include <iostream>

using namespace std;

//谓词

bool method01()

{        }

//谓词

class MyClass{

public:

        bool operator()()

        {        }

};

//一元谓词

bool method02(int x)

{

}

//二元谓词

bool method03(int x,int y)

{

}

int main()

{

        return 0;

}

小括号调用问题

#include <iostream>

using namespace std;

class MyClass

{

 public:

        MyClass()

        {

                cout<<"无参构造"<<endl;

        }

        MyClass(int x)

        {

                cout<<"有参构造"<<endl;

        }

        bool operator()()

        {

                cout<<"自定义谓词"<<endl;

                return true;

        }

};

int main()

{

        //函数对象(仿函数)

        //MyClass c();        //创建对象后有()不知道调用什么

        //MyClass c;        //此时调用无参构造

        //MyClass c(10);        //此时调用有参构造

        //MyClass * c = new MyClass;        //此时调用无参构造

        MyClass * c = new MyClass(10);        //此时调用有参构造

        bool b = (*c)()        //用已经创建的对象后有()是调用重载的()运算符


        return 0;

}

内建函数对象

C++提供的函数对象              

 算法类函数对象

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>//取反仿函数

注意:6个算数类函数对象,除了negate是一元运算,其他都是二元运算

#include<iostream>

using namespace std;

int main()

{

        //template<class T> T plus<T>//加法仿函数

        plus<int> pl;

        int x = pl(10,21);

        cout<<x<<endl;

        //template<class T> T minus<T>//减法仿函数

        minus<int> min;

        int y = min(10,21);

        cout<<y<<endl;

        //....

        //template<class T> T negate<T>//取反仿函数,不能对bool取反

        negate<int> neg;

        int z = neg(-10);

        cout<<z<<endl;

        
        return 0;

}

关系运算类函数对象

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 <iostream>

#include <string>

#include <stdlib.h>

#incldue <string.h>

using namespace std;

int main()

{

       // template<class T>bool equal_to<T>//等于

        equal_to<int> eq;

        bool b1 = eq(1,1);

        cout<<b1<<endl;

        char* str01 = (char*) calloc(6,1);

        strcpy(str01,"hello");

        char* str02 = (char*)calloc(6,1);

        strcpy(str02,"hello");

        

        string s01 = sstr01;

        string s02 = str02;

        equal_to<string> eq;

        bool b3 = eq(s01,s02);

        cout<<b3<<endl;

        

        return 0;

}

逻辑运算类运算函数

template<class T>bool logical_and<T> //逻辑与

template<class T>bool logical_or<T>//逻辑或

template<class T>bool logical_not<T>//逻辑非


注意:这三个逻辑运算类运算函数,not为一元谓词,其余为二元谓词

#include<iostream>

using namespace std;

int main()

{

        //template<class T>bool logical_and<T> //逻辑与

        logical_and<bool> a;

        bool b1 = a(true,true);

        cout<<b1<<endl;

        
        return 0;

}

适配器

在 C++ 中,适配器(Adapter)是一种设计模式的实现,它将一个类的接口转换成另一个接口,以满足用户的需求。适配器就像是一个转换器,使得原本不兼容的接口能够协同工作。

从广义上来说,C++ 中有函数适配器、容器适配器等不同类型。

函数对象适配器

以对象作为适配器


使用:

        bind2nd将绑定的数据放置第二个参数位置

        bind1st将绑定的数据放置在第一个参数位置

步骤:

        1,创建一个类

        2,使该类继承于binary_function

        3,泛型萃取

                第一泛型为重载的()运算符中第一个形参的数据类型

                第二泛型为重载的()运算符中第二个形参的数据类型

                第三泛型为重载的()运算符中返回值的数据类型

        4,在该类中重载()运算符,尾部加const

        5,创建该类对象

        6,使用算法,在算法适配器中使用bind1st或bind2nd绑定该对象与传入的值

//1,2,3

class Adapter:public binary_function<int,int,void>

{

//4

public:

         void operator()(int x,int y)const

        {

                

        }       

};

//5

Adapter a;

for_each(v.bedin(),v.end(),bind1st(a,10));

函数指针适配器

以全局函数作为适配器


使用:

        bind2nd将绑定的数据放置在第二个参数位置

        bind1st将绑定的数据放置在第一个参数位置
        ptr_fun(函数名)

步骤:

        1,定义一个全局变量,该函数两个参数

        2,使用算法,在算法适配器中使用bind1st或bind2nd绑定该函数与传入的值

#include<iostream>

#include<set>

#include<algorithm>

void my_method(int x,int y)

{

        cout<<x<<endl;

        cout<<y<<end;

}

int main()

{

        set<int> 5;

        s.insert(1);

        s.insert(2);

        s.insert(3);

        s.insert(4);

        for_each(s.begin(),s.end(),bind2nd(ptr_fun(my_method),100)};

        return 0;

成员函数适配器

以成员函数作为适配器


使用:

        bind2nd将绑定的数据放置到第二个参数位置

        bind1st将绑定的数据放置到第一个参数的位置

        

        mem_fun_ref(&类名::函数名):注意其包含的函数只能有一个参数

步骤:

        1,创建一个类

        2,在该类中编写成员函数

        3,使用算法,在算法适配器中使用mem_fun_ref包括该函数

注意:

        集合中存储的对象所在的类与成员函数所在的类为同一个类

        该函数必须是无参的

        集合中获取的数据就是该类中的this

#include <iostream>

#include <list>

#include <algorithm>

using namespace std;

class Data

{

 public:

        int x;

        Data(int x):x(x){        }

        void my_method()

        {

                cout<<this->x<<endl;       

        }      

};

int main()

{

        list<Data> l;

        l.push_back(Data(1));

        l.push_back(Data(2));

        l.push_back(Data(3));

        l.push_back(Data(4));

        for_each(l.begin(),l.end(),mem_fun_ref(&Data::my_method));

        

        return 0;

}

取反适配器

not1        一元函数对象取反

not2        二元函数对象取反

#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;

void show(int x)

{

        cout<<x<<",";

}

bool compare(int x,int y)

{

        return x<y;

}

class Myclass:public binary_function<int,int,bool>

{

public:

        bool operator()(int x,int y)const

        {

                return x>y;

        }        

};

int main()

{

        vector<int> nums;

        nums.push_back(2);
        nums.push_back(1);
        nums.push_back(3);
        nums.push_back(6);
        nums.push_back(9);

  

        for_each(nums.begin(),nums.end(),ptr_fun(show));

        cout << endl;
        //查找 vector 中第一个大于 5 的值
        // vector<int>::iterator it =
        find_if(nums.begin(),nums.end(),bind2nd(ptr_fun(dy5),5));
        // auto it =
        find_if(nums.begin(),nums.end(),bind2nd(MyClass(),5));
        auto it =
        find_if(nums.begin(),nums.end(),not1(bind2nd(MyClass(),5)));
        cout << *it << endl;
        //排序算法
        sort(nums.begin(),nums.end(),not2(less<int>()));
        for_each(nums.begin(),nums.end(),ptr_fun(show));
        cout << endl;
        return 0;

}

算法


遍历

for_each

/*
遍历算法 遍历容器元素
@param beg 开始迭代器
@param end 结束迭代器
@param _callback 函数回调或者函数对象
@return 函数对象
*/
for_each(iterator beg, iterator end, _callback);
//基本使用
#include <iostream>
#include <deque>
#incldue <algorithm>
using namespace std;
void myMethod(int x)
{
cout<<x<<",";
}
int main()
{
deque<int> d;
d.push_back(1);
d.push_back(2);
d.push_back(3);
d.push_back(4);
d.push_back(5);
for_each(d.begin(),d.end(),myMthod);
return 0;
}
案例2:lamba表达式
注意:c++11及以上版本才可使用
作用:简化函数
语法:
[](形参列表)
{
函数体
}
#include <iostream>
#include <deque>
#include <algorithm>
using namespace std;

void myMethod(int x)
{
cout<<x<<",";
}
int mian()
{
deque<int> d;
d.push_back(1);
d.push_back(2);
d.push_back(3);
d.push_back(4);
d.push_back(5);
for_each(d.begin(),d.end(),[](int x)
{
cout<<x<<",";
});
return 0;
}
// 案例 3: 遍历存储自定义类型的集合
class Data{
private:
        int x;
        int y;
public:
        Data(int x,int y):x(x),y(y){}
        void showData()
        {
                cout << "x = " << x << "\ty = " << y << endl;
        }
};
void fun02()
{
        deque<Data> d;
        d.push_back(Data(1,11));
        d.push_back(Data(2,22));
        d.push_back(Data(3,33));
        for_each(d.begin(),d.end(),[](Data& data){
                data.showData();
        });
}

transform

作用:搬运

语法:

        /*

        transform 算法 将指定容器区间元素搬运到另一容器中
         注意 :transform 不会给目标容器分配内存,所以需要我们提前分配好内存
        @param beg1 源容器开始迭代器
        @param end1 源容器结束迭代器
        @param beg2 目标容器开始迭代器
        @param _cakkback 回调函数或者函数对象
        @return 返回目标容器迭代器
        */
        transform(iterator beg1, iterator end1, iterator beg2, _callbakc);
        /*
         transform 算法 将指定容器区间元素搬运到另一容器中
        注意:transform 不会给目标容器分配内存,所以需要我们提前分配好内存
        @param beg1 源容器 1 开始迭代器
        @param end1 源容器 1 结束迭代器
        @param beg2 源容器 2 开始迭代器
        @param result 结果
        @param _cakkback 回调函数或者函数对象
        @return 返回目标容器迭代器
        */
        transform(iterator beg1, iterator end1, iterator beg2,iterator result, _callbakc);

#include <iostream>

#include <vector>
#include <list>
#include <algorithm>
using namespace std;
void fun01()
{
        //定义一个容器存储员工的工资
        vector<double> mm;
        mm.push_back(2100);
        mm.push_back(21000);
        mm.push_back(6100);
        mm.push_back(4000);
        mm.push_back(16000);
        //本月工资涨 200
        list<double> ml;
        ml.resize(mm.size());
transform(mm.begin(),mm.end(),ml.begin(),[](double x)
{
        return x+200;
});
for_each(ml.begin(),ml.end(),[](double m){
        cout << m << endl;
});
}
int main(int argc, char const *argv[])
{
        vector<double> mm;
        mm.push_back(2100);
        mm.push_back(21000);
        mm.push_back(6100);
        mm.push_back(4000);
        mm.push_back(16000);
        vector<double> mm02;
        mm02.push_back(210);
        mm02.push_back(2100);
        mm02.push_back(610);
        mm02.push_back(400);
        mm02.push_back(1600);
        vector<double> mm03;
        mm03.resize(mm.size());
        transform(mm.begin(),mm.end(),mm02.begin(),mm03.begin(),[](double x,double y){
        return x+y;
});
for_each(mm03.begin(),mm03.end(),[](double m){
        cout << m << endl;
});
        return 0;
}

 查找算法

find

作用:查找
/*
find 算法 查找元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 查找的元素
@return 返回查找到元素对应的迭代器
*/
find(iterator beg, iterator end, value)
void test01 ()
{
        vector < int > vs ;
        vs . push_back ( 12 );
        vs . push_back ( 15 );
        vs . push_back ( 11 );
        vs . push_back ( 13 );
        vs . push_back ( 14 );
vector < int > :: iterator it = find ( vs . begin (), vs . end (), 13 );
if ( it != vs . end ())
{
        cout << " 找到了 " << endl ;
}
else {
        cout << " 不存在 " << endl ;
}
}

 find_if

作用:条件查找

/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback 回调函数或者谓词 ( 返回 bool 类型的函数对象 )
@return 返回查找到元素对应的迭代器
*/
find_if(iterator beg, iterator end, _callback)
bool myIf ( int x )
{
        return x > 13 ;
}
void test02 ()
{
        vector < int > vs ;
        vs . push_back ( 12 );
        vs . push_back ( 15 );
        vs . push_back ( 11 );
        vs . push_back ( 13 );
        vs . push_back ( 14 );
        vector < int > :: iterator it = find_if ( vs . begin (), vs . end (), myIf );
        cout << * it << endl ;
}

 adjacent_find

作用:查找相邻重复元素

语法:

/**
*adjacent_find 算法 查找相邻重复元素
*@param beg 容器开始迭代器
*@param end 容器结束迭代器
*@param _callback 回调函数或者谓词 ( 返回 bool 类型的函数对象 )
*@return 返回相邻元素的第一个位置的迭代器
**/
adjacent_find(iterator beg, iterator end, _callback);
10 20 30 30 40
示例:
void test03 ()
{
        vector < int > vs ;
        vs . push_back ( 12 );
        vs . push_back ( 15 );
        vs . push_back ( 11 );
        vs . push_back ( 11 );
        vs . push_back ( 13 );
        vector < int > :: iterator it = adjacent_find ( vs . begin (), vs . end ());
        cout << * it << endl ;
}

 binary_search

作用:二分查找

语法:        

/*
注意 : 在无序序列中不可用
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 查找的元素
@return bool 查找返回 true 否则 false
*/
bool binary_search(iterator beg, iterator end, value);
void test04 ()
{
        vector < int > vs ;
        vs . push_back ( 1 );
        vs . push_back ( 3 );
        vs . push_back ( 5 );
        vs . push_back ( 7 );
        vs . push_back ( 9 );
        bool b = binary_search ( vs . begin (), vs . end (), 7 );
        if ( b ){
                cout << " 存在 " << endl ;
        } else {
                cout << " 不存在 " << endl ;
        }
}

 count

作用:统计

语法:        

/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 回调函数或者谓词 ( 返回 bool 类型的函数对象 )
@return int 返回元素个数
*/
count(iterator beg, iterator end, value);
#include <set>
void test05 ()
{
        multiset < int > s ;
        s . insert ( 1 );
        s . insert ( 2 );
        s . insert ( 2 );
        s . insert ( 2 );
        s . insert ( 5 );
        int num = count ( s . begin (), s . end (), 2 );
        cout << num << endl ;
}

 count_if

作用:条件统计

语法:

/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback 回调函数或者谓词 ( 返回 bool 类型的函数对象 )
@return int 返回元素个数
*/
count_if(iterator beg, iterator end, _callback)
void test06 ()
{
        multiset < int > s ;
        s . insert ( 1 );
        s . insert ( 2 );
        s . insert ( 2 );
        s . insert ( 3 );
        s . insert ( 5 );
        //统计容器中大于 2 的数
        int num = count_if ( s . begin (), s . end (), bind2nd ( greater < int > (), 2 ));
        cout << num << endl ;
        //统计容器中小于 2 的数
        int num02 = count_if ( s . begin (), s . end (), bind2nd ( less < int > (), 2 ));
        cout << num02 << endl ;
}

 排序算法

merge

作用:合并

语法:

/*
注意 : 两个容器必须是有序的
@param beg1 容器 1 开始迭代器
@param end1 容器 1 结束迭代器
@param beg2 容器 2 开始迭代器
@param end2 容器 2 结束迭代器
@param dest 目标容器开始迭代器
*/
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)
void test01 ()
{
vector < int > v1 ;
        v1 . push_back ( 1 );
        v1 . push_back ( 3 );
        v1 . push_back ( 5 );
vector < int > v2 ;
        v2 . push_back ( 2 );
        v2 . push_back ( 4 );
        v2 . push_back ( 6 );
vector < int > v3 ;
        v3 . resize ( v1 . size () + v2 . size ());
        merge ( v1 . begin (), v1 . end (), v2 . begin (), v2 . end (), v3 . begin ());
for_each ( v3 . begin (), v3 . end (),[]( int x ){
cout << x << " " ;
});
        cout << endl ;
}

 sort

作用:排序

语法:

/*
@param beg 容器 1 开始迭代器
@param end 容器 1 结束迭代器
@param _callback 回调函数或者谓词 ( 返回 bool 类型的函数对象 )
*/
sort(iterator beg, iterator end, _callback)
void test02 ()
{
vector < int > vs ;
vs . push_back ( 10 );
vs . push_back ( 13 );
vs . push_back ( 9 );
vs . push_back ( 4 );
vs . push_back ( 18 );
for_each ( vs . begin (), vs . end (),[]( int x ){
        cout << x << " " ;
});
        cout << endl ;
// 默认从小到大
sort ( vs . begin (), vs . end ());
for_each ( vs . begin (), vs . end (),[]( int x ){
        cout << x << " " ;
});
cout << endl ;
sort ( vs . begin (), vs . end (),[]( int x , int y ){
        return x > y ;
});
for_each ( vs . begin (), vs . end (),[]( int x ){
        cout << x << " " ;
});
        cout << endl ;
}

 random_shuffle

作用:打乱

语法:

/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
*/
random_shuffle(iterator beg, iterator end)
void test04 ()
{
vector < int > vs ;
vs . push_back ( 1 );
vs . push_back ( 2 );
vs . push_back ( 3 );
vs . push_back ( 4 );
vs . push_back ( 5 );
random_shuffle ( vs . begin (), vs . end ());
for_each ( vs . begin (), vs . end (),[]( int x ){
cout << x << " " ;
});
cout << endl ;
}

 reverse

作用:翻转

语法:

/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
*/
reverse(iterator beg, iterator end)
void test05 ()
{
vector < int > vs ;
vs . push_back ( 31 );
vs . push_back ( 2 );
vs . push_back ( 23 );
vs . push_back ( 14 );
vs . push_back ( 5 );
sort ( vs . begin (), vs . end ());
for_each ( vs . begin (), vs . end (),[]( int x ){
        cout << x << " " ;
});
cout << endl ;
reverse ( vs . begin (), vs . end ());
for_each ( vs . begin (), vs . end (),[]( int x ){
        cout << x << " " ;
});
        cout << endl ;
}

 拷贝与替换

copy

作用:拷贝

语法:

/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param dest 目标起始迭代器
*/
copy(iterator beg, iterator end, iterator dest)
void test01()
{
vector<int> vs;
vs.push_back(31);
vs.push_back(2);
vs.push_back(23);
vs.push_back(14);
vs.push_back(5);
vector<int> newVs;
newVs.resize(vs.size());
copy(vs.begin(),vs.end(),newVs.begin());
for_each(newVs.begin(),newVs.end(),[](int x){
        cout << x << endl;
});
}

 replace

作用:替换

语法:

/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param oldvalue 旧元素
@param oldvalue 新元素
*/
replace(iterator beg, iterator end, oldvalue, newvalue)
void test02 ()
{
vector < int > vs ;
vs . push_back ( 31 );
vs . push_back ( 2 );
vs . push_back ( 23 );
vs . push_back ( 14 );
vs . push_back ( 5 );
replace ( vs . begin (), vs . end (), 2 , 20 );
for_each ( vs . begin (), vs . end (),[]( int x ){
        cout << x << endl ;
});
}

 replace_if

作用:条件替换

/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback 函数回调或者谓词 ( 返回 Bool 类型的函数对象 )
@param oldvalue 新元素
*/
replace_if(iterator beg, iterator end, _callback, newvalue)
void test03 ()
{
vector < int > vs ;
vs . push_back ( 31 );
vs . push_back ( 2 );
vs . push_back ( 23 );
vs . push_back ( 14 );
vs . push_back ( 5 );
replace_if ( vs . begin (), vs . end (),[]( int x ){
        return x < 20 ;
}, 20 );
for_each ( vs . begin (), vs . end (),[]( int x ){
        cout << x << endl ;
});
}

 swap

作用:交换

语法:      

/*
@param c1 容器 1
@param c2 容器 2
*/
swap(container c1, container c2)
void test04 ()
{
vector < int > v01 ;
v01 . push_back ( 1 );
v01 . push_back ( 2 );
v01 . push_back ( 3 );
v01 . push_back ( 4 );
v01 . push_back ( 5 );
vector < int > v02 ;
v02 . push_back ( 6 );
v02 . push_back ( 7 );
v02 . push_back ( 8 );
        cout << " 交换前 :" << endl ;
for_each ( v01 . begin (), v01 . end (),[]( int x ){
        cout << x << " " ;
});
        cout << endl ;
for_each ( v02 . begin (), v02 . end (),[]( int x ){
        cout << x << " " ;
});
        cout << endl ;
swap ( v01 , v02 );
cout << " 交换后 :" << endl ;
for_each ( v01 . begin (), v01 . end (),[]( int x ){
        cout << x << " " ;
});
        cout << endl ;
for_each ( v02 . begin (), v02 . end (),[]( int x ){
        cout << x << " " ;
});
cout << endl ;
}

 常用算数生成算法

accumulate

作用:计算容器内元素累计总和

语法:

/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 累加值
@return int 总和
*/
accumulate(iterator beg, iterator end, value)
void test01 ()
{
vector < int > v01 ;
v01 . push_back ( 1 );
v01 . push_back ( 2 );
v01 . push_back ( 3 );
v01 . push_back ( 4 );
v01 . push_back ( 5 );
int sum = 0 ;
sum = accumulate ( v01 . begin (), v01 . end (), 0 );
cout << sum << endl ;
}

fill

作用 : 指定的值赋给指定范围内的所有元素
语法:
/*
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value t 填充元素
*/
fill(iterator beg, iterator end, value)

 void test02()

{
vector<int> v01;
v01.push_back(1);
v01.push_back(2);
v01.push_back(3);
v01.push_back(4);
v01.push_back(5);
fill(v01.begin(),v01.end(),10);
for_each(v01.begin(),v01.end(),[](int x){
cout << x << " ";
});
cout << endl;
}

 set_intersection

作用:获取交集

语法:

/*
注意 : 两个集合必须是有序序列
@param beg1 容器 1 开始迭代器
@param end1 容器 1 结束迭代器
@param beg2 容器 2 开始迭代器
@param end2 容器 2 结束迭代器
@param dest 目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址
*/
set_intersection(iterator beg1, iterator end1, iterator beg2, iteratorend2, iterator dest)
void test03()
{
vector<int> v01;
v01.push_back(1);
v01.push_back(2);
v01.push_back(3);
v01.push_back(4);
v01.push_back(5);
vector<int> v02;
v02.push_back(1);
v02.push_back(4);
v02.push_back(7);
vector<int> v03;
//back_inserter: 获取一个插入迭代器
set_intersection(v01.begin(),v01.end(),v02.begin(),v02.end(),back_inserter(v03));
for_each(v03.begin(),v03.end(),[](int x){
        cout << x << " ";
});
cout << endl;
}

 set_union

作用:获取并集

语法:

/*
注意 : 两个集合必须是有序序列
@param beg1 容器 1 开始迭代器
@param end1 容器 1 结束迭代器
@param beg2 容器 2 开始迭代器
@param end2 容器 2 结束迭代器
@param dest 目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址
*/
set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)
void test04()
{
vector<int> v01;
v01.push_back(1);
v01.push_back(2);
v01.push_back(3);
v01.push_back(4);
v01.push_back(5);
vector<int> v02;
v02.push_back(1);
v02.push_back(4);
v02.push_back(7);
vector<int> v03;
//back_inserter: 获取一个插入迭代器
set_union(v01.begin(),v01.end(),v02.begin(),v02.end(),back_inserter(v0
3));
for_each(v03.begin(),v03.end(),[](int x){
        cout << x << " ";
});
cout << endl;
}

 set_difference

作用:取差集

差集 :A B 的差集 , 就是 A 中有 B 中没有的元素集合 , 反之 B A 取差集 , 就是 B 中有 A 中没有的元素集合
语法:
/*
注意 : 两个集合必须是有序序列
@param beg1 容器 1 开始迭代器
@param end1 容器 1 结束迭代器
@param beg2 容器 2 开始迭代器
@param end2 容器 2 结束迭代器
@param dest 目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址
*/
set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)

void test05 ()
{
vector < int > v01 ;
v01 . push_back ( 1 );
v01 . push_back ( 3 );
v01 . push_back ( 5 );
v01 . push_back ( 7 );
v01 . push_back ( 9 );
vector < int > v02 ;
v02 . push_back ( 9 );
v02 . push_back ( 11 );
v02 . push_back ( 13 );
vector < int > v03 ;
//back_inserter: 获取一个插入迭代器
set_difference ( v01 . begin (), v01 . end (), v02 . begin (), v02 . end (), back_inserter ( v03 ));
for_each ( v03 . begin (), v03 . end (),[]( int x ){
cout << x << " " ;
});
cout << endl ;
}

相关文章:

C++语言之函数对象与算法

在 C 中&#xff0c;函数对象&#xff08;Function Object&#xff09;也叫仿函数&#xff08;Functor&#xff09;&#xff0c;是一个类&#xff0c;这个类重载了()运算符。从概念上讲&#xff0c;它的行为类似于一个函数&#xff0c;可以像调用函数一样来调用这个类的对象。 …...

Fakelocation Server服务器/专业版 Windows11

前言:需要Windows11系统 Fakelocation开源文件系统需求 Windows11 | Fakelocation | 任务一 打开 PowerShell&#xff08;以管理员身份&#xff09;命令安装 Chocolatey Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProto…...

java使用itext生成pdf

一、利用Adobe Acrobat DC软件创建pdf模板 备好Adobe Acrobat DC软件 1.excel/jpg/png文件转pdf文件 右击打开我们要转换的文件 2.然后点击 添加 域 3.可以看到域的名字 4.调整字体大小/对齐方式等 5.保存 二&#xff0c;代码部分 首先 上依赖 <dependency><group…...

【PPTist】添加PPT模版

前言&#xff1a;这篇文章来探索一下如何应用其他的PPT模版&#xff0c;给一个下拉菜单&#xff0c;列出几个项目中内置的模版 PPT模版数据 &#xff08;一&#xff09;增加菜单项 首先在下面这个菜单中增加一个“切换模版”的菜单项&#xff0c;点击之后在弹出框中显示所有的…...

AmazonS3集成minio实现https访问

最近系统全面升级到https&#xff0c;之前AmazonS3大文件分片上传直接使用http://ip:9000访问minio的方式已然行不通&#xff0c;https服务器访问http资源会报Mixed Content混合内容错误。 一般有两种解决方案&#xff0c;一是升级minio服务&#xff0c;配置ssl证书&#xff0c…...

适配屏幕px、rem单位换算, 将 pxToRem 函数设置为一个全局工具如:在 utils.js 文件、SCSS/Mixin 定义

页面的宽度适配&#xff1a; 假设页面的根元素&#xff08;html&#xff09;的字体大小设置为动态值&#xff08;常用 rem 单位适配时的做法&#xff09;&#xff0c; 比如 html { font-size: (屏幕宽度 / 设计稿宽度) }。如果根元素的字体大小为 1rem 屏幕宽度 / 1920px&…...

H.265流媒体播放器EasyPlayer.js播放器提示MSE不支持H.265解码可能的原因

随着人工智能和机器学习技术的应用&#xff0c;流媒体播放器将变得更加智能&#xff0c;能够根据用户行为和偏好提供个性化的内容推荐。总体而言&#xff0c;流媒体播放器的未来发展将更加注重技术创新和用户互动&#xff0c;以适应不断变化的市场需求和技术进步。 提示MSE不支…...

医学图像语义分割:前列腺肿瘤、颅脑肿瘤、腹部多脏器 MRI、肝脏 CT、3D肝脏、心室

医学图像语义分割&#xff1a;前列腺肿瘤、颅脑肿瘤、腹部多脏器 MRI、肝脏 CT、3D肝脏、心室 语义分割网络FCN&#xff1a;通过将全连接层替换为卷积层并使用反卷积上采样&#xff0c;实现了第一个端到端的像素级分割网络U-Net&#xff1a;采用对称的U形编解码器结构&#xff…...

16. 指针类型和步长概念问题

1. 项目场景&#xff1a; ➣ Jack Qiao对米粒说&#xff1a;“今天有道友遇到一个问题&#xff0c;举个栗子数组 arr[5] { 0 };道友发现&arr[0] 1与&arr 1打印出来的地址竟然不同。”米粒测试后果然是这样。 2. 问题描述 ☑ 举个栗子&#xff1a;数组 arr[5] { 0…...

【电路笔记】-布尔逻辑AND函数

逻辑AND函数 文章目录 逻辑AND函数1、概述2、逻辑 AND 函数 仅当所有输入均为 true 时&#xff0c;逻辑与函数输出才为 true&#xff0c;否则输出为 false。 1、概述 布尔代数基于逻辑函数&#xff0c;其中每个布尔函数&#xff08;例如逻辑 AND 函数&#xff09;通常具有一个…...

数据结构C语言描述3(图文结合)--双链表、循环链表、约瑟夫环问题

前言 这个专栏将会用纯C实现常用的数据结构和简单的算法&#xff1b;有C基础即可跟着学习&#xff0c;代码均可运行&#xff1b;准备考研的也可跟着写&#xff0c;个人感觉&#xff0c;如果时间充裕&#xff0c;手写一遍比看书、刷题管用很多&#xff0c;这也是本人采用纯C语言…...

wend看源码-APISJON

项目地址 腾讯APIJSON官方网站 定义 APIJSON 可以定义为一个面向HTTP 协议的JSON 规范&#xff0c;一个面向数据访问层的ORM 框架。其主要工作流程包括&#xff1a;前端按照既定格式组装 JSON 请求报文&#xff0c;通过 APIJSON-ORM 将这些报文直接转换为 SQL 语句&#xff0c…...

CSS(8):盒子阴影与文字阴影

一&#xff1a;盒子阴影text-shadow属性 1.box-shadow&#xff1a;h-shadow v-shadow blur spread color inset; 默认的是外部阴影outset&#xff0c;不能写在代码上 2.鼠标经过盒子后的阴影 rgba透明度 3.文字阴影 text-shadow:水平偏移 垂直偏移 模糊度 阴影颜色; 注意点…...

Hadoop 系列 MapReduce:Map、Shuffle、Reduce

文章目录 前言MapReduce 基本流程概述MapReduce 三个核心阶段详解Map 阶段工作原理 Shuffle 阶段具体步骤分区&#xff08;Partition&#xff09;排序&#xff08;Sort&#xff09;分组&#xff08;Combine 和 Grouping&#xff09; Reduce 阶段工作原理 MapReduce 应用场景Map…...

web——sqliabs靶场——第十三关——报错注入+布尔盲注

发现是单引号加括号闭合的 尝试联合注入 发现不太行&#xff0c;那尝试报错注入。 测试报错注入 unameadmin) and updatexml(1,0x7e,3) -- &passwdadmin&submitSubmit 爆数据库 unameadmin) and updatexml(1,concat(0x7e,database(),0x7e),3) -- &passwdadmin&a…...

调大Vscode资源管理器字体

对于调整资源管理器字体大小&#xff08;也就是下图红框&#xff09;&#xff0c;查找了网上很多方法。要么介绍的方法是调整了代码字体&#xff0c;要么是调节了终端字体&#xff0c;要么是通过整体放缩实现的调整&#xff0c;总之都不合适。 唯一的调整方法是在几篇CSDN里看到…...

【新人系列】Python 入门(十一):控制结构

✍ 个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4dd; 专栏地址&#xff1a;https://blog.csdn.net/newin2020/category_12801353.html &#x1f4e3; 专栏定位&#xff1a;为 0 基础刚入门 Python 的小伙伴提供详细的讲解&#xff0c;也欢迎大佬们…...

后端开发详细学习框架与路线

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;后端开发 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 为帮助你合理安排时间&#xff0c;以下是结合上述学习内容的阶段划分与时间分配建议。时间安排灵活&a…...

类文件结构详解.上

字节码 在 Java 中&#xff0c;JVM 可以理解的代码就叫做字节码&#xff08;即扩展名为 .class 的文件&#xff09;&#xff0c;它不面向任何特定的处理器&#xff0c;只面向虚拟机。Java 语言通过字节码的方式&#xff0c;在一定程度上解决了传统解释型语言执行效率低的问题&…...

【K8S问题系列 |18 】如何解决 imagePullSecrets配置正确,但docker pull仍然失败问题

如果 imagePullSecrets 配置正确&#xff0c;但在执行 docker pull 命令时仍然失败&#xff0c;可能存在以下几种原因。以下是详细的排查步骤和解决方案。 1. 检查 Docker 登录凭证 确保你使用的是与 imagePullSecrets 中相同的凭证进行 Docker 登录&#xff1a; 1.1 直接登录…...

Vue+Springboot用Websocket实现协同编辑

1. 项目介绍 在本文中&#xff0c;我们将介绍如何使用Vue.js和Spring Boot实现一个支持多人实时协同编辑的Web应用。通过WebSocket技术&#xff0c;我们可以实现文档的实时同步&#xff0c;让多个用户同时编辑同一份文档。 2. 技术栈 前端&#xff1a;Vue.js 3 Vuex后端&am…...

高阶C语言补充:柔性数组

C99中&#xff0c;结构体中最后一个元素允许时未知大小的数组&#xff0c;这就叫做柔性数组成员。 vs编译器也支持柔性数组。 之所以把柔性数组单独列出&#xff0c;是因为&#xff1a; 1、柔性数组是建立在结构体的基础上的。 2、柔性数组的使用用到了动态内存分配。 这使得柔…...

MYSQL——多表查询、事务和索引

概括 出现查询结果个数为笛卡尔积的原因是sql语句&#xff1a; select * from tb_emp,tb_dept; 没有加上where tb_emp.dept_id tb_dept.id;&#xff08;where条件可以消除笛卡尔积&#xff09; select * from tb_emp,tb_dept where tb_emp.dept_id tb_dept.id; 查询类型 …...

在 Swift 中实现字符串分割问题:以字典中的单词构造句子

文章目录 前言摘要描述题解答案题解代码题解代码分析示例测试及结果时间复杂度空间复杂度总结 前言 本题由于没有合适答案为以往遗留问题&#xff0c;最近有时间将以往遗留问题一一完善。 LeetCode - #140 单词拆分 II 不积跬步&#xff0c;无以至千里&#xff1b;不积小流&…...

Unity类银河战士恶魔城学习总结(P132 Merge skill tree with skill Manager 把技能树和冲刺技能相组合)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili 教程源地址&#xff1a;https://www.udemy.com/course/2d-rpg-alexdev/ 本章节实现了解锁技能后才可以使用技能&#xff0c;先完成了冲刺技能的锁定解锁 Dash_Skill.cs using System.Collections; using System…...

JavaScript 中 arguments、类数组与数组的深入解析

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 前端 文章目录 &#x1f4af;前言&#x1f4af;什么是 arguments 对象2.1 arguments 的定义2.2 arguments 的特性2.3 使用场景 &#x1f4af;深入了解 arguments 的结构3.1 arguments 的内部结构arguments 的关键属性…...

【java-Neo4j 5开发入门篇】-最新Java开发Neo4j

系列文章目录 前言 上一篇文章讲解了Neo4j的基本使用&#xff0c;本篇文章对Java操作Neo4j进行入门级别的阐述&#xff0c;方便读者快速上手对Neo4j的开发。 一、开发环境与代码 1.docker 部署Neo4j #这里使用docker部署Neo4j,需要镜像加速的需要自行配置 docker run --name…...

摄影:相机控色

摄影&#xff1a;相机控色 白平衡&#xff08;White Balance&#xff09;白平衡的作用&#xff1a; 白平衡的使用环境色温下相机色温下总结 白平衡偏移与包围白平衡包围 影调 白平衡&#xff08;White Balance&#xff09; 人眼看到的白色&#xff1a;会自动适应环境光线。 相…...

UI自动化测试中公认最佳的设计模式-POM

一、概念 什么是POM&#xff1f; POM是PageObjectModule&#xff08;页面对象模式&#xff09;的缩写&#xff0c;其目的是为了Web UI测试创建对象库。在这种模式下&#xff0c;应用涉及的每一个页面应该定义为一个单独的类。类中应该包含此页面上的页面元素对象和处理这些元…...

数字图像处理(2):Verilog基础语法

&#xff08;1&#xff09;Verilog常见数据类型&#xff1a; reg型、wire型、integer型、parameter型 &#xff08;2&#xff09;Verilog 常见进制&#xff1a;二进制&#xff08;b或B&#xff09;、十进制&#xff08;d或D&#xff09;、八进制&#xff08;o或O&#xff09;、…...

大公司如何实现打印机共享的?如何对打印机进行管控或者工号登录后进行打印?异地打印机共享的如何实现可以帮助用户在不同地理位置使用同一台打印机完成打印任务?

大公司如何实现打印机共享的&#xff1f;如何对打印机进行管控或者工号登录后进行打印&#xff1f;异地打印机共享的如何实现可以帮助用户在不同地理位置使用同一台打印机完成打印任务&#xff1f; 如果在局域网内&#xff0c;可以不需要进行二次开发&#xff0c;通过对打印机进…...

解决前端页面报错:Not allowed to load local resource

在前后端分离项目中&#xff0c;在前端页面里使用file://的绝对路径访问本地图片&#xff0c;在加载图片的 时候会报出Not allowed to load local resource 的错误。 这是因为浏览器出于安全因素&#xff0c;禁止通过绝对路径访问图片&#xff0c;需要通过虚拟路径进行访问。 …...

Qt 实现网络数据报文大小端数据的收发

1.大小端数据简介 大小端&#xff08;Endianness&#xff09;是计算机体系结构的一个术语&#xff0c;它描述了多字节数据在内存中的存储顺序。以下是大小端的定义和它们的特点&#xff1a; 大端&#xff08;Big-Endian&#xff09; 在大端模式中&#xff0c;一个字的最高有效…...

2024年11月21日Github流行趋势

项目名称&#xff1a;twenty 项目维护者&#xff1a;charlesBochet, lucasbordeau, Weiko, FelixMalfait, bosiraphael项目介绍&#xff1a;正在构建一个由社区支持的现代化Salesforce替代品。项目star数&#xff1a;21,798项目fork数&#xff1a;2,347 项目名称&#xff1a;p…...

Java的方法、基本和引用数据类型

个人的黑马程序员java笔记 目录 方法 例&#xff1a;方法定义和调用 方法的重载 对于byte, short, int, long类型 方法的内存 基本数据类型 引用数据类型 方法的值的传递的内存原理 方法 方法&#xff08;method&#xff09;是程序中最小的执行单元格式 方法定义&a…...

Spark分布式计算中Shuffle Read 和 Shuffle Write的职责和区别

在 Spark 的分布式计算中&#xff0c;Shuffle Read 和 Shuffle Write 是两个与数据重新分区和分发相关的重要阶段。它们的主要职责和区别如下&#xff1a; 1. Shuffle Write Shuffle Write 发生在上游的任务执行阶段&#xff0c;其作用是&#xff1a; 分区数据准备&#xff1…...

【成品文章+四小问代码更新】2024亚太杯国际赛B题基于有限差分格式的空调形状优化模型

这里仅展示部分内容&#xff0c;完整内容获取在文末&#xff01; 基于有限差分格式的空调形状优化模型 摘 要 随着科技进步&#xff0c;多功能环境调节设备成为市场趋势&#xff0c;集成了空调、加湿器和空气 净化器功能的三合一设备能提供更舒适健康的室内环境。我们需要分析…...

实验三:构建园区网(静态路由)

目录 一、实验简介 二、实验目的 三、实验需求 四、实验拓扑 五、实验任务及要求 1、任务 1&#xff1a;完成网络部署 2、任务 2&#xff1a;设计全网 IP 地址 3、任务 3&#xff1a;实现全网各主机之间的互访 六、实验步骤 1、在 eNSP 中部署网络 2、配置各主机 IP …...

MySQL 三大日志详解

在 MySQL 数据库中&#xff0c;binlog&#xff08;二进制日志&#xff09;、redo log&#xff08;重做日志&#xff09;和 undo log&#xff08;回滚日志&#xff09;起着至关重要的作用。它们共同保障了数据库的高可用性、数据一致性和事务的可靠性。下面将对这三大日志进行详…...

vscode使用ssh配置docker容器环境

1 创建容器&#xff0c;并映射主机和容器的指定ssh服务端口 2 进入容器 docker exec -it <容器ID> /bin/bash 3在容器中安装ssh服务 apt-get update apt-get install openssh-server 接着修改ssh文件信息,将容器的10008端口暴露出来允许root用户使用ssh登录 vim /…...

Python设计模式详解之10 —— 外观模式

引言 Facade设计模式&#xff08;外观模式&#xff09;是一种软件设计模式&#xff0c;它提供了一个统一的接口来访问子系统中的一组接口。Facade模式定义了一个高层接口&#xff0c;这个接口使得这一子系统更加容易使用。当一个系统的内部实现非常复杂&#xff0c;或者需要与…...

[服务器] 腾讯云服务器免费体验,成功部署网站

文章目录 概要整体架构流程概要 腾讯云服务器免费体验一个月。 整体架构流程 腾讯云服务器体验一个月, 选择预装 CentOS 7.5 首要最重要的是: 添加阿里云镜像。 不然国外源速度慢, 且容易失败。 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/li…...

低速接口项目之串口Uart开发(四)——UART串口实现FPGA内部AXILITE寄存器的读写控制

本节目录 一、设计背景 二、设计思路 三、逻辑设计框架 四、仿真验证 五、上板验证 六、往期文章链接本节内容 一、设计背景 通常&#xff0c;芯片手册或者IP都会提供一系列的用户寄存器以及相关的定义&#xff0c;用于软件开发人员进行控制底层硬件来调试&#xff0c;或封装…...

【Datawhale组队学习】模型减肥秘籍:模型压缩技术4——神经网络架构搜索

神经网络架构搜索是通过自动化方法来设计神经网络架构的一种技术&#xff0c;与传统手工设计网络结构相比&#xff0c;NAS能够在大量可能的架构中进行搜索&#xff0c;找到最优的神经网络架构&#xff0c;从而减少人工调参和设计的时间。学习这章时&#xff0c;重点在于理解NAS…...

用el-scrollbar实现滚动条,拖动滚动条可以滚动,但是通过鼠标滑轮却无效

问题&#xff1a; 用elementplus实现的滚动条的页面中&#xff0c;滑动滚动条可以滚动&#xff0c;但是通过鼠标滑轮却无效&#xff0c;鼠标没有问题。 解决&#xff1a; 在开发者工具中&#xff0c; 元素->时间监听器中发现当我移除网页中祖先元素的滚动事件&#xff0c;该…...

windows下,用CMake编译qt项目,出现错误By not providing “FindQt5.cmake“...

开发环境&#xff1a;windows10 qt5.14&#xff0c; 编译器msvc2017x64&#xff0c;CMake3.30&#xff1b; 现象&#xff1a; CMakeList文件里&#xff0c;如有find_package(Qt5 COMPONENTS Widgets REQUIRED) target_link_libraries(dis_lib PRIVATE Qt5::Widgets) 用CMak…...

windows实现VNC连接ubuntu22.04服务器

最近弄了一个700块钱的mini主机&#xff0c;刷了ubuntu22.04系统&#xff0c;然后想要在笔记本上通过VNC连接&#xff0c;这样就有了一个linux的开发环境。最后实现的过程为&#xff1a; 安装vnc服务器 安装 VNC 服务器软件&#xff1a; sudo apt update sudo apt install t…...

SQL注入--联合注入--理论

什么是SQL注入&#xff1f; SQL注入&#xff08;SQL Injection&#xff09;是一种常见的Web安全漏洞。 形成的主要原因是web应用程序在接收相关数据参数时未做好过滤&#xff0c;将其直接带入到数据库中查询&#xff0c;导致攻击者可以拼接执行构造的SQL语句&#xff0c;从而获…...

LaTeX 利用注销 ccmap 宏包实现降重功能

在中文LaTeX中&#xff0c;ccmap 宏包的主要作用是支持复制和粘贴时正确处理中文字符的编码。它的功能对于生成的PDF文档尤其有用&#xff0c;使得PDF中的中文字符在被复制到其他地方时能够以正确的编码显示&#xff0c;而不是乱码或其他不正确的字符。 以下是ccmap的详细功能…...

NVR接入录像回放平台EasyCVR视频融合平台加油站监控应用场景与实际功能

在现代社会中&#xff0c;加油站作为重要的能源供应点&#xff0c;面临着安全监管与风险管理的双重挑战。为应对这些问题&#xff0c;安防监控平台EasyCVR推出了一套全面的加油站监控方案。该方案结合了智能分析网关V4的先进识别技术和EasyCVR视频监控平台的强大监控功能&#…...