C++之结构体数组和std::vector容器结合使用的排序/均值/方差

简介: C++之结构体数组和std::vector容器结合使用的排序/均值/方差

1、排序


最近有个项目需要使用C++ STL的vector容器,然后做一个排序操作。STL很强大,有它自己的排序方法。


std::sort(数组起始指针,数组尾指针,排序规则);


举例如下:

//参考文献,sort对结构体排序
//排序方法,sort(数组起始指针,数组尾指针,排序规则);
//数组起始指针,数组尾指针是左闭右开;
//排序规则可以省略,也可以自己写;
//https://blog.csdn.net/qq_40828914/article/details/80670151
#include <QCoreApplication>
#include <algorithm>
#include <iostream>
#include <string>
//结构体排序方法1
//按姓名从小到大排序,姓名一样,按年龄从小到大排序
struct student1
{
    std::string name; //姓名
    int age;          //年龄
};
bool compare(const student1 &s1, const student1 &s2)
{
    //自己定义的排序规则
    if (s1.name == s2.name)
    {
        return s1.age < s2.age;
    }
    else
    {
        return s1.name < s2.name;
    }
}
//结构体排序方法2
//按姓名从小到大排序,姓名一样,按年龄从小到大排序
struct student2
{
    std::string name; //姓名
    int age;          //年龄
    bool operator<(const student2 &s2) const
    {
        //符号重载
        if (name == s2.name)
        {
            return age < s2.age;
        }
        else
        {
            return name < s2.name;
        }
    }
};
int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    //普通数组排序
    int a[] = {9, 2, 4, 5, 10, 7, 30};
    std::sort(a, a + 7);                   //省略掉排序规则的形式,默认从小到大
    std::sort(a, a + 7, std::less<int>()); //用c++自身的排序规则,从小到大
    for (int i = 0; i < 7; i++)
    {
        std::cout << a[i] << " ";
    }
    std::cout << std::endl;
    std::sort(a, a + 7, std::greater<int>()); //用c++自身的排序规则,从大到小
    for (int i = 0; i < 7; i++)
    {
        std::cout << a[i] << " ";
    }
    std::cout << std::endl;
    //结构体数组排序方法1
    student1 s1[100];
    s1[0].name = "zhangsan";
    s1[0].age = 18;
    s1[1].name = "zhangsan";
    s1[1].age = 19;
    s1[2].name = "lisi";
    s1[2].age = 20;
    std::sort(s1, s1 + 3, compare); //左闭右开,所以是对s[0]到s[2]排序
    for (int i = 0; i < 3; i++)
    {
        std::cout << s1[i].name << " " << s1[i].age << std::endl;
    }
    //结构体数组排序方法2:符合重载
    student2 s2[100];
    s2[0].name = "zhangsan";
    s2[0].age = 18;
    s2[1].name = "zhangsan";
    s2[1].age = 19;
    s2[2].name = "lisi";
    s2[2].age = 20;
    std::sort(s2, s2 + 3); //左闭右开,所以是对s[0]到s[2]排序
    for (int i = 0; i < 3; i++)
    {
        std::cout << s2[i].name << " " << s2[i].age << std::endl;
    }
    //针对std::vector容器排序
    std::vector<student1> vtDemo;
    student1 s3;
    s3.name = "hello";
    s3.age = 12;
    vtDemo.emplace_back(s3);
    s3.name = "world";
    s3.age = 7;
    vtDemo.emplace_back(s3);
    s3.name = "hello";
    s3.age = 11;
    vtDemo.emplace_back(s3);
    std::sort(vtDemo.begin(), vtDemo.end(), compare);
    for (size_t i = 0; i < vtDemo.size(); i++)
    {
        std::cout << vtDemo[i].name << " " << vtDemo[i].age << std::endl;
    }
    return app.exec();
}


2、均值与方差


先看基本数据结构

#include <numeric>
double sum = std::accumulate(std::begin(resultSet), std::end(resultSet), 0.0);  
double mean =  sum / resultSet.size(); //均值  
double accum  = 0.0;  
std::for_each (std::begin(resultSet), std::end(resultSet), [&](const double d) {  
    accum  += (d-mean)*(d-mean);  
});  
double stdev = sqrt(accum/(resultSet.size()-1)); //方差


再看自定义数据结构


struct Grade
{
    string name;
    int grade;
};
std::vector<Grade> subject = {
    {"English", 80},
    {"Biology", 70},
    {"History", 90}};
int test()
{
    //方法1,accumulate
    int sum1 = std::accumulate(subject.begin(), subject.end(), 0,
                               [](int a, Grade b) -> int {
                                   return a + b.grade;
                               });
    cout << "sum1 = " << sum1 << endl;
    //方法2,for_each
    int sum2 = 0;
    for_each(subject.begin(), subject.end(), [&sum2](Grade b) -> void {
        sum2 += b.grade;
    }); // sum2作为引用形参传递
    cout << "sum2 = " << sum2 << endl;
    system("pause");
    return 0;
}


相关文章
|
5月前
|
C++
基本二叉树与排序二叉树(C++源码)
本程序实现二叉树基本操作与二叉排序树应用。支持前序建树、四种遍历、求深度、叶子数、第K层节点数及查找功能;并实现二叉排序树的构建、中序输出与查找比较次数统计,分析不同插入顺序对树形态和查找效率的影响。
|
搜索推荐 编译器 C语言
【C++核心】特殊的元素集合-数组与字符串详解
这篇文章详细讲解了C++中数组和字符串的基本概念、操作和应用,包括一维数组、二维数组的定义和使用,以及C风格字符串和C++字符串类的对比。
400 5
|
存储 人工智能 算法
【C++数据结构——内排序】二路归并排序(头歌实践教学平台习题)【合集】
本关任务是实现二路归并算法,即将两个有序数组合并为一个有序数组。主要内容包括: - **任务描述**:实现二路归并算法。 - **相关知识**: - 二路归并算法的基本概念。 - 算法步骤:通过比较两个有序数组的元素,依次将较小的元素放入新数组中。 - 代码示例(以 C++ 为例)。 - 时间复杂度为 O(m+n),空间复杂度为 O(m+n)。 - **测试说明**:平台会对你编写的代码进行测试,提供输入和输出示例。 - **通关代码**:提供了完整的 C++ 实现代码。 - **测试结果**:展示代码运行后的排序结果。 开始你的任务吧,祝你成功!
419 10
|
搜索推荐 算法 数据处理
【C++数据结构——内排序】希尔排序(头歌实践教学平台习题)【合集】
本文介绍了希尔排序算法的实现及相关知识。主要内容包括: - **任务描述**:实现希尔排序算法。 - **相关知识**: - 排序算法基础概念,如稳定性。 - 插入排序的基本思想和步骤。 - 间隔序列(增量序列)的概念及其在希尔排序中的应用。 - 算法的时间复杂度和空间复杂度分析。 - 代码实现技巧,如循环嵌套和索引计算。 - **测试说明**:提供了测试输入和输出示例,帮助验证代码正确性。 - **我的通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了代码运行的测试结果。 通过这些内容,读者可以全面了解希尔排序的原理和实现方法。
296 10
|
搜索推荐 C++
【C++数据结构——内排序】快速排序(头歌实践教学平台习题)【合集】
快速排序是一种高效的排序算法,基于分治策略。它的主要思想是通过选择一个基准元素(pivot),将数组划分成两部分。一部分的元素都小于等于基准元素,另一部分的元素都大于等于基准元素。然后对这两部分分别进行排序,最终使整个数组有序。(第一行是元素个数,第二行是待排序的原始关键字数据。本关任务:实现快速排序算法。开始你的任务吧,祝你成功!
333 7
|
存储 算法 搜索推荐
【C++面向对象——群体类和群体数据的组织】实现含排序功能的数组类(头歌实践教学平台习题)【合集】
1. **相关排序和查找算法的原理**:介绍直接插入排序、直接选择排序、冒泡排序和顺序查找的基本原理及其实现代码。 2. **C++ 类与成员函数的定义**:讲解如何定义`Array`类,包括类的声明和实现,以及成员函数的定义与调用。 3. **数组作为类的成员变量的处理**:探讨内存管理和正确访问数组元素的方法,确保在类中正确使用动态分配的数组。 4. **函数参数传递与返回值处理**:解释排序和查找函数的参数传递方式及返回值处理,确保函数功能正确实现。 通过掌握这些知识,可以顺利地将排序和查找算法封装到`Array`类中,并进行测试验证。编程要求是在右侧编辑器补充代码以实现三种排序算法
327 5
|
存储 对象存储 C++
C++ 中 std::array<int, array_size> 与 std::vector<int> 的深入对比
本文深入对比了 C++ 标准库中的 `std::array` 和 `std::vector`,从内存管理、性能、功能特性、使用场景等方面详细分析了两者的差异。`std::array` 适合固定大小的数据和高性能需求,而 `std::vector` 则提供了动态调整大小的灵活性,适用于数据量不确定或需要频繁操作的场景。选择合适的容器可以提高代码的效率和可靠性。
|
安全 C++
C++: std::once_flag 和 std::call_once
`std::once_flag` 和 `std::call_once` 是 C++11 引入的同步原语,确保某个函数在多线程环境中仅执行一次。
C++(十一)对象数组
本文介绍了C++中对象数组的使用方法及其注意事项。通过示例展示了如何定义和初始化对象数组,并解释了栈对象数组与堆对象数组在初始化时的区别。重点强调了构造器设计时应考虑无参构造器的重要性,以及在需要进一步初始化的情况下采用二段式初始化策略的应用场景。
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。