咸宁燃冰世纪教育

C++常用算法函数整理

掌握这些STL算法函数,让你的代码更简洁高效

介绍

在C++的<algorithm>头文件中,包含了许多实用的算法函数,它们可以高效处理容器(如数组、vector等)的元素。这些函数不仅能简化代码,还能提高程序效率,是每个C++程序员都应该掌握的工具。

本文整理了与sort、unique类似的常用算法函数,按功能分类介绍,包括它们的用法、示例和注意事项,帮助你更好地理解和运用这些强大的工具。

使用提示

  • 大部分函数的参数是迭代器(如begin()和end()),适用于数组、vector、list等多种容器
  • 部分函数(如unique、lower_bound)需要容器先排序才能正确工作
  • 点击左侧导航可以快速跳转到相应章节
  • 所有代码示例均可点击右上角复制按钮进行复制

排序与打乱

1. sort

功能:对容器元素进行升序排序(默认),可自定义排序规则。排序算法采用的是 introsort(内省排序),结合了快速排序、堆排序和插入排序的优点。

示例:

sort函数用法示例
// 完整的sort函数示例代码
#include <iostream>      // 包含输入输出流库
#include <vector>       // 包含vector容器
#include <algorithm>   // 包含sort函数

// 自定义降序比较函数
bool descendingOrder(int a, int b) {
    return a > b;  // a大于b时返回true,即降序排列
}

int main() {
    // 创建并初始化一个vector容器
    std::vector<int> numbers = {3, 1, 4, 2, 5};
    
    // 输出排序前的元素
    std::cout << "排序前: ";
    for(int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    
    // 1. 默认升序排序
    std::sort(numbers.begin(), numbers.end());
    
    // 输出升序排序后的结果
    std::cout << "升序排序后: ";
    for(int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    
    // 2. 使用自定义函数进行降序排序
    std::sort(numbers.begin(), numbers.end(), descendingOrder);
    
    // 输出降序排序后的结果
    std::cout << "降序排序后(自定义函数): ";
    for(int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    
    // 3. 使用lambda表达式进行降序排序(更简洁的方式)
    std::sort(numbers.begin(), numbers.end(),
              [](int a, int b) { return a > b; });
    
    // 输出lambda表达式排序后的结果
    std::cout << "降序排序后(lambda): ";
    for(int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

运行结果:
排序前: 3 1 4 2 5
升序排序后: 1 2 3 4 5
降序排序后(自定义函数): 5 4 3 2 1
降序排序后(lambda): 5 4 3 2 1

2. stable_sort

功能:稳定排序(相等元素的相对顺序不变),效率略低于sort。稳定排序保证相等元素在排序后的相对位置与排序前相同。

适用场景:需要保留原始相对顺序时(如先按成绩排序,再按姓名排序时保持同成绩者的姓名顺序)。

示例:

stable_sort函数用法示例
// 完整的stable_sort函数示例代码
#include <iostream>      // 包含输入输出流库
#include <vector>       // 包含vector容器
#include <algorithm>   // 包含stable_sort函数
#include <string>       // 包含string类

// 定义一个学生结构体,包含姓名和分数
struct Student {
    std::string name;  // 学生姓名
    int score;        // 学生分数
    
    // 构造函数,方便初始化
    Student(std::string n, int s) : name(n), score(s) {}
};

int main() {
    // 创建并初始化学生 vector
    std::vector<Student> students = {
        Student("Alice", 85),
        Student("Bob", 75),
        Student("Charlie", 85),
        Student("David", 90),
        Student("Eve", 75)
    };
    
    // 输出排序前的学生信息
    std::cout << "排序前的学生列表:" << std::endl;
    for(const Student& s : students) {
        std::cout << s.name << ": " << s.score << std::endl;
    }
    
    // 使用stable_sort按分数降序排序
    // 分数相同的学生将保持原有的相对顺序
    std::stable_sort(students.begin(), students.end(),
                     [](const Student& a, const Student& b) {
                         return a.score > b.score;
                     });
    
    // 输出排序后的学生信息
    std::cout << "\n按分数降序排序后的学生列表:" << std::endl;
    for(const Student& s : students) {
        std::cout << s.name << ": " << s.score << std::endl;
    }
    std::cout << "注意:分数相同的学生(Alice和Charlie, Bob和Eve)保持了原来的顺序" << std::endl;
    
    return 0;
}

运行结果:
排序前的学生列表:
Alice: 85
Bob: 75
Charlie: 85
David: 90
Eve: 75

按分数降序排序后的学生列表:
David: 90
Alice: 85
Charlie: 85
Bob: 75
Eve: 75
注意:分数相同的学生(Alice和Charlie, Bob和Eve)保持了原来的顺序

3. reverse

功能:反转容器中元素的顺序。将指定范围内的元素首尾颠倒,第一个元素和最后一个元素交换位置,第二个和倒数第二个交换,以此类推。

示例:

reverse函数用法示例
// 完整的reverse函数示例代码
#include <iostream>      // 包含输入输出流库
#include <vector>       // 包含vector容器
#include <algorithm>   // 包含reverse函数
#include <string>       // 包含string类,也可以被反转

// 打印vector元素的函数
void printVector(const std::vector<int>& v, const std::string& msg) {
    std::cout << msg << ": ";
    for(int num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}

int main() {
    // 1. 反转整个vector
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    printVector(numbers, "反转前");
    
    // 反转整个容器
    std::reverse(numbers.begin(), numbers.end());
    printVector(numbers, "反转后");
    
    // 2. 反转容器的一部分
    std::vector<int> numbers2 = {10, 20, 30, 40, 50, 60};
    printVector(numbers2, "\n部分反转前");
    
    // 反转从第2个元素到第5个元素(索引1到4)
    std::reverse(numbers2.begin() + 1, numbers2.begin() + 5);
    printVector(numbers2, "部分反转后");
    
    // 3. 反转字符串
    std::string str = "Hello, World!";
    std::cout << "\n字符串反转前: " << str << std::endl;
    
    std::reverse(str.begin(), str.end());
    std::cout << "字符串反转后: " << str << std::endl;
    
    return 0;
}

运行结果:
反转前: 1 2 3 4 5
反转后: 5 4 3 2 1

部分反转前: 10 20 30 40 50 60
部分反转后: 10 50 40 30 20 60

字符串反转前: Hello, World!
字符串反转后: !dlroW ,olleH

4. shuffle

功能:随机打乱容器元素(需要配合随机数生成器)。shuffle函数使用均匀分布来随机排列元素,比传统的rand()方法更均匀。

示例:

shuffle函数用法示例
// 完整的shuffle函数示例代码
#include <iostream>        // 包含输入输出流库
#include <vector>         // 包含vector容器
#include <algorithm>     // 包含shuffle函数
#include <random>         // 包含随机数生成器
#include <chrono>         // 用于获取系统时间作为随机种子

// 打印vector元素的函数
void printVector(const std::vector<int>& v, const std::string& msg) {
    std::cout << msg << ": ";
    for(int num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}

int main() {
    // 创建一个包含1到10的vector
    std::vector<int> numbers;
    for(int i = 1; i <= 10; ++i) {
        numbers.push_back(i);
    }
    
    printVector(numbers, "打乱前");
    
    // 创建随机数生成器
    // 使用系统时间作为种子,确保每次运行结果不同
    unsigned seed = static_cast<unsigned>(
        std::chrono::system_clock::now().time_since_epoch().count()
    );
    
    std::mt19937 rng(seed); // 使用梅森旋转算法的随机数生成器
    
    // 第一次打乱
    std::shuffle(numbers.begin(), numbers.end(), rng);
    printVector(numbers, "第一次打乱后");
    
    // 第二次打乱(得到不同的结果)
    std::shuffle(numbers.begin(), numbers.end(), rng);
    printVector(numbers, "第二次打乱后");
    
    // 示例:模拟洗牌
    std::vector<int> cards;
    for(int i = 1; i <= 52; ++i) {
        cards.push_back(i); // 52张牌
    }
    
    std::shuffle(cards.begin(), cards.end(), rng);
    std::cout << "\n洗牌后的前5张牌: ";
    for(int i = 0; i < 5; ++i) {
        std::cout << cards[i] << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

运行结果(每次运行结果不同):
打乱前: 1 2 3 4 5 6 7 8 9 10
第一次打乱后: 7 3 9 1 10 5 2 4 8 6
第二次打乱后: 5 8 2 10 3 9 4 1 6 7

洗牌后的前5张牌: 23 15 47 8 31

去重与查找

1. unique

功能:移除相邻的重复元素(需先排序),返回去重后最后一个有效元素的下一个位置。注意,unique并不会真正删除元素,而是将重复的元素移到容器末尾。

示例:

unique函数用法示例
// 完整的unique函数示例代码
#include <iostream>      // 包含输入输出流库
#include <vector>       // 包含vector容器
#include <algorithm>   // 包含unique和sort函数

// 打印vector元素的函数
void printVector(const std::vector<int>& v, const std::string& msg, int limit = -1) {
    std::cout << msg << ": ";
    int count = 0;
    for(int num : v) {
        std::cout << num << " ";
        count++;
        if(limit != -1 && count >= limit) {
            break;
        }
    }
    std::cout << std::endl;
}

int main() {
    // 创建一个包含重复元素的vector
    std::vector<int> numbers = {1, 2, 2, 3, 3, 3, 4, 5, 5};
    
    printVector(numbers, "原始数组");
    std::cout << "原始数组大小: " << numbers.size() << std::endl;
    
    // 注意:使用unique前必须先排序(虽然本例已经排序,但这是必要步骤)
    std::sort(numbers.begin(), numbers.end());
    
    // 使用unique去重,返回指向最后一个不重复元素之后的迭代器
    auto last = std::unique(numbers.begin(), numbers.end());
    
    // 此时容器大小并未改变,但重复元素已被移到后面
    printVector(numbers, "unique处理后(完整容器)");
    std::cout << "处理后容器大小(未变): " << numbers.size() << std::endl;
    
    // 打印去重后的有效元素
    std::cout << "去重后的有效元素: ";
    for(auto it = numbers.begin(); it != last; ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;
    
    // 真正删除重复元素(使用erase)
    numbers.erase(last, numbers.end());
    
    printVector(numbers, "删除重复元素后");
    std::cout << "删除后容器大小: " << numbers.size() << std::endl;
    
    return 0;
}

运行结果:
原始数组: 1 2 2 3 3 3 4 5 5
原始数组大小: 9
unique处理后(完整容器): 1 2 3 4 5 3 4 5 5
处理后容器大小(未变): 9
去重后的有效元素: 1 2 3 4 5
删除重复元素后: 1 2 3 4 5
删除后容器大小: 5

2. find

功能:在容器中查找指定元素,返回第一个匹配元素的迭代器;若未找到,返回尾迭代器。find函数使用线性搜索,时间复杂度为O(n)。

示例:

find函数用法示例
// 完整的find函数示例代码
#include <iostream>      // 包含输入输出流库
#include <vector>       // 包含vector容器
#include <algorithm>   // 包含find函数
#include <string>       // 包含string类

int main() {
    // 1. 在整数vector中查找
    std::vector<int> numbers = {10, 20, 30, 40, 50};
    
    int target = 30;
    auto it = std::find(numbers.begin(), numbers.end(), target);
    
    if(it != numbers.end()) {
        int index = it - numbers.begin(); // 计算索引位置
        std::cout << "找到 " << target << ",位置索引: " << index << std::endl;
    } else {
        std::cout << "未找到 " << target << std::endl;
    }
    
    // 查找不存在的元素
    target = 35;
    it = std::find(numbers.begin(), numbers.end(), target);
    if(it != numbers.end()) {
        std::cout << "找到 " << target << std::endl;
    } else {
        std::cout << "未找到 " << target << std::endl;
    }
    
    // 2. 在字符串vector中查找
    std::vector<std::string> fruits = {"apple", "banana", "cherry", "date"};
    
    std::string fruit_target = "cherry";
    auto str_it = std::find(fruits.begin(), fruits.end(), fruit_target);
    
    if(str_it != fruits.end()) {
        int index = str_it - fruits.begin();
        std::cout << "\n找到 " << fruit_target << ",位置索引: " << index << std::endl;
    } else {
        std::cout << "\n未找到 " << fruit_target << std::endl;
    }
    
    return 0;
}

运行结果:
找到 30,位置索引: 2
未找到 35

找到 cherry,位置索引: 2

3. lower_bound

功能:在已排序的容器中查找第一个大于或等于目标值的元素,返回其迭代器(二分查找,O(log n)复杂度)。注意:使用前必须确保容器已排序。

示例:

lower_bound函数用法示例
// 完整的lower_bound函数示例代码
#include <iostream>      // 包含输入输出流库
#include <vector>       // 包含vector容器
#include <algorithm>   // 包含lower_bound和sort函数

// 打印vector元素的函数
void printVector(const std::vector<int>& v, const std::string& msg) {
    std::cout << msg << ": ";
    for(int num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}

int main() {
    // 创建并初始化一个已排序的vector(lower_bound要求容器已排序)
    std::vector<int> numbers = {10, 20, 30, 40, 50, 60};
    printVector(numbers, "已排序数组");
    
    // 1. 查找存在的元素
    int target1 = 30;
    auto it1 = std::lower_bound(numbers.begin(), numbers.end(), target1);
    
    if(it1 != numbers.end()) {
        int index1 = it1 - numbers.begin();
        std::cout << "查找 " << target1 << ": 找到元素,位置索引: " << index1 
                  << ", 值: " << *it1 << std::endl;
    }
    
    // 2. 查找不存在但在范围内的元素
    int target2 = 35;
    auto it2 = std::lower_bound(numbers.begin(), numbers.end(), target2);
    
    if(it2 != numbers.end()) {
        int index2 = it2 - numbers.begin();
        std::cout << "查找 " << target2 << ": 未找到元素,第一个大于等于的元素位置索引: " << index2 
                  << ", 值: " << *it2 << std::endl;
    }
    
    // 3. 查找大于所有元素的目标
    int target3 = 70;
    auto it3 = std::lower_bound(numbers.begin(), numbers.end(), target3);
    
    if(it3 == numbers.end()) {
        std::cout << "查找 " << target3 << ": 目标大于所有元素,返回end迭代器" << std::endl;
    }
    
    // 4. 查找小于所有元素的目标
    int target4 = 5;
    auto it4 = std::lower_bound(numbers.begin(), numbers.end(), target4);
    
    if(it4 != numbers.end()) {
        int index4 = it4 - numbers.begin();
        std::cout << "查找 " << target4 << ": 第一个大于等于的元素位置索引: " << index4 
                  << ", 值: " << *it4 << std::endl;
    }
    
    return 0;
}

运行结果:
已排序数组: 10 20 30 40 50 60
查找 30: 找到元素,位置索引: 2, 值: 30
查找 35: 未找到元素,第一个大于等于的元素位置索引: 3, 值: 40
查找 70: 目标大于所有元素,返回end迭代器
查找 5: 第一个大于等于的元素位置索引: 0, 值: 10

4. upper_bound

功能:在已排序的容器中查找第一个大于目标值的元素,返回其迭代器(二分查找,O(log n)复杂度)。与lower_bound的区别在于,upper_bound返回的是严格大于目标值的第一个元素。

示例:

upper_bound函数用法示例
// 完整的upper_bound函数示例代码
#include <iostream>      // 包含输入输出流库
#include <vector>       // 包含vector容器
#include <algorithm>   // 包含upper_bound和sort函数

// 打印vector元素的函数
void printVector(const std::vector<int>& v, const std::string& msg) {
    std::cout << msg << ": ";
    for(int num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}

int main() {
    // 创建并初始化一个已排序的vector(upper_bound要求容器已排序)
    std::vector<int> numbers = {10, 20, 30, 30, 40, 50};
    printVector(numbers, "已排序数组(包含重复元素)");
    
    // 1. 查找存在的元素
    int target1 = 30;
    auto it1 = std::upper_bound(numbers.begin(), numbers.end(), target1);
    
    if(it1 != numbers.end()) {
        int index1 = it1 - numbers.begin();
        std::cout << "查找 " << target1 << ": 第一个大于目标的元素位置索引: " << index1 
                  << ", 值: " << *it1 << std::endl;
    }
    
    // 2. 计算等于目标值的元素数量
    auto lower = std::lower_bound(numbers.begin(), numbers.end(), target1);
    auto upper = std::upper_bound(numbers.begin(), numbers.end(), target1);
    int count = upper - lower;
    std::cout << "值为 " << target1 << " 的元素数量: " << count << std::endl;
    
    // 3. 查找不存在但在范围内的元素
    int target2 = 25;
    auto it2 = std::upper_bound(numbers.begin(), numbers.end(), target2);
    
    if(it2 != numbers.end()) {
        int index2 = it2 - numbers.begin();
        std::cout << "查找 " << target2 << ": 第一个大于目标的元素位置索引: " << index2 
                  << ", 值: " << *it2 << std::endl;
    }
    
    // 4. 查找大于所有元素的目标
    int target3 = 60;
    auto it3 = std::upper_bound(numbers.begin(), numbers.end(), target3);
    
    if(it3 == numbers.end()) {
        std::cout << "查找 " << target3 << ": 目标大于等于所有元素,返回end迭代器" << std::endl;
    }
    
    return 0;
}

运行结果:
已排序数组(包含重复元素): 10 20 30 30 40 50
查找 30: 第一个大于目标的元素位置索引: 4, 值: 40
值为 30 的元素数量: 2
查找 25: 第一个大于目标的元素位置索引: 2, 值: 30
查找 60: 目标大于等于所有元素,返回end迭代器

区间操作

1. copy

功能:将一个容器的元素复制到另一个容器。copy函数将[first, last)范围内的元素复制到以result开始的目标范围,返回指向最后一个复制元素的下一个位置的迭代器。

示例:

copy函数用法示例
// 完整的copy函数示例代码
#include <iostream>      // 包含输入输出流库
#include <vector>       // 包含vector容器
#include <algorithm>   // 包含copy函数
#include <iterator>    // 包含输出迭代器

// 打印vector元素的函数
template<typename T>
void printVector(const std::vector<T>& v, const std::string& msg) {
    std::cout << msg << ": ";
    for(const T& elem : v) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;
}

int main() {
    // 1. 基本用法:复制整个容器
    std::vector<int> source = {1, 2, 3, 4, 5};
    std::vector<int> dest1(source.size()); // 目标容器需要预先分配足够空间
    
    std::copy(source.begin(), source.end(), dest1.begin());
    
    printVector(source, "源容器");
    printVector(dest1, "复制后的目标容器");
    
    // 2. 复制部分元素
    std::vector<int> dest2;
    // 使用back_inserter自动插入元素,无需预先分配空间
    std::copy(source.begin() + 1, source.begin() + 4, std::back_inserter(dest2));
    
    printVector(dest2, "\n复制部分元素后的容器(元素2,3,4)");
    
    // 3. 复制到标准输出(使用ostream_iterator)
    std::cout << "\n直接复制到标准输出: ";
    std::copy(source.begin(), source.end(), 
              std::ostream_iterator<int>(std::cout, " "));
    std::cout << std::endl;
    
    // 4. 复制不同类型的容器(如数组到vector)
    int arr[] = {10, 20, 30, 40};
    std::vector<int> dest3;
    
    std::copy(std::begin(arr), std::end(arr), std::back_inserter(dest3));
    printVector(dest3, "\n从数组复制到vector");
    
    return 0;
}

运行结果:
源容器: 1 2 3 4 5
复制后的目标容器: 1 2 3 4 5

复制部分元素后的容器(元素2,3,4): 2 3 4

直接复制到标准输出: 1 2 3 4 5

从数组复制到vector: 10 20 30 40

2. fill

功能:将容器中指定范围内的元素设置为给定的值。fill函数可以快速初始化容器或修改容器中某一区间的所有元素为相同的值。

示例:

fill函数用法示例
// 完整的fill函数示例代码
#include <iostream>      // 包含输入输出流库
#include <vector>       // 包含vector容器
#include <algorithm>   // 包含fill函数

// 打印vector元素的函数
void printVector(const std::vector<int>& v, const std::string& msg) {
    std::cout << msg << ": ";
    for(int num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}

int main() {
    // 1. 初始化容器并填充值
    std::vector<int> numbers(5); // 创建一个包含5个元素的vector
    printVector(numbers, "初始容器(未初始化)");
    
    std::fill(numbers.begin(), numbers.end(), 0); // 填充0
    printVector(numbers, "填充0后");
    
    // 2. 填充部分元素
    std::fill(numbers.begin() + 1, numbers.begin() + 4, 9); // 填充索引1-3为9
    printVector(numbers, "部分填充9后");
    
    // 3. 与resize结合使用
    std::vector<int> largeVector;
    largeVector.resize(10); // 调整大小为10
    std::fill(largeVector.begin(), largeVector.end(), 5); // 填充5
    printVector(largeVector, "\n调整大小并填充5后");
    
    // 4. 填充字符数组
    char str[10];
    std::fill(str, str + 9, '*'); // 填充前9个字符为'*'
    str[9] = '\0'; // 添加字符串结束符
    std::cout << "\n填充后的字符数组: " << str << std::endl;
    
    return 0;
}

运行结果:
初始容器(未初始化): 0 0 0 0 0 (注:实际可能是随机值,取决于编译器)
填充0后: 0 0 0 0 0
部分填充9后: 0 9 9 9 0

调整大小并填充5后: 5 5 5 5 5 5 5 5 5 5

填充后的字符数组: *********

3. transform

功能:对容器中的元素应用一个函数,并将结果存储到另一个容器中。transform可以实现元素的转换、映射等操作,是函数式编程的重要工具。

示例:

transform函数用法示例
// 完整的transform函数示例代码
#include <iostream>      // 包含输入输出流库
#include <vector>       // 包含vector容器
#include <algorithm>   // 包含transform函数
#include <cmath>        // 包含数学函数
#include <string>       // 包含string类

// 打印vector元素的函数
template<typename T>
void printVector(const std::vector<T>& v, const std::string& msg) {
    std::cout << msg << ": ";
    for(const T& elem : v) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;
}

// 1. 一元函数:计算平方
int square(int x) {
    return x * x;
}

// 2. 二元函数:计算两数之和
int sum(int a, int b) {
    return a + b;
}

int main() {
    // 示例1:使用一元函数(计算平方)
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    std::vector<int> squares(numbers.size());
    
    // 将square函数应用到numbers的每个元素,结果存入squares
    std::transform(numbers.begin(), numbers.end(), 
                     squares.begin(), square);
    
    printVector(numbers, "原始数字");
    printVector(squares, "数字的平方");
    
    // 示例2:使用lambda表达式(计算平方根)
    std::vector<double> roots(numbers.size());
    
    std::transform(numbers.begin(), numbers.end(),
                     roots.begin(),
                     [](int x) { return sqrt(double(x)); });
    
    printVector(roots, "数字的平方根");
    
    // 示例3:使用二元函数(两个容器对应元素相加)
    std::vector<int> a = {10, 20, 30};
    std::vector<int> b = {5, 8, 12};
    std::vector<int> c(a.size());
    
    std::transform(a.begin(), a.end(),
                     b.begin(),
                     c.begin(),
                     sum);
    
    printVector(a, "\n容器a");
    printVector(b, "容器b");
    printVector(c, "a + b 的结果");
    
    // 示例4:字符串转换(转为大写)
    std::string str = "hello, world!";
    std::transform(str.begin(), str.end(),
                     str.begin(),
                     [](char c) { return toupper(c); });
    
    std::cout << "\n转换为大写的字符串: " << str << std::endl;
    
    return 0;
}

运行结果:
原始数字: 1 2 3 4 5
数字的平方: 1 4 9 16 25
数字的平方根: 1 1.41421 1.73205 2 2.23607

容器a: 10 20 30
容器b: 5 8 12
a + b 的结果: 15 28 42

转换为大写的字符串: HELLO, WORLD!

最值与比较

1. max_element 和 min_element

功能:查找容器中的最大值和最小值元素,返回对应的迭代器。这两个函数使用线性搜索,时间复杂度为O(n)。

示例:

max_element和min_element函数用法示例
// 完整的max_element和min_element函数示例代码
#include <iostream>      // 包含输入输出流库
#include <vector>       // 包含vector容器
#include <algorithm>   // 包含max_element和min_element函数
#include <string>       // 包含string类

// 打印vector元素的函数
template<typename T>
void printVector(const std::vector<T>& v, const std::string& msg) {
    std::cout << msg << ": ";
    for(const T& elem : v) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;
}

// 自定义比较函数:比较字符串长度
bool compareStringLength(const std::string& a, const std::string& b) {
    return a.length() < b.length();
}

int main() {
    // 示例1:查找整数容器中的最大最小值
    std::vector<int> numbers = {5, 2, 9, 1, 5, 6};
    printVector(numbers, "整数容器");
    
    // 查找最大值
    auto max_it = std::max_element(numbers.begin(), numbers.end());
    std::cout << "最大值: " << *max_it 
              << ", 位置索引: " << (max_it - numbers.begin()) << std::endl;
    
    // 查找最小值
    auto min_it = std::min_element(numbers.begin(), numbers.end());
    std::cout << "最小值: " << *min_it 
              << ", 位置索引: " << (min_it - numbers.begin()) << std::endl;
    
    // 示例2:查找部分范围内的最大最小值
    auto max_part_it = std::max_element(numbers.begin() + 1, numbers.begin() + 5);
    std::cout << "\n部分范围(索引1-4)的最大值: " << *max_part_it << std::endl;
    
    // 示例3:使用自定义比较函数查找字符串容器
    std::vector<std::string> words = {"apple", "banana", "cherry", "date"};
    printVector(words, "\n字符串容器");
    
    // 查找最长的字符串(使用自定义比较函数)
    auto longest_it = std::max_element(words.begin(), words.end(), compareStringLength);
    std::cout << "最长的字符串: " << *longest_it 
              << ", 长度: " << longest_it->length() << std::endl;
    
    // 查找最短的字符串(使用lambda表达式)
    auto shortest_it = std::min_element(words.begin(), words.end(),
                            [](const std::string& a, const std::string& b) {
                                return a.length() < b.length();
                            });
    std::cout << "最短的字符串: " << *shortest_it 
              << ", 长度: " << shortest_it->length() << std::endl;
    
    return 0;
}

运行结果:
整数容器: 5 2 9 1 5 6
最大值: 9, 位置索引: 2
最小值: 1, 位置索引: 3

部分范围(索引1-4)的最大值: 9

字符串容器: apple banana cherry date
最长的字符串: banana, 长度: 6
最短的字符串: date, 长度: 4

2. equal

功能:比较两个容器的元素是否相等。equal函数检查[first1, last1)范围内的元素是否与从first2开始的相同数量的元素相等,返回布尔值。

示例:

equal函数用法示例
vectorvector v1 = {1,2,3}, v2 = {1,2,4};
bool is_equal = equal(v1.begin(), v1.end(), v2.begin());
// false