algorithm中常用的STL处理函数

目录

STL操作的灵魂——函数对象

“函数对象”是什么?

那又有疑问了:为什么把operator()放进struct中呢?

这里为什么要进行“ObjectDisplayData = for_each()”变量之间的赋值?

“谓词”是什么?

我们为什么要使用algorithm库对容器进行操作?

一元谓词的使用

查找第一个偶数元素并且输出显示

遍历输出全部的偶数元素

几个常用的一元谓词

元素分组函数partition()

元素分组函数stable_partition()

在模板类中定义迭代器时的注意事项

Find_if的用法

Fill填充函数

Fill_n填充函数

Includes函数的使用

Copy_if函数进行有条件的复制

Copy_n函数—无条件的复制n个连续的元素

Copy函数的使用

Remove_copy_if函数的使用

Replace_copy_if()函数的使用

Copy_backward()函数使用

Equal_range()函数的使用

Equal函数使用

All_of函数

Any_of函数

Inplace_merge()函数的使用

Merge函数的使用


STL操作的灵魂——函数对象

“函数对象”是什么?

函数对象的出现旨在对容器中的每个元素进行自定义处理,因此一般将函数对象当作自定义处理的工具,一般用于algorithm库函数的第三参数。切记:函数对象有记忆性,可以保存每次调用后的数据值。函数对象这个概念用口语描述有些吃力,我们可以举例子来说明一下:

#include <iostream>  
#include <algorithm>  
#include <vector>  
#include <string>  
using namespace std;  
  
struct DisplayData   
{  
    void operator()(const int& var)  
    {  
        cout << var << " ";  
    }  
}ObjectDisplayData;  
  
int main()  
{  
    vector<int> VectorArray1{ 1,2,3,4,5,6,7,8,9,10 };  
    for_each(VectorArray1.begin(), VectorArray1.end(), ObjectDisplayData);  
}  

我们看到,在algorithm库中提供的函数for_each有第三个参数,第三个参数的含义就是我们对[VectorArray1.begin(), VectorArray1.end())[注意:左闭右开区间]进行ObjectDisplayData操作。

那又有疑问了:为什么把operator()放进struct中呢?

C++中Struct作为一个可以继承数据和成员函数为一体的自定义数据类型,可用于在对STL容器元素进行自定义处理后将元素的状态记录下来,例如:我想查询STL容器中偶数的个数,那这时我们就需要记录容器中偶数个数的变量。

我们这时又想到,每次调用函数并且记录下来状态,我们一定要将用于记录状态的变量声明为static类型,那针对于函数对象我们该如何操作呢?

其实不用担心,函数对象,你可以把struct中的所有成员变量全部默认看作static类型的,因此无需你特殊声明,函数对象会自动保存每一次的调用状态。

#include <iostream>  
#include <algorithm>  
#include <vector>  
#include <string>  
using namespace std;  
  
template<typename T>  
struct DisplayData // 如果用class,一定要将所有成员声明为public类型的  
{  
    int count;  
    DisplayData()  
    {  
        count = 0;  
    }  
    void operator()(const T& var)  
    {  
        ++count;  
        cout << var << " ";  
    }  
};  
  
int main()  
{  
    vector<int> VectorArray1{ 1,2,3,4,5,6,7,8,9,10 };  
    DisplayData<int> ObjectDisplayData;  
    ObjectDisplayData = for_each(VectorArray1.begin(), VectorArray1.end(), DisplayData<int>());  // 一定要赋值,相当于结构体元素的拷贝
    cout << endl << "STL容器总元素个数为" << ObjectDisplayData.count << endl;  
}  

注:这里count变量充当了记录元素个数的功能(记录了元素的状态)。

这里为什么要进行“ObjectDisplayData = for_each()”变量之间的赋值?

 

“谓词”是什么?

谓词就是一种特殊的函数对象,谓词的返回值是bool,接受变量可以是一元或多元的。

我们为什么要使用algorithm库对容器进行操作?

要使用一个库,先了解库的基本功能是什么:

C++中的algorithm库,包含了所有vector、list、set、map操作能想到的一些函数,如查找,替换、排序、计数等常用的功能全部在里面,在这里虽然不像Java那样完全面向对象,方法全部在类里面,但是熟读algorithm库还是非常有必要,官网的链接:http://www.cplusplus.com/reference/algorithm/ 可以非常直接学习,代码也非常清晰易懂,下面自己写了几个例子:

#include <iostream>  
#include <algorithm>  
#include <vector>  
using namespace std;  
   
//参考http://www.cplusplus.com/reference/algorithm/  
   
bool IsOdd (int i) {  
    return ((i%2)==1);  
}  
   
int main() {  
    int myints[] = { 5, 20, 51, 30, 20, 10, 22,50 };  
   
    int len= sizeof(myints)/ sizeof(myints[0]);  
   
    vector<int> myvector(myints,myints+len);  
   
    cout<<myvector.size()<<endl;  
   
    vector<int>::iterator  iter;  
   
    //find函数查看vector是否包含某元素  
    iter=  find(myvector.begin(),myvector.end(),50);  
   
    if (iter != myvector.end()) {  
        std::cout << "Element found in myvector: " << *iter << '\n';  
    }// 30  
    else {  
        std::cout << "Element not found in myvector\n";  
    }  
   
    //根据条件来查看vector是否包含某元素  
    std::vector<int>::iterator it = std::find_if (myvector.begin(), myvector.end(), IsOdd);  
    std::cout << "The first odd value is " << *it << '\n';  
   
    std::vector<int>::iterator iter1 =  
    std::find_if_not (myvector.begin(), myvector.end(), [](int i){return i%2;} );  
    std::cout << "The first even value is " << *iter1 << '\n';  
   
    //计数工具  一直接对数组计数  
    int mycount = std::count (myints, myints+8, 10);  
    std::cout << "10 appears " << mycount << " times.\n";  
   
    // counting elements in container:  
    //对vector计数  
    mycount = std::count (myvector.begin(), myvector.end(), 20);  
    std::cout << "20 appears " << mycount  << " times.\n";  
   
    //按照条件计数  
     mycount = count_if (myvector.begin(), myvector.end(), IsOdd);  
    std::cout << "myvector contains " << mycount  << " odd values.\n";  
   
    //search_n 找位置情况,其中1表示从第几个20开始找  
    it = std::search_n (myvector.begin(), myvector.end(), 1, 20);  
   
    if (it!=myvector.end())  
        std::cout << "two 30s found at position " << (it-myvector.begin()) << '\n';  
    else  
        std::cout << "match not found\n";  
} 

 

一元谓词的使用

查找第一个偶数元素并且输出显示

#include <iostream>  
#include <algorithm>  
#include <vector>  
#include <string>  
using namespace std;  
  
template<typename T>  
struct DisplayData // 如果用class,一定要将所有成员声明为public类型的  
{  
    int count;  
    int Division;  
    DisplayData(int& Division)  
    {  
        this->Division = Division;  
    }  
    bool operator()(const T& var)  
    {  
        ++count;  
        return ((var % this->Division) == 0);  
    }  
};  
  
int main()  
{  
    vector<int> VectorArray1{ 1,2,3,4,5,6,7,8,9,10 };  
    int Division = 2;  
    DisplayData<int> ObjectDisplayData(Division);  
    ObjectDisplayData = for_each(VectorArray1.begin(), VectorArray1.end(), DisplayData<int>(Division));  
    vector<int>::iterator itor1 = find_if(VectorArray1.begin(), VectorArray1.end(), DisplayData<int>(Division));  
    if (itor1 != VectorArray1.end())  
    {  
        cout << "第一个偶数是" << *itor1 << endl;  
    }  
    cout << endl << "STL容器总元素个数为" << ObjectDisplayData.count << endl;  
}  

遍历输出全部的偶数元素

#include <iostream>  
#include <algorithm>  
#include <vector>  
#include <string>  
using namespace std;  
  
template<typename T>  
struct DisplayData // 如果用class,一定要将所有成员声明为public类型的  
{  
    int count;  
    int Division;  
    DisplayData(int& Division)  
    {  
        this->Division = Division;  
        this->count = 0;  
    }  
    bool operator()(const T& var)  
    {  
        ++count;  
        return ((var % this->Division) == 0);  
    }  
};  
  
int main()  
{  
    vector<int> VectorArray1{ 1,2,3,4,5,6,7,8,9,10 };  
    int Division = 2;  
    DisplayData<int> ObjectDisplayData(Division);  
    ObjectDisplayData = for_each(VectorArray1.begin(), VectorArray1.end(), DisplayData<int>(Division));  
    vector<int>::iterator itor1 = find_if(VectorArray1.begin(), VectorArray1.end(), DisplayData<int>(Division));  
    for (int Order = 0; itor1 != VectorArray1.end();)  
    {  
        itor1 = find_if(itor1 + 1, VectorArray1.end(), DisplayData<int>(Division));  
        if (itor1 != VectorArray1.end())  
        {  
            cout << "第\"" << ++Order << "\"个偶数是" << *itor1 << endl;  
        }  
    }  
    cout << "STL容器总元素个数为" << ObjectDisplayData.count << endl;  
}  

注意:itor1 = find_if(itor1 + 1, VectorArray1.end(), DisplayData<int>(Division)); 我们“在第x个偶数的迭代器”基础上1,是因为find_if函数遍历的范围是[a,b),这样做是为了让迭代器在(在第x个偶数的迭代器,end())之间遍历得到“在第x+1个偶数的迭代器”。

几个常用的一元谓词

元素分组函数partition()

函数的作用

算法std::partition()使用一元谓词来划分范围,算法stable_partition()也使用一元谓词来划分范围,但保持元素的相对顺序不变。例如:数组{1,4,3,2,5,6,7,10,9,8},分类指标为“奇偶”,通过使用partition一元谓词,课一分为{1,3,5,7,9,4,2,5,6,10,8},并返回第二组的第一个元素的迭代器,即4的迭代器。

代码示例

#include <iostream>  
#include <algorithm>  
#include <vector>  
using namespace std;  
  
template<typename T>  
struct CompareIntPart   
{  
    bool operator()(const T& var1)  
    {  
        return (int)var1 % 2 == 0;  
    }  
};  
  
template<typename T>  
void DisplayArray(vector<T>& var)  
{  
    typename vector<T>::iterator itor = var.begin();  
    for (; itor != var.end(); itor++)  
    {  
        cout << *itor << " ";  
    }  
    cout << endl;  
}  
  
int main()  
{  
    vector<float> VectorArray{ 1.23,1.67,2.1,2.5,3.3,4.2 };  
    vector<float>::iterator itor1 = partition(VectorArray.begin(), VectorArray.end(), CompareIntPart<float>());  
    cout << "第二部分的第一个元素是" << *itor1 << endl;  
    DisplayArray<float>(VectorArray);  
}  

注意:这里的partition的第三参数,也就是函数对象,必须只有一个参数,即如下所示:

bool operator()(const T& var1) 

输出结果

 

我们这里注意到输出结果总共分为两部分:4.2,2.5,2.1和1.67,3.3,1.23。其中,第一部分是函数对象返回值为真的元素,但是他们没有按照彼此之间的相对顺序进行排列。

元素分组函数stable_partition()

函数的作用

stable_partition()与partition()唯一的区别是一旦遇到相同的元素不改变他们的相对顺序。例如:数组{1.23,2,67,1.1,5.3,2.2},我们按照他们的整数部分是否为偶数进行区分,可得到:2.67,2.2和1.23,1.1,5.3。我们发现这两部分中每一部分的彼此的相对顺序没有发生改变。这就是stable_partition与partition最大的区别。

代码示例

#include <iostream>  
#include <algorithm>  
#include <vector>  
using namespace std;  
  
template<typename T>  
struct CompareIntPart   
{  
    bool operator()(const T& var1)  
    {  
        return (int)var1 % 2 == 0;  
    }  
};  
  
template<typename T>  
void DisplayArray(vector<T>& var)  
{  
    typename vector<T>::iterator itor = var.begin();  
    for (; itor != var.end(); itor++)  
    {  
        cout << *itor << " ";  
    }  
    cout << endl;  
}  
  
int main()  
{  
    vector<float> VectorArray{ 1.23,1.67,2.1,2.5,3.3,4.2 };  
    vector<float>::iterator itor1 = stable_partition(VectorArray.begin(), VectorArray.end(), CompareIntPart<float>());  
    cout << "第二部分的第一个元素是" << *itor1 << endl;  
    DisplayArray<float>(VectorArray);  
} 

​​​​​​​ 

 

输出结果

 

在模板类中定义迭代器时的注意事项

错误名称

C7510 “iterator”: 类型 从属名称的使用必须以“typename”为前缀

 

解决方法

在 "map <T1, T2> ::iterator it;" 前加 typename,例子如下:  
template<typename T1, typename T2>  
void printMap(map <T1, T2>& Map)  
{  
    typename map <T1, T2> ::iterator it;  
    for (it = Map.begin(); it != Map.end(); ++it)  
    {  
        cout << it->first << " : " << it->second << endl;  
    }  
} 

​​​​​​​ 

Find_if的用法

代码示例

// 函数对象.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。  
//  
  
#include <iostream>  
#include <algorithm>  
#include <vector>  
#include <string>  
using namespace std;  
  
template<typename T>  
struct DisplayData // 如果用class,一定要将所有成员声明为public类型的  
{  
    int count;  
    int Division;  
    DisplayData(int& Division)  
    {  
        this->Division = Division;  
        this->count = 0;  
    }  
    bool operator()(const T& var)  
    {  
        ++count;  
        return ((var % this->Division) == 0);  
    }  
};  
  
int main()  
{  
    vector<int> VectorArray1{ 1,4,3,2,5,6,7,8,9,10 };  
    int Division = 2;  
    DisplayData<int> ObjectDisplayData(Division);  
    ObjectDisplayData = for_each(VectorArray1.begin(), VectorArray1.end(), DisplayData<int>(Division));  
    vector<int>::iterator itor1 = find_if(VectorArray1.begin(), VectorArray1.end(), DisplayData<int>(Division));  
    cout << "第\"" << 1 << "\"个偶数是" << *itor1 << endl;  
    for (int Order = 1; itor1 != VectorArray1.end();)  
    {  
        itor1 = find_if(itor1 + 1, VectorArray1.end(), DisplayData<int>(Division));  
        if (itor1 != VectorArray1.end())  
        {  
            cout << "第\"" << ++Order << "\"个偶数是" << *itor1 << endl;  
        }  
    }  
    cout << "STL容器总元素个数为" << ObjectDisplayData.count << endl;  
}  

注:find_if_not是返回不符合条件的第一个迭代器,与find_if作用相反。

Fill填充函数

// 用于在一个范围内填充相同的元素
#include <iostream>     // std::cout  
#include <algorithm>    // std::fill  
#include <vector>       // std::vector  
  
int main () {  
  std::vector<int> myvector (8);                       // myvector: 0 0 0 0 0 0 0 0  
  
  std::fill (myvector.begin(),myvector.begin()+4,5);   // myvector: 5 5 5 5 0 0 0 0  
  std::fill (myvector.begin()+3,myvector.end()-2,8);   // myvector: 5 5 5 8 8 8 0 0  
  
  std::cout << "myvector contains:";  
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)  
    std::cout << ' ' << *it;  
  std::cout << '\n';  
  
  return 0;  
}  

Fill_n填充函数

// fill_n 用于从起始迭代器开始填充多个相同的元素
#include <iostream>     // std::cout  
#include <algorithm>    // std::fill_n  
#include <vector>       // std::vector  
  
int main () {  
  std::vector<int> myvector (8,10);        // myvector: 10 10 10 10 10 10 10 10  
  
  std::fill_n (myvector.begin(),4,20);     // myvector: 20 20 20 20 10 10 10 10  
  std::fill_n (myvector.begin()+3,3,33);   // myvector: 20 20 20 33 33 33 10 10  
  
  std::cout << "myvector contains:";  
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)  
    std::cout << ' ' << *it;  
  std::cout << '\n';  
  
  return 0;  
} 

​​​​​​​ 

Includes函数的使用

// 用于检测数组1是否包含数组2
#include <iostream>  
#include <algorithm>  
#include <vector>  
using namespace std;  
  
int main()  
{  
    vector<int> VectorArray1{ 1,2,3,4,5,6,7,9 };  
    vector<int> VectorArray2{ 3,1,7,9 };  
    sort(VectorArray2.begin(), VectorArray2.end()); // 按照升序排列  
    bool is_include = includes(VectorArray1.begin(), VectorArray1.end(), VectorArray2.begin(), VectorArray2.end());  
    cout << is_include << endl; // is_include = 1  
}  

注:在调用includes函数之前,一定要对两个数组进行升序排序,必须是升序而且排序方式必须一致。

Copy_if函数进行有条件的复制

#include <iostream>  
#include <algorithm>  
#include <vector>  
using namespace std;  
  
int main()  
{  
    vector<int> VectorArray1{ 1,2,-1,3,-4,5 };  
    vector<int> VectorArray2(VectorArray1.size());  
    auto Result = copy_if(VectorArray1.begin(), VectorArray1.end(), VectorArray2.begin(), [](int i) {return i >= 0; });  
    VectorArray2.resize(distance(VectorArray2.begin(), Result)); // 将多余的存储空间释放掉  
} 

​​​​​​​ 

注:copy_if函数返回“最后一个不满足“[](int i) { return i >= 0; }”的元素的后一个元素的迭代器“。

Copy_n函数—无条件的复制n个连续的元素

针对于普通数组的元素拷贝

// copy_n algorithm example  
#include <iostream>     // std::cout  
#include <algorithm>    // std::copy  
#include <vector>       // std::vector  
  
int main () {  
  int myints[]={10,20,30,40,50,60,70};  
  std::vector<int> myvector;  
  
  myvector.resize(7);   // allocate space for 7 elements  
  
  std::copy_n ( myints, 7, myvector.begin() );  // 第一个参数是复制目标数组的初始地址或者初始迭代器
  
  std::cout << "myvector contains:";  
  for (std::vector<int>::iterator it = myvector.begin(); it!=myvector.end(); ++it)  
    std::cout << ' ' << *it;  
  
  std::cout << '\n';  
  
  return 0;  
}  

针对于动态数组的元素拷贝

#include <iostream>  
#include <algorithm>  
#include <vector>  
using namespace std;  
  
int main()  
{  
    vector<int> VectorArray1{ 1,2,-1,3,-4,5 };  
    vector<int> VectorArray2(VectorArray1.size());  
    auto Result = copy_if(VectorArray1.begin(), VectorArray1.end(), VectorArray2.begin(), [](int i) {return i >= 0; });  
    VectorArray2.resize(distance(VectorArray2.begin(), Result)); // 将多余的存储空间释放掉  
  
    vector<int> VectorArray3;  
    VectorArray3.resize(3); // 预留3个内存空间  
    copy_n(VectorArray1.begin(), 3, VectorArray3.begin());  
}  

有返回值的copy_n函数

#include <iostream>  
#include <algorithm>  
#include <vector>  
using namespace std;  
  
int main()  
{  
    vector<int> VectorArray1{ 1,2,-1,3,-4,5 };  
    vector<int> VectorArray2(VectorArray1.size());  
    auto Result = copy_if(VectorArray1.begin(), VectorArray1.end(), VectorArray2.begin(), [](int i) {return i >= 0; });  
    VectorArray2.resize(distance(VectorArray2.begin(), Result)); // 将多余的存储空间释放掉  
  
    vector<int> VectorArray3;  
    VectorArray3.resize(4); // 预留3个内存空间  
    vector<int>::iterator itor1 = copy_n(VectorArray1.begin(), 3, VectorArray3.begin());  
    cout << *itor1 << endl; // 复制元素所在的目标范围的后一个元素的迭代器  
}  

Copy函数的使用

// copy algorithm example  
#include <iostream>     // std::cout  
#include <algorithm>    // std::copy  
#include <vector>       // std::vector  
  
int main () {  
  int myints[]={10,20,30,40,50,60,70};  
  std::vector<int> myvector (7);  
  
  std::copy ( myints, myints+7, myvector.begin() );  
  
  std::cout << "myvector contains:";  
  for (std::vector<int>::iterator it = myvector.begin(); it!=myvector.end(); ++it)  
    std::cout << ' ' << *it;  
  
  std::cout << '\n';  
  
  return 0;  
}  

注意:一定要分清copy函数与copy_n()函数的调用格式

Copy()

copy ( myints, myints+7, myvector.begin() ); // 复制[myints, myints+7)之间的元素

Copy_n()

copy ( myints,  7, myvector.begin() ); // myints复制包括自己在内的7个元素

Remove_copy_if函数的使用

// remove_copy_if example  
#include <iostream>     // std::cout  
#include <algorithm>    // std::remove_copy_if  
#include <vector>       // std::vector  
  
bool IsOdd (int i) { return ((i%2)==1); }  
  
int main () {  
  int myints[] = {1,2,3,4,5,6,7,8,9};  
  std::vector<int> myvector (9);  
  
  std::remove_copy_if (myints,myints+9,myvector.begin(),IsOdd);  
  
  std::cout << "myvector contains:";  
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)  
    std::cout << ' ' << *it;  
  std::cout << '\n';  
  
  return 0;  
}  

Replace_copy_if()函数的使用

// replace_copy_if example  
#include <iostream>     // std::cout  
#include <algorithm>    // std::replace_copy_if  
#include <vector>       // std::vector  
  
bool IsOdd (int i) { return ((i%2)==1); }  
  
int main () {  
  std::vector<int> foo,bar;  
  
  // set some values:  
  for (int i=1; i<10; i++) foo.push_back(i);          // 1 2 3 4 5 6 7 8 9  
  
  bar.resize(foo.size());   // allocate space  
  std::replace_copy_if (foo.begin(), foo.end(), bar.begin(), IsOdd, 0);  
                                                        // 0 2 0 4 0 6 0 8 0  
  
  std::cout << "bar contains:";  
  for (std::vector<int>::iterator it=bar.begin(); it!=bar.end(); ++it)  
    std::cout << ' ' << *it;  
  std::cout << '\n';  
  
  return 0;  
} 

​​​​​​​ 

 

Copy_backward()函数使用

#include <iostream>  
#include <algorithm>  
#include <vector>  
using namespace std;  
  
int main()  
{  
    vector<int> VectorArray1{ 1,2,-1,3,-4,5 };  
    vector<int> VectorArray2(VectorArray1.size());  
    auto Result = copy_if(VectorArray1.begin(), VectorArray1.end(), VectorArray2.begin(), [](int i) {return i >= 0; });  
    VectorArray2.resize(distance(VectorArray2.begin(), Result)); // 将多余的存储空间释放掉  
  
    vector<int> VectorArray3;  
    VectorArray3.resize(4); // 预留3个内存空间  
    vector<int>::iterator itor1 = copy_n(VectorArray1.begin(), 3, VectorArray3.begin());  
    cout << *itor1 << endl; // 复制元素所在的目标范围的后一个元素的迭代器  
  
    vector<int> VectorArray4;  
    VectorArray4.resize(4);  
    vector<int>::iterator itor2 = copy_backward(VectorArray1.begin(), VectorArray1.begin() + 4, VectorArray4.end());  
    cout << *itor2 << endl; // itor2指向的是第一个数组的第一个元素的地址。也是倒序装填的最后一个元素的地址  
}  

注:copy_backward()采用的是倒叙装填,就是先将元素复制到第二个数组末尾,再一次向前填充复制。

Equal_range()函数的使用

// Equal_range()函数的主要作用是“查找特定元素的地址上下限” ,一定要先排序! 
#include <iostream>     // std::cout  
#include <algorithm>    // std::equal_range, std::sort  
#include <vector>       // std::vector  
  
bool mygreater (int i,int j) { return (i>j); }  
  
int main () {  
  int myints[] = {10,20,30,30,20,10,10,20};  
  std::vector<int> v(myints,myints+8);                         // 10 20 30 30 20 10 10 20  
  std::pair<std::vector<int>::iterator,std::vector<int>::iterator> bounds;  
  
  // using default comparison:  
  std::sort (v.begin(), v.end());                              // 10 10 10 20 20 20 30 30  
  bounds=std::equal_range (v.begin(), v.end(), 20);            //          ^        ^  
  
  // using "mygreater" as comp:  
  std::sort (v.begin(), v.end(), mygreater);                   // 30 30 20 20 20 10 10 10  
  bounds=std::equal_range (v.begin(), v.end(), 20, mygreater); //       ^        ^  
  
  std::cout << "bounds at positions " << (bounds.first - v.begin());  
  std::cout << " and " << (bounds.second - v.begin()) << '\n';  
  
  return 0;  
}  

注意:这里“bounds=std::equal_range (v.begin(), v.end(), 20, mygreater);”也必须带有mygreater,为了表明操作对象的排序方式是“mygreater(降序排列)”。

#include <iostream>  
#include <vector>  
#include <algorithm>  
using namespace std;  
  
int main()  
{  
    vector<int> VectorArray1{ 10,10,20,20,30,30 };  
    sort(VectorArray1.begin(), VectorArray1.end()); // 默认升序排列  
    pair<vector<int>::iterator, vector<int>::iterator> Boundary;  
    Boundary = equal_range(VectorArray1.begin(), VectorArray1.end(), 20);  
    cout << "下界元素索引为" << distance(VectorArray1.begin(), Boundary.first) << endl; // 指向第一个20  
    cout << "上界元素索引为" << distance(VectorArray1.begin(), Boundary.second) << endl; // 指向第一个30  
}  

注意:这里的返回值是“第一个20元素的索引”与“最后一个20元素的后一个元素的索引”。

Equal函数使用

// equal algorithm example  
#include <iostream>     // std::cout  
#include <algorithm>    // std::equal  
#include <vector>       // std::vector  
  
bool mypredicate (int i, int j) // 自定义等价条件  
{  
  return (i==j);  
}  
  
int main () {  
  int myints[] = {20,40,60,80,100};               //   myints: 20 40 60 80 100  
  std::vector<int>myvector (myints,myints+5);     // myvector: 20 40 60 80 100  
  
  // using default comparison:  
  if ( std::equal (myvector.begin(), myvector.end(), myints) )  
    std::cout << "The contents of both sequences are equal.\n";  
  else  
    std::cout << "The contents of both sequences differ.\n";  
  
  myvector[3]=81;                                 // myvector: 20 40 60 81 100  
  
  // using predicate comparison:  
  if ( std::equal (myvector.begin(), myvector.end(), myints, mypredicate) )  
    std::cout << "The contents of both sequences are equal.\n";  
  else  
    std::cout << "The contents of both sequences differ.\n";  
  
  return 0;  
}  

注意:equal的返回值为true或者false,其中equal的第四个参数规定了了两个数组中元素等价的条件。

#include <iostream>  
#include <vector>  
#include <algorithm>  
using namespace std;  
  
bool EqualLaw(int& var1, float& var2)   
{  
    return var1 == (int)var2;   
}  
  
int main()  
{  
    vector<int> VectorArray1{ 10,10,20,20,30,30 };  
    sort(VectorArray1.begin(), VectorArray1.end()); // 默认升序排列  
    pair<vector<int>::iterator, vector<int>::iterator> Boundary;  
    Boundary = equal_range(VectorArray1.begin(), VectorArray1.end(), 20);  
    cout << "下界元素索引为" << distance(VectorArray1.begin(), Boundary.first) << endl; // 指向第一个20  
    cout << "上界元素索引为" << distance(VectorArray1.begin(), Boundary.second) << endl; // 指向第一个30  
  
    vector<float> VectorArray2{ 10.1,10.1,20.1,20.1 ,30.1,30.1 };  
    bool Is_Empty = equal(VectorArray1.begin(), VectorArray1.end(), VectorArray2.begin(), EqualLaw);  
    cout << Is_Empty << endl;  
} 

​​​​​​​ 

All_of函数

// all_of 函数用于对所有元素进行条件检验,如果全部符合条件(例如:全是偶数),返回true,否则返回false
#include <iostream>     // std::cout  
#include <algorithm>    // std::all_of  
#include <array>        // std::array  
  
int main () {  
  std::array<int,8> foo = {3,5,7,11,13,17,19,23};  
  
  if ( std::all_of(foo.begin(), foo.end(), [](int i){return i%2;}) )  
    std::cout << "All the elements are odd numbers.\n";  
  
  return 0;  
} 

​​​​​​​ 

Any_of函数

// any_of 函数:有一个满足条件,就返回true,否则返回false  
#include <iostream>     // std::cout  
#include <algorithm>    // std::any_of  
#include <array>        // std::array  
  
int main () {  
  std::array<int,7> foo = {0,1,-1,3,-3,5,-5};  
  
  if ( std::any_of(foo.begin(), foo.end(), [](int i){return i<0;}) )  
    std::cout << "There are negative elements in the range.\n";  
  
  return 0;  
}  

Inplace_merge()函数的使用

函数作用

合并两个连续排序的范围:[first,middle)和[middle,last),将结果放入合并后的排序范围[first,last)。最后,在进行默认的升序排序。

代码示例

Inplace_merge()函数的名称其实是“in place merge”,意为“就地合并”。

#include <iostream>  
#include <vector>  
#include <algorithm>  
using namespace std;  
  
int main()  
{  
    vector<int> first{ 10,20,20,30,30,40 };  
    vector<int> second{ 10,20,30,30,40 };  
    vector<int> VectorArray(first.size() + second.size());  
    vector<int>::iterator itor = copy(first.begin(), first.end(), VectorArray.begin());  
    copy(second.begin(), second.end(), itor);  
    inplace_merge(VectorArray.begin(), itor, VectorArray.end());  
} 

输出结果

 

Merge函数的使用

#include <iostream>  
#include <vector>  
#include <algorithm>  
using namespace std;  
  
struct DefaultOrder  
{  
    bool operator()(const int& var1, const int& var2)  
    {  
        return var1 > var2;  
    }  
};  
  
int main()  
{  
    vector<int> first{ 10,20,20,30,30,40 };  
    vector<int> second{ 10,20,30,30,40 };  
    vector<int> VectorArray(first.size() + second.size());  
    vector<int>::iterator itor = copy(first.begin(), first.end(), VectorArray.begin());  
    copy(second.begin(), second.end(), itor);  
    inplace_merge(VectorArray.begin(), itor, VectorArray.end());  
  
    vector<int> VectorArray1(first.size() + second.size());  
    merge(first.begin(), first.end(), second.begin(), second.end(), VectorArray1.begin()); // 默认进行升序排列  
    sort(VectorArray1.begin(), VectorArray1.end(), DefaultOrder()); // 进行降序排列  
}  

注意:这里merge需要进行默认的升序排序,如果容器中是自定义数据类型,那我们必须要重载相应的运算符。

 

猜你喜欢

转载自blog.csdn.net/weixin_45590473/article/details/107952670