c++之STL

本文深入讲解C++标准模板库(STL)的核心概念、组件构成及其使用方法,包括容器、迭代器、算法等内容,并通过多个实例演示如何应用STL解决实际问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

c++之STL

一、STL的几点概念

1、STL是C++标准程序库的核心,深刻影响了标准程序库的整体结构
2、STL由一些可适应不同需求的集合类,以及在这些数据集合上操作的算法构成
3、STL内的所有组件都由模板构成,其元素可以是任意类型
4、STL是所有C++编译器和所有操作系统平台都支持的一种库

二、STL组件的构成

1、 容器: 管理某类对象的集合

(1)序列式容器:排列次序取决于插入时机和位置

(2)关联式容器:排列顺序取决于特定准则

2、 迭代器: 在对象集合上进行遍历

3、算法: 处理集合内的元素

(1)容器适配器

(2)函数对象

三、STL容器元素的条件

1、必须能够通过拷贝构造函数进行复制

2、必须可以通过赋值运算符完成赋值操作

3、必须可以通过析构函数完称销毁动作

4、序列式容器元素的默认构造函数必须可用

5、某些动作必须定义operator ==,例如搜寻操作

6、关联式容器必须定义出排序准则,默认情况是重载

四、STL容器的共同操作

1、初始化情况
产生一个空容器
以另一个容器元素为初值完成初始化
以数组元素为初值完成初始化
2、与大小相关的操作
size()-返回当前容器的元素数量
empty()-判断容器是否为空
max_size()-返回容器能容纳的最大元素数量
3、比较
==,!=,<,<=,>,>=
比较操作两端的容器必须属于同一类型
如果两个容器内的所有元素按序相等,那么这两个容器相等
采用字典式顺序判断某个容器是否小于另一个容器

4、元素操作
insert(pos,e)-将元素e的拷贝安插于迭代器pos所指的位置
erase(beg,end)-移除[beg,end]区间内的所有元素
clear()-移除所有元素

四、vector模拟动态数组

1、vector的元素可以是任意类型T,但必须具备赋值和拷贝能力(具有public拷贝构造函数和重载的赋值操作符)
2、必须包含的头文件#include<vector>
3、vector支持随机存取
4、vector的大小(size)和容量(capacity)
5、size返回实际元素个数,
6、capacity返回vector能容纳的元素最大数量。如果插入元素时,元素个数超过capacity,需要重新配置内部存储器

五、排序和查找算法

1、find
template<class InIt, class T>
InIt find(InIt first, InIt last, constT& val);
返回区间[first,last) 中的迭代器 i ,使得 * i == val
2、find_if
template<class InIt, class Pred>
InIt find_if(InIt first, InIt last, Predpr);
返回区间[first,last) 中的迭代器 i, 使得 pr(*i) ==true

3、 binary_search 折半查找,要求容器已经有序且支持随机访问迭代器,返回是否找到
template<class FwdIt, class T>
 boolbinary_search(FwdIt first, FwdIt last, const T& val);
上面这个版本,比较两个元素x,y 大小时, 看x < y
template<class FwdIt, class T, class Pred>
bool binary_search(FwdIt first, FwdItlast, const T& val, Pred pr);
上面这个版本,比较两个元素x,y 大小时, 看pr(x,y)

4、lower_bound,uper_bound,equal_range
lower_bound:
 template<classFwdIt, class T>
FwdIt lower_bound(FwdIt first, FwdItlast, const T& val);
要求[first,last)是有序的,
查找大于等于val的最小的位置
5、sort   快速排序
template<class RanIt>
void sort(RanIt first, RanIt last);
按升序排序。判断x是否应比y靠前,就看x < y 是否为true
template<class RanIt, class Pred>
void sort(RanIt first, RanIt last, Pred pr);
按升序排序。判断x是否应比y靠前,就看pr(x,y) 是否为true

六、几个例子

1、

#include <bits/stdc++.h>
using namespace std;
template<typename T>
T add(T a, T b){
    return (a + b);
}


template<typename T1>
struct tester{
    T1 a;
};


int main(){


    cout << add(1, 2) << endl;
    cout << add(1.1, 2.2) << endl;
    return 0;


    //--------------


    int a[5] = {5,3,8,6,0};


    cout << "incremental:" << endl;
    sort(a, a + 5);
    for (int i = 0; i < 5; ++i){
        cout << a[i] << endl;
    }


    cout << "decremental:" << endl;
    sort(a, a + 5, greater<int>());
    for (int i = 0; i < 5; ++i){
        cout << a[i] << endl;
    }
    return 0;
}

2、

#include <bits/stdc++.h>
using namespace std;
int main(){
#if 0
    vector<int> con;
    vector<int>::iterator iter;
#else
    list<int> con;
    list<int>::iterator iter;
#endif
    copy(istream_iterator<int>(cin), 
            istream_iterator<int>(),
            back_inserter(con));


    cout << "output:" << endl;
    for (iter = con.begin(); iter != con.end(); iter++){
        cout << (*iter) << endl;
    }


    //sort(con.begin(), con.end());


    cout << "Another output:" << endl;
    copy(con.begin(), 
            con.end(), 
            ostream_iterator<int>(cout, "\n"));
    return 0;

}

3、

#include <bits/stdc++.h>
using namespace std;
int main(){
    vector<int> a;
    for (int i = 0; i < 5; ++i){
        a.push_back(5 - i);
    }
    cout << "Size: " << a.size() << endl;
    a.pop_back();
    a[0] = 1;


    cout << "Size: " << a.size() << endl;
    for (int i = 0; i < (int)a.size(); ++i){
        cout << a[i] << ", " << endl;
    }
    cout << endl;


    sort(a.begin(), a.end());
    cout << "Size: " << a.size() << endl;
    for (int i = 0; i < (int)a.size(); ++i){
        cout << a[i] << ", " << endl;
    }
    cout << endl;


    a.clear();
    cout << "Size: " << a.size() << endl;
    return 0;
}

4、

#include <bits/stdc++.h>
using namespace std;
int main(){
    stack<int>s;
    s.push(1);
    s.push(2);
    s.push(3);
    cout << "Top: " << s.top() << endl;
    cout << "Size: " << s.size() << endl;
    s.pop();
    cout << "Size: " << s.size() << endl;
    if(s.empty()){
        cout << "Is empty" << endl;
    }else{
        cout << "Is not empty" << endl;
    }
    return 0;

}

5、

#include <bits/stdc++.h>
using namespace std;
int main(){
    list<int>lis;
    list<int>::iterator li;
    for (int i = 0; i < 2; ++i){
        lis.push_back(i);
        lis.push_front(i);
    }
    lis.sort();
    //lis.unique();
    cout << "Size: " << lis.size() << endl;
    for (li = lis.begin(); li != lis.end(); li++){
        cout << *li << endl;
    }


    lis.pop_front();
    cout << "Size: " << lis.size() << endl;
    for (li = lis.begin(); li != lis.end(); li++){
        cout << *li << endl;
    }


    lis.pop_back();
    cout << "Size: " << lis.size() << endl;
    for (li = lis.begin(); li != lis.end(); li++){
        cout << *li << endl;
    }




    return 0;

}

6、

#include <bits/stdc++.h>
using namespace std;
struct T1{
    int v;
    bool operator<(const T1 &a)const{
        return (v < a.v);
    }
};


struct T2{
    int v;
};
struct cmp{
    const bool operator()(const T2 &a, const T2 &b){
        return (a.v < b.v);
    }
};


int main(){
    map<T1, int>mt1; //example for user-defined class
    map<T2, int, cmp>mt2; //example for user-defined class(functor)


    map<string, int> m2;
    map<string, int>::iterator m2i, p1, p2;
    //map<string, int, greater<string> >m2;
    //map<string, int, greater<string> >::iterator m2i, p1, p2;
    m2["abd"] = 2;
    m2["abc"] = 1;
    m2["cba"] = 2;
    m2.insert(make_pair("aaa", 9));
    m2["abf"] = 4;
    m2["abe"] = 2;
    cout << m2["abc"] << endl;


    m2i = m2.find("cba");
    if(m2i != m2.end()){
        cout << m2i->first << ": " << m2i->second << endl;
    }else{
        cout << "find nothing" << endl;
    }


    cout << "Iterate" << endl;
    for(m2i = m2.begin(); m2i != m2.end(); m2i++){
        cout << m2i->first << ": " << m2i->second << endl;
    }


    return 0;

}

7、

#include <bits/stdc++.h>
using namespace std;
struct T1{
    int key;
    int value1, value2;
    bool operator<(const T1 &b)const{
        return (key < b.key);
    }
};


struct T2{
    int key;
    int v1, v2;
};
struct T2cmp{
    bool operator()(const T2 &a, const T2 &b){
        return (a.key < b.key);
    }
};


int main(){
    set<T1> s2;
    set<T2, T2cmp> s3;


#if 1
    set<string>s1;
    set<string>::iterator iter1;
#else
    set<string, greater<string> >s1;
    set<string, greater<string> >::iterator iter1;
#endif
    s1.insert("abc");
    s1.insert("abc");
    s1.insert("abc");
    s1.insert("bca");
    s1.insert("aaa");


    cout << "ITERATE:" << endl;
    for (iter1 = s1.begin(); iter1 != s1.end(); iter1++){
        cout << (*iter1) << endl;
    }


    cout << "FIND:" << endl;
    iter1 = s1.find("abc");
    if(iter1 != s1.end()) {
        cout << *iter1 << endl;
    }else{
        cout << "NOT FOUND" << endl;
    }


    return 0;

}

8、

#include <bits/stdc++.h>
using namespace std;
int main(){
    string t1, t2("a");
    t1 = "b";
    cout << "t1: " << t1 << ", t2: " << t2 << endl;
    cout << "t2[0] = " << t2[0] << endl;
    t1 += "def";
    cout << "t1 = " << t1 << endl;


    if(t1 == t2){
        cout << "t1 == t2" << endl;
    }else{
        cout << "t1 != t2" << endl;
    }


    printf("t1 = %s\n", t1.c_str()); //不要修改!


    unsigned idx = t1.find("de");
    if(idx != string::npos){
        cout << "find @ index " << idx << endl;
    }else{
        cout << "not found " << endl;
    }


    string t3 = "abcd";
    t3.replace(1, 2, "ooxx");
    cout << "t3: " << t3 << ", size = " << t3.size() << endl;
    return 0;

}

9、

#include <bits/stdc++.h>

using namespace std;

int main(){
    int a[10] = {1,3,5,2,4,6,7,5,2,5};
    sort(a, a + 10);
    for (int i = 0; i < 10; ++i){
        printf("%d  ", a[i]);
    }
    printf("\n");


    int *s, *e;
    s = lower_bound(a, a + 10, 5);
    e = upper_bound(a, a + 10, 5);
    printf("[%d, %d)\n", s - a, e - a);
    while(s != e){
        printf("%d ", *s++);
    }


    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值