天天看點

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;
}      

繼續閱讀