IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【C++笔记】十八、标准模板库(STL)(上) -> 正文阅读

[C++知识库]【C++笔记】十八、标准模板库(STL)(上)

  • 1.标准模板库(STL)概述

STL:Standard template library,包含了容器、迭代器、函数对象和算法。

  • 容器

与数组类似,可以存储若干个值

容器中每一个值的类型都是相同的

常用的容器:vector、valarray

  • 迭代器

可以用来遍历容器中的值

  • 函数对象

类似于函数的对象,可以是类对象或函数指针

  • 算法

排序

查找

2.迭代器(Iterator)基础

#include <iostream>
#include <vector>
using namespace std;
int main(int argc, const char * argv[]) {
	
    // 迭代器(Iterator)基础
    
    //1. 回顾一下vector的基本功能
    //2. 向vector追加值
    //3. 什么是迭代器
    //4. 使用迭代器获取vector中特定位置的值
    //5. 使用begin()和end()
    //6. 利用迭代器枚举vector中所有的值
    //7. 删除vector中特定区间的值
    //8. 在vector中特定的位置插入一个或一组值
    
    
    //  vector的基本功能
    /*
     vector是STL中的一个容器,用于存储若干个值
     1. vector可以像数组一样,使用[n]来引用特定位置的值
     2. size方法:获取vector中值的个数
     3. swap方法:交换容器的内容
     4. begin和end方法:来获取首、尾两个迭代器
     */
    
    vector<int> ages;
    ages.push_back(20);
    ages.push_back(30);
    ages.push_back(40);
    ages.push_back(50);
    ages.push_back(60);
    
   // cout << ages.size() << endl; // 5
   // ages.pop_back();  // 虽然60弹出了,但只改变了size的大小(尾指针),值还在vector之中
   // cout << ages[4] << endl;  // 60
   // cout << ages.size() << endl; // 4
   // ages.push_back(100);  // 从弹出那个位置开始送入值
   // cout << ages[4] << endl; // 100
    
    //  什么是迭代器
    /*
     迭代器是一个广义的指针,用于指向容器中当前的值。可以使用++、--、+、-来移动指针
     typedef iterator
    */
    
    // 使用迭代器来获取vector特定位置的值
    vector<int>::iterator it;
    
    it = ages.begin();  // 指向vector首元素
    cout << *it << endl; // 20
    it++;
    cout << *it << endl; // 30
    cout << *(it + 2) << endl;  // 50
    
    //  begin和end方法
    /*
     begin指向了容器的第一个元素的地址
     end指向了容器最后一个元素的下一个元素的地址
     */
    it = ages.end();
    cout << *(it) << endl;  // 0
    cout << *(it - 1) << endl;  // 60
    
    auto it1 = ages.begin();  // auto会自动将it1识别为vector中的迭代器,这样就省去了定义迭代器的步骤
    cout << *it1 << endl;
    
    //  枚举vector中所有的值
    //  传统的方法
    for(int i = 0; i < ages.size(); i++)
    {
        cout << ages[i] << " ";
    }
    cout << endl;
    
    //  迭代器枚举vector中的所有的值
    for(auto it = ages.begin();it != ages.end();it++)  // for(初始化;终止条件;自加)
    {
        cout << *it << " ";
    }
    cout << endl; // 20 30 40 50 60
    
    //  7. 删除vector中特定区间的值
    //  删除第3个值
    ages.erase(ages.begin() + 2);
    for(auto it = ages.begin();it != ages.end();it++)
    {
        cout << *it << " ";
    }
    cout << endl; // 20 30 50 60
    
    //  删除一个区间的值
    ages.erase(ages.begin(), ages.begin() + 3); // 删除第1个到第4个元素,包含第1个,不包含第4个
    for(auto it = ages.begin();it != ages.end();it++)
    {
        cout << *it << " ";
    }
    cout << endl; // 60
    
    // 8. 在vector中特定的位置插入一个或一组值
    ages.insert(ages.begin(), 10);  // 方法insert的第一个参数是迭代器,不是索引值
    ages.insert(ages.end(), 30);
    for(auto it = ages.begin();it != ages.end();it++)
    {
        cout << *it << " ";
    }
    cout << endl; // 10 60 30
    
    vector<int> ages1;
    ages1.push_back(100);
    ages1.push_back(200);
    ages1.push_back(300);
    
    // 将ages1中的一个区间的值,插入到ages的指定位置
    ages.insert(ages.begin(), ages1.begin() + 1, ages1.end()); // 第一个参数是被插入的vector的迭代器,第二、三个参数是要插进去的vector的迭代器
    for(auto it = ages.begin();it != ages.end();it++)
    {
        cout << *it << " ";
    }
    cout << endl;  // 200 300 10 60 30
    
    return 0;
}

3.用于替代for语句的for_each函数

#include <iostream>
#include <vector>
using namespace std;
class Person
{
public:
    int code;
    string name;
    Person(int code, string name)
    {
        this->code = code;
        this->name = name;
    }
};
void eachPerson(const Person& person)
{
    //person.code = 300; // 传入参数的类型如果不加const,则这里可以进行一些修改
    cout << "code:" << person.code << " name:" << person.name << endl;
}
int main(int argc, const char * argv[]) {
    // for_each函数
    vector<Person> persons;
    persons.push_back(Person(10, "Bill"));
    persons.push_back(Person(20, "Mike"));
    persons.push_back(Person(30, "John"));
    
    for(auto it = persons.begin(); it != persons.end(); it++) // persons.begin()返回的是一个对象
    {
        cout << "code:" << it->code << " name:" << it->name << endl;
    }
    
    for_each(persons.begin(), persons.end(), eachPerson); // 参数三要传入一个函数
    
   /* for(auto it = persons.begin(); it != persons.end(); it++)
    {
        cout << "code:" << it->code << " name:" << it->name << endl;
    }*/
    
    return 0;
}

4.用于随机排列容器中元素值的random_shuffle函数

#include <iostream>
#include <vector>
using namespace std;
void eachStr(string str)
{
    cout << str << endl;
}
int main(int argc, const char * argv[]) {
    // 随机排列容器元素的函数:random_shuffle

    vector<string> names;
    names.push_back("Bill");
    names.push_back("Mike");
    names.push_back("John");
    names.push_back("Mary");
    for_each(names.begin(), names.end(), eachStr); // Bill Mike John Mary 每遍历到一个值,就执行一次eachStr
    
    random_shuffle(names.begin(), names.end()); // 随机排列容器中的元素
    for_each(names.begin(), names.end(), eachStr); // Bill Mary John Mike
    
    random_shuffle(names.begin(), names.end());
    for_each(names.begin(), names.end(), eachStr); // 结果又会不同
    return 0;
}

5.用于对容器中元素值排序的sort函数

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

class Person
{
public:
    int code;
    Person(int code)
    {
        this->code = code;
    }
};

// 在C++中,只能对自己定义的类进行操作符重载
bool operator<(const Person& p1, const Person& p2) // 可以通过重载小于号,来改变sort的排序规则
{
   // if(p1.code <= p2.code)  // 升序
    if(p1.code >= p2.code)    // 降序
        return true;
    else
        return false;
}

bool comparePerson(const Person& p1, const Person& p2)
{
     if(p1.code <= p2.code)  // 升序
    //if(p1.code >= p2.code)    // 降序
        return true;
    else
        return false;
}

bool compareInt(int n1, int n2)
{
   // if(n1 <= n2)   //  升序
    if(n1 >= n2)     //  降序
        return true;
    else
        return false;
}

int main(int argc, const char * argv[]) {
    // 用于对容器中元素值排序的sort函数
    vector<int> numbers;
    numbers.push_back(10);
    numbers.push_back(5);
    numbers.push_back(20);
    for(auto it = numbers.begin(); it!=numbers.end();it++)
    {
        cout << *it << " "; // 空格隔开
    }
    cout << endl;  // 10 5 20
    
   // sort(numbers.begin(), numbers.end()); // 排序后默认按照升序 5 10 20排列
    sort(numbers.begin(), numbers.end(), compareInt); // 可以在sort参数三的位置,传入一个比较器
    for(auto it = numbers.begin(); it!=numbers.end();it++)
    {
        cout << *it << " ";
    }
    cout << endl;

    
    vector<Person> persons;
    persons.push_back(Person(20));
    persons.push_back(Person(10));
    persons.push_back(Person(30));
    
    for(auto it = persons.begin(); it != persons.end();it++)
    {
        cout << it->code << " ";
    }
    cout << endl;  // 20 10 30 
    
   // sort(persons.begin(), persons.end());  // 30 20 10,经过操作符重载之后,将默认的升序变为了降序
    sort(persons.begin(), persons.end(),comparePerson);
    for(auto it = persons.begin(); it != persons.end();it++)
    {
        cout << it->code << " "; 
    }
    cout << endl;  
    
    return 0;
}

6.用于查找容器中元素值的find函数

#include <iostream>
#include <vector>
using namespace std;
int main(int argc, const char * argv[]) {
    // 用于查找容器中元素值的find函数
    vector<string> names;
    names.push_back("Bill");
    names.push_back("Mike");
    names.push_back("Mike");
    names.push_back("Mary");

    vector<string>::iterator it = find(names.begin(), names.end(), "Mike1"); // 第一、二个参数定义查找范围,第三个参数写要查找的值
    if(it != names.end()) // 如果等于names.end,说明到末尾了还没找到
    {
        cout << "已经找到." << endl;
        cout << *it << endl;
    }
    else
    {
        cout << "未找到." << endl;
    }
    
    return 0;
}

7.用于复制容器元素值的copy函数

#include <iostream>
#include <vector>
using namespace std;
int main(int argc, const char * argv[]) {
    // copy函数:用于将一个容器中的元素值复制到另一个容器中
    vector<string> names;
    names.push_back("Bill");
    names.push_back("Mike");
    names.push_back("John");
    names.push_back("Mary");
    vector<string> names1(4); // 这里比4大也可以,使用copy前,要提前给目标数组分配内存空间
    copy(names.begin(), names.end(), names1.begin()); // 参数12指定数据源要复制的内容的范围,参数3指定要复制到的目标位置
    for(auto v:names1) // 用for输出vector中的所有元素的写法
    {
        cout << v << endl; // Bill Mike John Mary
    }
    
    return 0;
}

8.枚举容器中元素的3种方法

#include <iostream>
#include <vector>
using namespace std;
void printNumber(int value)
{
    cout << "for_each:" << value << endl;
}
int main(int argc, const char * argv[]) {
    // 枚举容器中元素值的3种方法
    vector<int> numbers;
    numbers.push_back(10);
    numbers.push_back(5);
    numbers.push_back(20);
    //  第1种方法
    for(auto it = numbers.end() - 1; it != numbers.begin() - 1;it--) // 这样是从后往前数,此时要注意从numbers.end() - 1开始,从numbers.begin() - 1结束,因为for的范围取前不取后
    {
        cout << *it << endl;    //  20 5 50
    }
    //  第2种方法,只能从前往后数
    for_each(numbers.begin(), numbers.end(), printNumber); // 打印 for_each:10 for_each:5 for_each:20
    
    //  第3种方法
    //  C++ 11  基于范围的for循环
    for(auto n:numbers) // n不是迭代器
    {
        cout << "基于范围的for循环:" << n << endl; // 10 5 20
    }
    return 0;
}

9.将STL算法用于非STL容器

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

bool compareInt(int n1, int n2)
{
    if(n1 >= n2)
        return true;  // 降序
    else
        return false;
}

int main(int argc, const char * argv[]) {
    // 将STL算法用于非STL容器
    // sort、copy等都是基于迭代器实现的
    
    // 基础理论:指针 = 迭代器
    int values[] {4,5,1,7,-20};
    size_t size = sizeof(values)/sizeof(int);
    sort(values, values + size); // 传入的是指针
    for(auto v:values)
    {
        cout << v << " "; 
    }
    cout << endl;   // -20 1 4 5 7
    
    sort(values, values + size, compareInt);
    for(auto v:values)
    {
        cout << v << " ";
    }
    cout << endl; // 7 5 4 1 -20
    
    vector<int> v_values(5); // 使用copy前要预先分配空间
    copy(values, values+size, v_values.begin()); // STL容器和非STL容器混合使用
    for(auto v:v_values)
    {
        cout << v << " ";
    }
    cout << endl; // 7 5 4 1 -20
    return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-20 14:54:29  更:2021-08-20 14:55:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 14:03:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码