STL:STL算法总结

本文详细介绍了C++ STL中的常用算法,包括填充、遍历、排序、查找、删除和替换等,提供了丰富的示例进行说明,如fill、generate、transform、min/max、random_shuffle、count、remove、replace、unique、accumulate等操作。
摘要由CSDN通过智能技术生成

1. 头文件

头文件功能
<algorithm>算法函数
<numeric>数值算法
<functional>函数对象/仿函数

2. 常用算法

2.1 填充

函数作用
fill(beg,end,val)将值val赋给[beg,end)范围内的所有元素
fill_n(beg,n,val)将值val赋给[beg,beg+n)范围内的所有元素
generate(beg,end,func)连续调用函数func填充[beg,end)范围内的所有元素
generate_n(beg,n,func)连续调用函数func填充[beg,beg+n)范围内的所有元素

fill() / fill_n() 用于填充相同值,generate() / generate_n() 用于填充不同值。

generate 的用法:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int func(){
        static int i=0;
        return ++i;
}

// 创建仿函数
struct Gen{
        int i,step;
        bool first;
        Gen(int i,int step):i(i),step(step),first(true){}
        int operator()(){
                int res = first?i:i+=step;      // 第一次不加,其余次都加
                first = false;
                return res;
        }
};

int main(){
        vector<int> vec(10);       // 有10个元素,目前都是0
        for(auto n:vec){
                cout << n << " ";
        }
        cout << endl;

        generate(vec.begin(),vec.end(),func);
        for(auto n:vec){
                cout << n << " ";
        }
        cout << endl;

        generate(vec.begin(),vec.end(),Gen(1,2));    // 调用仿函数
        for(auto n:vec){
                cout << n << " ";
        }
        cout << endl;

        generate(vec.begin(),vec.end(),Gen(10,10));
        for(auto n:vec){
                cout << n << " ";
        }
        cout << endl;
}

结果为:

0 0 0 0 0 0 0 0 0 0 
1 2 3 4 5 6 7 8 9 10 
1 3 5 7 9 11 13 15 17 19 
10 20 30 40 50 60 70 80 90 100

算法其实调用的都是模板
generate 在库中的模板:

template<class It,class Func>
void Generate(It first,It last,Func func){
        for(It it=first;it!=last;++it){
                *it = func();
        }
}

2.2 遍历

函数作用
for_each(beg,end,func)将[beg,end)范围内所有元素依次调用函数func,返回func。不修改序列中的元素
transform(beg,end,res,unary)将[beg,end)范围内所有元素依次调用函数unary,结果放入res中

transform 的用法:

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;

int func(){
        static int i=0;
        return i=i+10;
}

int Divide10(int n){
        return n/10;
}

int main(){
        vector<int> vec(10);       // 有10个元素,目前都是0
        generate(vec.begin(),vec.end(),func);
        for(auto n:vec){
                cout << n << " ";
        }
        cout << endl;
/*
        for(auto& n:vec){
                n/=10;
        }
*/
        // transform(开始,结束,从开始放入,以除10的规则放入);
        transform(vec.begin(),vec.end(),vec.begin(),Divide10);
        for(auto n:vec){
                cout << n << " ";
        }
        cout << endl;
}

结果为:

10 20 30 40 50 60 70 80 90 100 
1 2 3 4 5 6 7 8 9 10 

transform 在库中的模板:

template<class It,class It2,class Func>
void accumulate(It first,It last,It2 first2,Func func){
        for(It it=first;it!=last;++it){
                *first2 = func(*it);   // *first2 = Divide10(*it);
                ++first2;
        }
}

2.3 最大最小

函数作用
max(a,b)返回两个元素中较大一个
max(a,b,cmp)使用自定义比较操作cmp,返回两个元素中较大一个
max_element(beg,end)返回一个ForwardIterator,指出[beg,end)中最大的元素
max_element(beg,end,cmp)使用自定义比较操作cmp,返回一个ForwardIterator,指出[beg,end)中最大的元素

min 与 max 类似

3. 排序算法

3.1 排序

函数作用
sort(beg,end)默认升序重新排列元素
sort(beg,end,comp)使用函数comp代替比较操作符执行sort()
partition(beg,end,pred)元素重新排序,使用pred函数,把结果为true的元素放在结果为false的元素之前
stable_sort(beg,end)与sort()类似,保留相等元素之间的顺序关系
stable_sort(beg,end,pred)使用函数pred代替比较操作符执行stable_sort()
stable_partition(beg,end)与partition()类似,保留容器中的相对顺序
stable_partition(beg,end,pred)使用函数pred代替比较操作符执行stable_partition()

3.2 反转

函数作用
reverse(beg,end)元素重新反序排序
reverse_copy(beg,end,res)与reverse()类似,结果写入res
rotate(beg,mid,end)元素移到容器末尾,由mid成为容器第一个元素
rotate_copy(beg,mid,end,res)与rotate()类似,结果写入res

3.3 随机

函数作用
random_shuffle(beg,end)元素随机调整次序
random_shuffle(beg,end,gen)使用函数gen代替随机生成函数执行random_shuffle()

random_shuffle 的用法:

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;

int func(){
        static int i=0;
        return i=i+10;
}

int main(){
        vector<int> vec(10);
        generate(vec.begin(),vec.end(),func);
        for(auto n:vec){
                cout << n << " ";
        }
        cout << endl;

        for(int i=0;i<3;++i){
                random_shuffle(vec.begin(),vec.end());
                for(auto n:vec){
                        cout << n << " ";
                }
                cout << endl;
        }
}

结果为:

10 20 30 40 50 60 70 80 90 100 
50 40 80 90 10 60 30 20 70 100 
10 60 80 90 50 40 100 30 20 70 
60 80 70 40 90 50 30 10 20 100 

4. 查找算法

4.1 统计

函数作用
count(beg,end,val)利用==操作符,对[beg,end)的元素与val进行比较,返回相等元素个数。
count_if(beg,end,pred)使用函数pred代替==操作符执行count()。

count 的用法:

#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;

int func(){
        static int i=0;
        return i++;
}

bool IsEven(int n){
        return n%2 == 0;
}

int main(){
        vector<int> vec(10);
        generate(vec.begin(),vec.end(),func);
        for(auto n:vec){
                cout << n << " ";
        }
        cout << endl;

        cout << count(vec.begin(),vec.end(),5) << endl;   // 有几个5?
        cout << count_if(vec.begin(),vec.end(),IsEven) << endl;    // 有几个偶数?
}

结果为:

0 1 2 3 4 5 6 7 8 9 
1
5

4.2 查找

函数作用
find(beg,end,val)利用==操作符,对[beg,end)的元素与val进行比较。当匹配时结束搜索,返回该元素的InputIterator。
find_if(beg,end,pred)使用函数pred代替==操作符执行find()。
find_first_of(beg1,end1,beg2,end2)在[beg1,end1)范围内查找[beg2,end2)中任意一个元素的第一次出现。返回该元素的Iterator。
find_first_of(beg1,end1,beg2,end2,pred)使用函数pred代替==操作符执行find_first_of()。返回该元素的Iterator。
find_end(beg1,end1,beg2,end2)在[beg1,end1)范围内查找[beg2,end2)最后一次出现。找到则返回最后一对的第一个ForwardIterator,否则返回end1。
find_end(beg1,end1,beg2,end2,pred)使用函数pred代替==操作符执行find_end()。返回该元素的Iterator。
adjacent_find(beg,end)对[beg,end)的元素,查找一对相邻重复元素,找到则返回指向这对元素的第一个元素的ForwardIterator。否则返回end。
adjacent_find(beg,end,pred)使用函数pred代替==操作符执行adjacent_find()。

4.3 搜索

函数作用
search(beg1,end1,beg2,end2)在[beg1,end1)范围内查找[beg2,end2)首一次出现,返回一个ForwardIterator,查找成功,返回[beg1,end1)内第一次出现[beg2,end2)的位置,查找失败指向end1。整个区域的对应
search(beg1,end1,beg2,end2,pred)使用函数pred代替==操作符执行search()。
binary_search(beg,end,val)在[beg,end)中查找val,找到返回true。二分法,需要排好序
binary_search(beg,end,val,comp)使用函数comp代替比较操作符执行binary_search()。

4.4 边界

函数作用
equal_range(beg,end,val)返回一对iterator,第一个表示lower_bound,第二个表示upper_bound。需要排好序
equal_range(beg,end,val,comp)使用函数comp代替比较操作符执行lower_bound()。

5. 删除和替换算法

5.1 复制

函数作用
copy(beg,end,res)复制[beg,end)到res
copy_backward(beg,end,res)与copy()相同,不过元素是以相反顺序被拷贝。

5.2 移除

函数作用
remove(beg,end,val)删除[beg,end)内所有等于val的元素。注意,该函数不是真正删除函数。
remove_if(beg,end,pred)删除[beg,end)内pred结果为true的元素。
remove_copy(beg,end,res,val)将所有不等于val元素复制到res,返回OutputIterator指向被拷贝的末元素的下一个位置。
remove_copy_if(beg,end,res,pred)将所有使pred结果为true的元素拷贝到res。

remove 的用法:

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;

int func(){
        static int i=0;
        return i++;
}

int main(){
        vector<int> vec(10);
        generate(vec.begin(),vec.end(),func);
        for(auto n:vec){
                cout << n << " ";
        }
        cout << endl;
        
        auto p = remove(vec.begin(),vec.end(),2);    // 只是覆盖,不是真正的删除
        vec.erase(p,vec.end());      // 要真正删除干净还需要erase
        for(auto n:vec){
                cout << n << " ";
        }
        cout << endl;
}

结果为:

0 1 2 3 4 5 6 7 8 9 
0 1 3 4 5 6 7 8 9

5.3 替换

函数作用
replace(beg,end,oval,nval)将[beg,end)内所有等于oval的元素都用nval代替。
replace_copy(beg,end,res,oval,nval)与replace()类似,不过将结果写入res。
replace_if(beg,end,pred,nval)将[beg,end)内所有pred为true的元素用nval代替。
replace_copy_if(beg,end,res,pred,nval)与replace_if(),不过将结果写入res。

5.4 去重

函数作用
unique(beg,end)清除序列中相邻重复元素,不能真正删除元素。重载版本使用自定义比较操作。排好序的才有意义
unique(beg,end,pred)将所有使pred结果为true的相邻重复元素去重。
unique_copy(beg,end,res)与unique类似,不过把结果输出到res。
unique_copy(beg,end,res,pred)与unique类似,不过把结果输出到res。

5.5 交换

函数作用
swap(a,b)交换存储在a与b中的值。
swap_range(beg1,end1,beg2)将[beg1,end1)内的元素[beg2,beg2+beg1-end1)元素值进行交换。
iter_swap(it_a,it_b)交换两个ForwardIterator的值。

6. 算术算法

函数作用
accumulate(beg,end,val)对[beg,end)内元素之和,加到初始值val上。
accumulate(beg,end,val,binary)将函数binary代替加法运算,执行accumulate()。

accumulate 的默认用法:

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;

int func(){
        static int i=0;
        return ++i;
}

int main(){
        vector<int> vec(10);       // 有10个元素,目前都是0
        generate(vec.begin(),vec.end(),func);
        for(auto n:vec){
                cout << n << " ";
        }
        cout << endl;
        int sum = 0;
        for(auto n:vec){
                sum += n;
        }
        cout << sum << endl;

        int res = accumulate(vec.begin(),vec.end(),0);    // 0为sum的初始值,默认是加法
        cout << res << endl;
}

结果为:

1 2 3 4 5 6 7 8 9 10 
55
55

accumulate 的累乘用法:

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;

int func(){
        static int i=0;
        return ++i;
}

int mulitply(int res,int n){
        return res*n;
}

int main(){
        vector<int> vec(10);       // 有10个元素,目前都是0
        generate(vec.begin(),vec.end(),func);
        for(auto n:vec){
                cout << n << " ";
        }
        cout << endl;
        int sum = 1;
        for(auto n:vec){
                sum *= n;
        }
        cout << sum << endl;
        int res = accumulate(vec.begin(),vec.end(),1,mulitply);
        cout << res << endl;
}

结果为:

1 2 3 4 5 6 7 8 9 10 
3628800
3628800

accumulate 在库中的模板:

template<class It,class T>
T accumulate(It first,It last,T init){
        T res = init;
        for(It it=first;it!=last;++it){
                res += *it;
        }
        return res;
}

template<class It,class T,class Func>
T accumulate(It first,It last,T init,Func func){
        T res = init;
        for(It it=first;it!=last;++it){
                res = func(res,*it);
        }
        return res;
}

7. 关系算法

函数作用
equal(beg1,end1,beg2)判断[beg1,end1)与[beg2,end2)内元素都相等
equal(beg1,end1,beg2,pred)使用pred函数代替默认的==操作符。
includes(beg1,end1,beg2,end2)判断[beg1,end1)是否包含[beg2,end2),使用底层元素的<操作符,成功返回true。重载版本使用用户输入的函数。
includes(beg1,end1,beg2,end2,comp)将函数comp代替<操作符,执行includes()。

8. 集合算法

函数作用
merge(beg1,end1,beg2,end2,res)合并[beg1,end1)与[beg2,end2)存放到res。
merge(beg1,end1,beg2,end2,res,comp)将函数comp代替<操作符,执行merge()。
inplace_merge(beg,mid,end)合并[beg,mid)与[mid,end),结果覆盖[beg,end)。
inplace_merge(beg,mid,end,cmp)将函数comp代替<操作符,执行inplace_merge()。

9. 排列组合算法

9.1 排列组合

函数作用
next_permutation(beg,end)取出[beg,end)内的下移一个排列。
next_permutation(beg,end,comp)将函数comp代替<操作符,执行next_permutation()。
prev_permutation(beg,end)取出[beg,end)内的上移一个排列。
prev_permutation(beg,end,comp)将函数comp代替<操作符,执行prev_permutation()。

9.2 堆算法

函数作用
make_heap(beg,end)把[beg,end)内的元素生成一个堆。
make_heap(beg,end,comp)将函数comp代替<操作符,执行make_heap()。
pop_heap(beg,end)重新排序堆。它把first和last-1交换,然后重新生成一个堆。可使用容器的back来访问被"弹出"的元素或者使用pop_back进行真正的删除。并不真正把最大元素从堆中弹出。
pop_heap(beg,end,comp)将函数comp代替<操作符,执行pop_heap()。
push_heap(beg,end)假设first到last-1是一个有效堆,要被加入到堆的元素存放在位置last-1,重新生成堆。在指向该函数前,必须先把元素插入容器后。
push_heap(beg,end,comp)将函数comp代替<操作符,执行push_heap()。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值