STL常用算法

sort

1.sort()

用法

void sort( first , last)
void sort( first , last , cmp)

实现对迭代器[ first ,last)的排序,排序规则默认为<或指定的cmp 

注意1 sort排序为不稳定排序

注意2 迭代器为随机访问迭代器,如list,forward_list内部有专门的sort函数

注意3 stl提供了专门的比较器less<T>和greater<T>,显然默认是less<T>

演示代码

#include<bits/stdc++.h>
using namespace std;
bool cmp(int i,int j){
    return i>j;
}
int main (){
    array<int,5>arr={3,1,5,4,2};
    sort(arr.begin(),arr.end());
    for(int i=0;i<5;i++)cout<<arr[i]<<" \n"[i==4];
    arr={3,1,5,4,2};
    sort(arr.begin(),arr.end(),cmp);
    for(int i=0;i<5;i++)cout<<arr[i]<<" \n"[i==4];
    arr={3,1,5,4,2};
    sort(arr.begin(),arr.end(),greater<int>());
    for(int i=0;i<5;i++)cout<<arr[i]<<" \n"[i==4];
    return 0;
}

2.stable_sort

用法

void sort( first , last)
void sort( first , last , cmp)

实现对迭代器[ first ,last)的稳定排序,排序规则默认为<或指定的cmp 

注意一 相较于sort,stable_sort排序具有稳定性

演示代码

#include<bits/stdc++.h>
using namespace std;
struct node{//为展示稳定性,我们新建结构体
    int key,val;
};
//函数对象
class cmp{
public:
    bool operator()(const node n1, const node n2)const{
        return n1.key<n2.key;
    }
};
int main (){
    array<node,5>arr={(node){2,3},{1,1},{3,2},{1,2},{1,0}};
    //我们预期key 1相等下val依次是原先顺序的 1,2,0 
    stable_sort(arr.begin(),arr.end(),cmp());
    for(int i=0;i<5;i++)cout<<arr[i].key<<" "<<arr[i].val<<endl;
    return 0;
}

3.partial_sort

用法

void partial_sort( first , mid , last)
void partial_sort( first , mid , last , cmp)

实现提取迭代器[ first ,last)的前mid - first个元素

注意一 first,mid,last要求是随机访问迭代器,list内部没有该函数

注意二 partial_sort底层是依靠堆实现的

演示代码

#include<bits/stdc++.h>
using namespace std;
int main (){
    array<int,5>arr={4,1,5,2,3};
    partial_sort(arr.begin(),arr.begin()+3,arr.end());
    for(int i=0;i<5;i++)cout<<arr[i]<<" \n"[i==4];
    //print: 1 2 3 5 4
    return 0;
}

4.partial_sort_copy

用法

void partial_sort_copy( first , last , res_first , res_last)
void partial_sort_copy( first , last , res_first , res_last , cmp)

实现提取迭代器[ first ,last)的前res_first - res_last个元素到res_first ~ res_last中

注意一 res_first,res_last要求是随机访问迭代器,first,last只需要是输入迭代器。换句话说,你可以对list部分排序copy到普通数组等随机访问容器中

注意二 如何记忆呢?只需要观察输出容器是否支持 last-first就可以了。部分排序的前提是知道部分排序的元素个数,显然如果是partial_sort,list并不支持这一功能。而在partical_sort_copy中同理输出容器不能是list等不存在随机迭代器的容器

演示代码

#include<bits/stdc++.h>
using namespace std;
int main (){
    array<int,5>arr={4,1,5,2,3};
    array<int,3>copy_arr;
    partial_sort_copy(arr.begin(),arr.end(),copy_arr.begin(),copy_arr.end());
    for(int i=0;i<3;i++)cout<<copy_arr[i]<<" \n"[i==2];
    //print: 1 2 3
    return 0;
}

5.nth_element

用法

void nth_element(  first, nth, last)
void nth_element(  first, nth, last , cmp)

将第 nth 个元素移动至第 nth 的位置,之前的元素小于该元素,之后的元素大于该元素。

显然是快排中的一个步骤

注意一 first,kth,last要求是随机访问迭代器

演示代码

#include<bits/stdc++.h>
using namespace std;
int main (){
    array<int,5>arr={4,1,2,2,3};
    nth_element(arr.begin(),arr.begin()+2,arr.end());
    for(int i=0;i<5;i++)cout<<arr[i]<<" \n"[i==4];
    //print: 1 2 2 4 3
    return 0;
}

6.is_sorted/is_sort_until

用法

bool  is_sorted(first,last)
bool  is_sorted(first , last , cmp)
ite  is_sorted_until (first,last)
ite  is_sorted_until (first , last , cmp)

返回第一个破坏有序状态的迭代器,有序则返回last

注意一 first , last 要求是正向迭代器

演示代码

#include<bits/stdc++.h>
using namespace std;
int main (){
    list<int>lst={1,2,3,5,4};
    cout<<boolalpha<<is_sorted(lst.begin(),lst.end())<<endl;
    cout<<distance(lst.begin(),is_sorted_until(lst.begin(),lst.end()))<<endl;
    //print:
    //false
    //4
    return 0;
}

merge

1.merge

用法

ite merge(first1 , last1 , first2 , last2 , res_first )
ite merge(first1 , last1 , first2 , last2 , res_first , cmp)

合并两个有序序列到目标容器中,返回目标容器序列最后一个元素后面的位置

注意一 first1-last1 和first2 -last2 必须满足默认排序规则或cmp。

演示代码

#include<bits/stdc++.h>
using namespace std;
int main (){
    list<int>lst={1,3,4};
    list<int>lst2={2,4,5};
    list<int>res_lst(lst.size()+lst2.size());
    auto it=merge(lst.begin(),lst.end(),lst2.begin(),lst2.end(),res_lst.begin());
    for(auto i=res_lst.begin();i!=it;i++)
        cout<<*i<<endl;
    //print: 1 2 3 4 4 5
    return 0;
}

2.inplace_merge

用法

void inplace_merge(first , mid , last )
void inplace_merge(first , mid , last , cmp)

同一段序列中first~mid有序,mid~last有序,将其合并储存在原容器中

显然它是归并排序的一部分

注意一 first-mid 和mid -last 必须满足默认排序规则或cmp。

演示代码

#include<bits/stdc++.h>
using namespace std;
int main (){
    list<int>lst={1,3,4,2,5,6};
    inplace_merge(lst.begin(),next(lst.begin(),3),lst.end());
    for(auto i:lst)cout<<i<<" ";
    //print: 1 2 3 4 5 6
    return 0;
}

find

1.find

用法

ite find( first , last , const T&val)

在序列中查找给定元素·,并返回查找值所在迭代器,若无则返回last

注意1 关联式容器如set,map内部有专门的find函数

演示代码

#include<bits/stdc++.h>
using namespace std;
int main (){
    list<int>lst={1,3,4,2,5,6};
    cout<<distance(lst.begin(),find(lst.begin(),lst.end(),2));
    //print: 3
    return 0;
}

2.find_if/find_if_not

用法

ite find_if( first , last , pred)
ite find_if_not( first , last , pred)

注意1 find_if和find_if_not函数都是为了自定义比较规则,由pred一元谓词函数指定。

当pred返回true则find_if返回该元素所处迭代器

pred返回false则find_if_not返回该元素所处迭代器

查找失败返回last

注意2 二者功能其实是类似的,可以通过改变pred内容自由转换find_if和find_if_not查找功能

注意3 pred也常直接使用lambda

演示代码

#include<bits/stdc++.h>
using namespace std;
bool pred(int i){
    return i>0;
}
int main (){
    list<int>lst={1,3,2,4};
    cout<<distance(lst.begin(),find_if(lst.begin(),lst.end(),[=](int i){
        return i%2==0;
    }))<<endl;
    cout<<distance(lst.begin(),find_if_not(lst.begin(),lst.end(),pred))<<endl;
    //print: 2 4
    return 0;
}

3.find_end

用法

ite find_end(first1 , last1 , first2 , last2)
ite find_end(first1 , last1 , first2 , last2 ,pred)

查找序列first1~last1中first2~last2最后出现的位置,返回的是第一个元素匹配的迭代器,错误返回last

注意1 pred第一个参数接受first1-last1中的元素,第二个元素接受first2-last2中的元素

注意2 实现的底层原理明显是使用双指针,感兴趣可以自行查阅和实现

演示代码

#include<bits/stdc++.h>
using namespace std;
int main (){
    list<int>lst={1,3,2,8,12,20,4};
    vector<int>v={2,3,4};
    cout<<distance(lst.begin(),find_end(lst.begin(),lst.end(),v.begin(),v.end(),[=](int i,int j){
        return i%j==0;
    }))<<endl;
    //print: 3
    return 0;
}

4.find_first_of

用法

ite find_first_of(first1 , last1 , first2 , last2)
ite find_first_of(first1 , last1 , first2 , last2 ,pred)

查找first1-last1中第一个与first2-last2任意匹配的元素,错误返回last1

注意1 pred第一个参数接受first1-last1中的元素,第二个元素接受first2-last2中的元素

演示代码

#include<bits/stdc++.h>
using namespace std;
int main (){
    list<int>lst={1,5,4};
    vector<int>v={2,3,4};
    cout<<distance(lst.begin(),find_first_of(lst.begin(),lst.end(),v.begin(),v.end(),[=](int i,int j){
        return i==j;
    }))<<endl;
    //print: 2
    return 0;
}

5.adjacent_find

用法

ite adjacent_find(first , last )
ite adjacent_find( first , last ,pred)

查找first - last 中连续两个相同的元素,返回第一个元素的迭代器,错误返回last

当然如果是第二种重载形式,则是查找连续两个符合pred的元素

注意1 pred是二元谓词,需要传入两个参数

注意2 adjacent_find实现原理是遍历序列,通过传入该元素和下一个元素到pred判断bool

演示代码

#include<bits/stdc++.h>
using namespace std;
int main (){
    list<int>lst={1,2,5,4,2};
    cout<<distance(lst.begin(),adjacent_find(lst.begin(),lst.end(),[=](int i,int j){
        return i%j==0;
    }));
    //print: 3
    return 0;
}

  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值