STL简单总结

目录

一、模板

                  1. 使用者决定参数类型

2. 函数模板和普通函数的区别

3. 函数模板被调用的顺序

4. 生成模板函数

5. 模板的特点

二、STL中的强制类型转换

1. static_cast

2. dynamic_cast

3. const_cast

4. reinterpret_cast

三、STL基本概念

1. STL(Standard Template Library, 标准模板库)

2. 容器

2.1 string的特性

2.2 vector容器

2.3 deque容器

2.4 stack容器

2.5 queue容器

2.6 list(链表)

2.7 set/multiset容器

2.8 map/multimap容器

2.9 STL容器共性机制

2.10 STL容器使用时机

三、常用算法

3.1函数对象

3.1.1函数对象的概念

3.1.2谓词概念

3.1.3 内建函数对象

3.1.4 函数对象适配器

3.2 常用查找算法

3.2 常用遍历算法


一、模板

1. 使用者决定参数类型

模板技术使类型参数化,编写代码时可以忽略参数类型,让使用者决定参数类型。

如何告诉编译器是模板函数:template<class T>

template<class T>
void MyFun(T& a, T& b){
         T temp = a;
         a = b;
         b = temp;
}

2. 函数模板和普通函数的区别

普通函数可以进行自动类型转换,函数模板必须严格类型匹配。

3. 函数模板被调用的顺序

函数模板->模板函数->被调用

函数模板在调用的时候,可以自动类型推导;

模板必须显示指定类型,例:

template <class T>
class Person{
public:
	Person(T id, T age){
	    …;
    }
};

int main(){
	Person<int> p(10, 20);
    …;
    return 0;
}

4. 生成模板函数

想让编译器知道要生成什么样的模板函数(自动类型推导),可以定义为如下形式

template<class T1, class T2> //此处可以定义多个class T

void Myfun(T & a, T& b){
	…;
}
int main(){
	float f = 0.0;
	int i = 0;
    Myfun(f, i);
	Myfun(i, f); //此时生成两个模板函数
	return 0;
}

5. 模板的特点

普通派生类继承模板类时,必须明确定义模板类型;模板派生类集成模板类时,不需要立刻指定模板类型。

二、STL中的强制类型转换

1. static_cast

一般类型转换:

转换基础数据类型;如果转换指针和引用,必须在一个继承树下。

2. dynamic_cast

通常在基类和派生类之间转换时使用:

转换具有集成关系的指针和引用,在转换钱会进行对象类型安全检查,子类指针可以转换为父类指针(从大到小),类型安全,可以转换。父类指针转换为子类指针(从小到大),类型不安全,不可以转换。

3. const_cast

主要针对const的转换

增加和去掉const

4. reinterpret_cast

用于进行没有任何关联之间的转换:

例如一个字符指针转换为一个整形数;无关的指针类型都可以进行转换。

以上四个类型转换,一定要自己写一写,才能加深印象。当使用有问题时,编译器会直接报出错误。

三、STL基本概念

1. STL(Standard Template Library, 标准模板库)

STL从广义上分为:容器(container),算法(algorithm),迭代器(iterator容器算法之间通过迭代器(容器和算法之间的桥梁)进行无缝连接,STL几乎所有的代码都采用了模板或者模板函数,这相比传统的有函数和类组成的库来说提供了更好的代码重用机会。

在C++标准中,STL被组织成以下13个头文件:

<algorithm>、<deque>、<functional>、<iterator>、<vector>、<list>、<map>、<memory>、<numeric>、<queue>、<set>、<stack>、<utility>

2. 容器

容器分为序列容器和关联容器。

// …此处需要补充

2.1 string的特性

  • char*是一个指针,string是一个类:

     string封装了char*,管理这个字符串,是一个char*型的容器。

  • string封装的成员方法:

        查找find,拷贝copy,删除delete,替换replace,插入insert

  • 不用考虑内存的释放和越界

        string管理char*所分类的内存,每一次string的赋值,取值都由string类负责维护,不用担心

        赋值越界和取值越界等问题。

  • string和char*通过string提供的c_str()方法进行转换。

2.2 vector容器

         vector容器是一个长度动态改变的动态数组,拥有一段连续的内存,具有数组的随机存取的优点。

2.2.1 vector特性:

  • vector是动态数组,连续内存空间,具有随机存取效率高的特点。
  • vector是单口容器,在队尾插入和删除元素效率高,在制定位置插入会导致数据元素移动,效率低。

如下图:

vector中reserve和resize的区别:

         reserve是容器预留空间,但在空间内不会真正创建元素对象,所以在没有添加新的对象之前,不能引用容器内的元素。

         resize是改变容器的大小,且会创建对象,因此调用这个函数之后,就可以引用容器内的对象了。

如果提前知晓容器大小,且容器需求容量较大,可以巧用reserve,增加程序效率。

总结:vector是个动态数组,当空间不足时插入新元素,vector会重新申请一块更大的内存空间,将旧空间数据拷贝到新空间,然后释放旧空间,vector是单口容器,所以在尾端插入和删除元素效率较高,在指定位置插入,会引起数据元素移动,效率较低。

2.3 deque容器

2.3.1 deque特性

         deque是“double-ended queue”的缩写,deque支持随机存取。deque是一种双向开口的连续性空间,可以再头尾两端分别做元素的插入和删除操作。

deque和vector最大差异有两点:

  1. 在于deque允许常数时间内对头端进行元素插入和删除操作。
  2. 在于deque没有容量的概念,因为他是动态的以分段的连续空间组合而成,随时可以增加一段新的空间并链接起来。

2.4 stack容器

2.4.1特点:

         先进先出。

        没有提供迭代器,不能遍历,不支持随机存取。

2.5 queue容器

2.5.1 queue特性

         queue是一种先进先出(first in first out,FIFO)的数据类型,有两个口,数据元素只能从一个口进,另一个口出。队列只允许从队尾加入元素,队头删除元素,必须符合先进先出的原则,queue和stack一样不具有遍历行为。

2.6 list(链表)

2.6.1 链表特点

链表是由一系列的节点组成,节点包含两个域,一个数据域,一个指针域。

  1. 链表内存是非连续的,添加删除元素,时间复杂度都为常数项,不需要移动元素,比数组添加删除效率高。
  2. 链表只有在需要的时候,才分配内存。
  3. 聊表需要额外的空间保存节点关系(前驱和后继)。
  4. 只要拿到第一个节点,相当于拿到整个链表。

 

2.6.2 list大小操作

size(); //返回容器中的元素个数
empty(); //判断容器是否为空
resize(num); //重新制定容器的长度为num,如果容器变长,则以默认值填充新位置,如果容器变短,则末尾超出容器长度的元素被删除。
resize(num, elem); //重新制定容器的长度为num,如果容器变长,则以elem值填充新位置,如果容器变短,则末尾超出容器长度的元素被删除。

2.6.3 list赋值操作

assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身
assign(n, elem); //将n个elem拷贝赋值给本身
list& operator=(const list& list); //重载等号运算符
swap(lst); //将lst与本身的元素互换

2.6.4 list数据的存取

front(); //返回第一个元素
back(); //返回最后一个元素

2.6.5 list数反转排序

reverse(); //反转链表,比如list包含1,3,5元素,运行此方法后,list就包含5,3,1元素
sort(); //list排序(算法sort支持可随机访问的容器,所以list自己提供了sort算法)

链表和数组的区别:

  1. 数组必须实现定义固定的长度(元素个数),不能适应数据的动态增减,当数据增加时,坑呢超出原先定义的元素个数;当减少时,造成内存浪费。
  2. 链表动态的进行存储和分配,可以适应数据动态的增减,且可以方便的插入、删除数据元素。(数组中插入、删除数据项时,需要移动其他数据项)

2.7 set/multiset容器

2.7.1 set/multiset特性

set/multiset的特性所有元素会根据元素的值自动进行排序。set是以RB-tree(红黑树,平衡二叉树的一种)为底层机制,其查找效率非常好。set容器中不允许重复元素,multiset允许重复元素。

二叉树就是任何节点最多只允许有两个子节点,分别是左子节点和右子节点。

二叉搜索树,是指二叉树中的节点按照一定的规则进行排序,使得对二叉树中元素访问更加高效。二叉搜索树的放置规则是:任何节点的元素值一定大于其左子树中的每个节点的元素值,并且小于其右子树的值。因此从根节点一直向左走,一直到无路可走,即得到最小值,一直向右走,直至无路可走,可得到最大值。那么在二叉搜索树中找到最大元素和最小元素是非常简单的事儿。

set容器只有insert()方法,没有push等方法。set容器元素值不可以相等,multiset可以放值相等的元素。不可以通过迭代器直接修改元素的值。

2.7.2 set常用API

2.7.2.1 set构造函数

set<T> set; //set默认构造函数
multiset<T> mst; //multiset默认构造函数
set(const set &set); //拷贝构造函数

2.7.2.1 set赋值操作

set& operator=(const set& set); //重载等号操作符
swap(set); //交换两个集合容器

2.7.2.1 set大小操作

size(); //返回容器中元素的个数
empty(); //判断容器是否为空

2.8 map/multimap容器

2.8.1 map/multimap特性

         map相对于set区:map具有键值和实值,所有元素根据键值自动排序,pair的第一元素被称为键值,第二元素被称为实值。map也是以红黑树为底层实现机制。

         迭代器是不可以修改map的键值,键值关系到排列规则,任意改变键值会破坏容器的排列规则,但可以改变实值。

         map和multimap的区别,map不允许相同的key值存在,multimap则允许相同key值存在。

2.8.2 map常用API

2.8.2.1 map删除操作

clear(); //删除所有元素
erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg,end); //删除区间[beg, end)的所有元素,返回下一个元素的迭代器。
earse(keyElement); //删除容器中key为keyElement的对组。

2.8.2.2 map查找操作

find(key); //查找键值key是否存在,存在则返回该键值所在元素的迭代器;不存在则返回map.end();
count(keyElement); //返回容器中key为keyElement的对组个数。对map来说要么是0要么是1;对multimap来说值可能大于1.
lower_bound(keyElement); //返回第一个key<=keyElement元素的迭代器。
upper_bount(keyElement); //返回第一个key>keyElement元素的迭代器。
equal_range(keyElement); //返回容器中key与keyElement相等的上下限的两个迭代器。

2.9 STL容器共性机制

         STL容器所提供的都是值寓意,而非引用寓意,也就是说当我们给容器中插入元素的时候,容器内部实施了拷贝动作,将我们要插入的元素再另行拷贝一份放入到容器中,而不是将原数据元素直接放进容器中,也就是说我们提供的元素必须能够被拷贝。

         ⊙除了queue和stack之外,每个容器都提供可返回迭代器的函数,运用返回的迭代器就可以访问元素。

         ⊙通常STL不会抛出异常,需要使用者传入正确参数。

         ⊙每个容器都提供了一个默认的构造函数和拷贝构造函数。

         ⊙大小相关的构造方法:

  1. size()返回容器中元素的个数
  2. empty()判断容器是否为空

2.10 STL容器使用时机

  • vector使用场景:比如软件历史操作记录的存储,由于经常要查看历史记录,比如上一次的记录,上上次的记录,但却不会去删除记录,因为记录是事实的描述。
  • deque使用场景:比如排队购票系统,对排队者的存储可以采用deque,支持头端的快速移除,尾端的快速添加,如果采用vector,则头端移除时,会移动大量的数据,速度慢。

        vector和deque的比较:

        一:vector.at()比deque.at()效率高,vector.at(0)是固定的,deque的开始位置是不固定的。

        二:如果有大量释放操作,vector花费时间更少,这与二者的内部实现有关。

        三:deque支持头部快速插入与快速移除,这是deque的优点。

  • list使用场景:比如公交车乘客的存储,随时可能有乘客下车,支持频繁的不确实位置元素的移除插入。
  • set使用场景:比如对手机游戏的个人得分纪录存储,存储要求从高分到低分的数序排列。
  • map使用场景:比如按ID存储十万个用户,想要快速通过ID查找到对应用户。二叉树的查找效率,这是就体现出来了。如果是vector容器,最坏的情况下可能要遍历完整个容器才能找到该用户。

三、常用算法

3.1函数对象

3.1.1函数对象的概念

       重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象,也叫仿函数(functor),其实就是重载“()”操作符,使得类对象可以像函数那样调用。

注意:

  1. 函数对象是一个类,不是一个函数。
  2. 函数对象重载了“()”操作符使得他可以像函数一样调用。

假定某个类有一个重载operator(),而且重载的operator()要求获取一个参数,我们就将这个类称为“一元仿函数”(unary functor);如果重载的operator()要求获取两个参数,就将这个类称为“二元仿函数”(binary functor)…

3.1.2谓词概念

         谓词是指普通函数或重载的operator()返回值是bool的函数对象(仿函数),如果operator接受一个参数,那么叫一元谓词,如果接受两个参数,那么叫做二元谓词,谓词可以作为一个判断式。

例如:

struct myfunc01{

    bool operator()(int i){} //接受一个参数,并且返回值为bool 即一元谓词

};
bool compare01(int i) //同样是叫做一元谓词  

struct myfunc02{

    bool operator()(int i, int j){} //接受两个参数,并且返回值为bool 即二元谓词

};
bool compare02(int i, int j) //同样是叫做二元谓词

3.1.3 内建函数对象

         STL内建了一些函数对象。分为:算数类函数对象,关系运算类函数对象,逻辑运算类仿函数。这些仿函数所产生的对象,用法和一般函数完全相同,我们还可以产生无名的临时对象来履行函数功能。使用内建函数对象,需要引入头文件 #include <functional>。

  • 6个算数类函数对象,除了negate是一元运算,其他都是二元运算。
template<class T> T plus<T> //加法仿函数
template<class T> T minute<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个关系类函数对象,每一种都是二元运算。
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> //小于等于

  • 逻辑运算类运算函数,logical_not为一元运算,其余是二元运算。
template<class T> bool logical_and<T> //逻辑与
template<class T> bool logical_or<T> //逻辑或
template<class T> bool logical_not<T> //逻辑非

         例子:

         // 使用内建函数对象声明一个对象        

plus<int> myPlus;
cout << myPlus(10, 20) << endl;

         // 使用匿名临时对象

        

cout << plus<int>()(10, 20) << endl;

3.1.4 函数对象适配器

         函数对象适配器是完成一些配接工作,这些配接包括绑定(bind),否定(negate),以及对一般函数或成员函数的修饰,使其成为函数对象,重点掌握函数对象适配器(红色字体):

         bind1st : 将参数绑定为函数对象的第一个参数

         bind2nd : 将参数绑定为函数对象的第二个参数

         not1 : 对一元函数对象取反

         not2 : 对二元函数对象取反

         ptr_fun : 将普通函数修饰成函数对象

         mem_fun : 修饰成员函数

         mem_fun_ref : 修饰成员函数

        

预定义函数对象:

         仿函数适配器:bind1st bind2nd 绑定适配器看如下代码test01()

         仿函数适配器:not1 not2 取反适配器看如下代码test02()

         仿函数适配器:ptr_fun 看如下代码test03()

         成员函数适配器:mem_fun mem_fun_ref 看如下代码test04()

#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>

using namespace std;

struct MyPrint : public binary_function<int, int, void>{
    void operator()(int i, int j) const{
        cout << i + j << " ";
    }
};

// 仿函数适配器bind1st bind2nd 绑定适配器
void test01(){
    vector<int> vec;
    for(int iCnt = 0; iCnt < 10; iCnt++){
        vec.push_back(iCnt);
    }

    // 绑定适配器 将一个二元函数对象转变成一元函数对象
    // bind1st和bind2nd的区别
    // bind1st,将addNum绑定为函数对象的第一个参数
    // bind2nd,将addNum绑定为函数对象的第二个参数
    int addNum = 100;
    for_each(vec.begin(), vec.end, bind2nd(MyPrint(), addNum));
    // for_each(vec.begin(), vec.end, bind1st(MyPrint(), addNum));
}

// 仿函数适配器 not1 not2 取反适配器
struct MyCompare() : publid binary_function<int, int, void>{
    bool operator()(int i, int j) const{
        return i > j;
    }
};

struct MyPrint02(){
    void operator()(int i){
        cout << i << " ";
    }
};

struct MyGreater : public unary_function(int, bool){
    bool operator()(int i) const{
        return i > 5;
    }
};

void test02(){
    vector<int> vec;
    for(int iCnt = 0; iCnt < 10; iCnt++){
        vec.push_back(iCnt);
    }

    for_each(vec.begin(), vec.end, MyPrint02);
    cout << endl;
    sort(vec.begin, vec.end, not2(MyCompare()));
    for_each(vec.begin(), vec.end, MyPrint02);
    cout << endl;
    
    // not1 not2
    // 如果对二元谓词取反,用not2
    // 如果对一元谓词取反,用not1
    vector<int>::iterator it = find_if(vec.begin(), vec.end(), not1(MyGreater()));
    if(it == vec.end()){
        cout << "没有找到" <<endl;
    }else{
        cout << *it <<endl;
    }
        
}

// 仿函数适配器 ptr_fun
void MyPrint03(int i, int j){
    cout << "i:" << i << " j:" << j << endl;
    cout << i + j << endl;
};

void test03(){
    vector<int> vec;
    for(int iCnt = 0;iCnt < 10; iCnt++){
        vec.push_back(iCnt);
    }
    // ptr_fun把普通函数转成函数对象
    for_each(vec.begin(), vec.end(), bind2nd(ptr_fun(MyPrint03), 10));
}

// 成员函数适配器 mem_fun mem_fun_ref
class Person{
public:
    Person(int age, int id):m_age(age), m_id(id){}
    void show(){
        cout << "age:" << m_age << " id:" << m_id << endl;
    } 

public:
    int m_age;
    int m_id;
};

void test04(){
    // 如果容器中存放的对象或者对象指针,for_each算法打印的收,调用类自己提供的打印函数
    vector<Person> vec;
    Person p1(10, 20), p2(30, 40), p3(50, 60);
    vec.push_back(p1);
    vec.push_back(p2);
    vec.push_back(p3);
    // 格式:&类名::函数名
    for_each(vec.begin(), vec.end(), mem_fun_ref(&Person::show));

    vector<Person*> vec1;
    vec1.push_back(&p1);
    vec1.push_back(&p2);
    vec1.push_back(&p3);
    for_each(vec1.begin(), vec1.end(), mem_fun(&Person::show));

    // mem_fun和mem_fun_ref区别
    // 如果存放的对象指针,使用mem_fun
    // 如果存放的是对象,使用mem_fun_ref
}

void main(){
    test01();
    test02();
    test03();
    test04();
}

3.2 常用查找算法

/*
    find算法
    @param beg 容器开始迭代器
    @param end 容器结束迭代器
    @param value 查找的元素
    @return 返回查找元素的位置
*/
find(iterator beg, iterator end, value);

/*
    adjacent_find 算法:查找相邻重复元素
    @param beg 容器开始迭代器
    @param end 容器结束迭代器
    @param _callback 回调函数或者谓词(返回bool类型的函数对象)
    @return 返回相邻元素的第一个位置的迭代器
*/
adjacent_find(iterator beg, iterator end, _callback);

/*
    binary_search算法:二分查找法
    @param beg 容器开始迭代器
    @param end 容器结束迭代器
    @param value 查找的元素
    @return bool 找到返回true,否则返回false
*/
bool binary_search(iterator beg, iterator end, value)

/*
    find_if算法:条件查找
    @param beg 容器开始迭代器
    @param end 容器结束迭代器
    @param _callback 回调函数或者谓词(返回bool类型的函数对象)
    @return 返回查找元素的位置
*/
find_if(iterator beg, iterator end, _callback);

3.2 常用遍历算法

/*
    遍历算法
    @param beg 容器开始迭代器
    @param end 容器结束迭代器
    @param _callback 函数回调或者函数对象
    @return 函数对象
*/
for_each(iterator beg, iterator end, _callback);

/*
    transform算法:将指定容器区间元素搬运到另一个容器中
    注意:transform不会给目标容器分配内存,所以需要提前分配好内存
    @param beg1 源容器开始迭代器
    @param end1 源容器结束迭代器
    @param beg2 目标容器开始迭代器
    @param _callback 函数回调或者函数对象
    @return 返回目标容器迭代器
*/
transform(iterator beg1, iterator end1, iterator beg2, _callback);
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

// transform将一个容器的元素 搬运 到另一个容器中
struct MyPlus{
    int operator()(int i){
        return i + 10;
    }
};

void MyPrint(int i){
    cout << i << " "; 
}

void test01(){
    vector<int> vec1;
    vector<int> vec2;

    for(int iCnt = 0; iCnt < 10; iCnt++){
        vec1.push_back(iCnt);
    }

    vec2.resize(vec1.size());
    
    transform(vec1.begin(), vec1.end(), vec2.begin(), MyPlus());
    for_each(vec2.begin(), vec2.end(), MyPrint);

}

void main(){
    
    test01();
    return;
}

感谢黑马程序员老师的讲解,故整理如上内容,希望大家共同学习,共同进步!!!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: STL(Standard Template Library)算法是C++标准库中的一组通用算法,用于处理各种类型的数据结构。STL算法提供了一系列函数对象和迭代器,以便能够对容器中的元素进行常见的操作,如查找、排序、删除、替换等。 STL算法主要分为以下几类: 1. 非修改性算法:这类算法不会改变容器中的元素,例如查找、计数、比较等。常用的函数包括find、count、equal等。 2. 修改性算法:这类算法会修改容器中的元素,例如排序、删除、替换等。常用的函数包括sort、remove、replace等。 3. 排序算法:STL提供了多种排序算法,如快速排序、归并排序等。常用的函数包括sort、stable_sort等。 4. 数值算法:这类算法主要用于数值计算,如求和、积累、内积等。常用的函数包括accumulate、inner_product等。 5. 集合操作:这类算法主要用于集合的操作,如交集、并集、差集等。常用的函数包括set_intersection、set_union等。 STL算法的优势在于其通用性和高效性。通过使用STL算法,我们可以在不同类型的容器上进行相同的操作,避免了针对不同容器实现不同操作的麻烦。此外,STL算法的底层实现经过优化,通常比手动编写的算法更高效。 总之,STL算法是C++标准库中提供的一组通用算法,用于处理各种类型的数据结构。通过使用STL算法,我们可以方便地对容器进行各种操作,提高开发效率并保证程序的高效性。 ### 回答2: STL算法是C++标准模板库(Standard Template Library)中的一部分,它提供了丰富的算法操作,方便我们在处理数据时进行快速、高效的操作。 STL算法包含很多算法函数,比如排序(sort)、查找(find)、替换(replace)、去重(unique)、合并(merge)等等。这些算法函数可以处理各种数据容器,比如数组、容器、字符串等。 STL算法的使用非常方便,我们只需要包含<algorithm>头文件,并使用其中的函数即可。例如,我们可以使用sort函数对一个数组进行排序,使用find函数在容器中查找某个元素,使用replace函数替换容器中的某个值等等。 STL算法的好处是它提供了统一的接口和一致的命名规范,使得我们在处理不同的数据结构时都能使用相同的函数名来调用相应的操作。这样可以大大提高代码的复用性和可读性,减少了我们编写和维护代码的工作量。 此外,STL算法还可以通过函数对象(function object)、谓词(predicate)等机制来灵活地进行自定义操作。我们可以自定义比较函数来实现按照特定条件进行排序,或者自定义判断函数来在查找时指定特定的条件等。这样可以让我们的代码更加灵活和可扩展。 总之,STL算法是C++中非常重要和强大的一部分,它提供了丰富的算法函数,方便我们在处理数据时进行各种操作。它的使用简单方便,可以提高代码的复用性和可读性,是C++开发中不可或缺的工具之一。 ### 回答3: STL(Standard Template Library,标准模板库)是C++中的一个重要部分,其中的算法部分(Algorithm)是其核心。STL Algorithm提供了一组强大的算法,用于对各种容器(如数组、向量、列表等)中的元素进行各种操作和处理。 STL算法可以分为若干类别,其中包括常用算法、排序算法、查找算法、数值算法等等。常用算法如copy(复制)、find(查找)、transform(转换)等,它们可以快速且高效地完成各种常见的操作。排序算法如sort(排序)、stable_sort(稳定排序)等,可以根据指定的规则对容器中的元素进行排序。查找算法如binary_search(二分查找)和lower_bound(寻找下界)等,可以在有序容器中快速查找指定元素。数值算法如accumulate(累加)、partial_sum(部分求和)等,用于对数值进行处理和计算。 STL的优势在于其算法的可重用性和通用性。STL Algorithm是基于模板的设计,它可以适用于不同类型的容器和元素。无论是基本数据类型还是自定义类型,只要满足一定的要求(如支持迭代器),就可以使用STL算法对其进行操作。这种通用性使得STL Algorithm可以被广泛应用于各种场景,大大提高了开发效率。 总结来说,STL算法是C++中的一组强大工具,用于对各种容器中的元素进行各种操作和处理。它的通用性和可重用性使得开发者可以更加高效地完成各种任务,提高代码的可读性和可维护性。无论是在日常开发中还是在算法竞赛中,STL Algorithm都扮演着重要的角色。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

whyperfect

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值