Как отсортировать вектор объектов C++

128
13 октября 2018, 19:20

Есть класс Date (день, месяц, год) И есть вектор этих объектов Надо с помощью обычной сортировки sort() отсортировать по году и по названию месяца.

Подскажите как сделать сортировку

Вот код самого вектора и класса

class Date {
    int year;
    string month;
    int day;
public:
    void set_year(int y) {
        year = y;
    }
    void set_month(string m) {
        month = m;
    }
    void set_day(int d) {
        day = d;
    }
    int get_year() {
        return year;
    }
    string get_month() {
        return month;
    }
    int get_day() {
        return day;
    }
    void showObj() {
        cout << "Day: " << get_day() << endl;
        cout << "Month: " << get_month() << endl;
        cout << "Year: " << get_year() << endl;
    }

};

vector <string> months = { "Январь", "Февраль","Март","Апрель","Май", "Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь" };
    vector <Date> ivector;
    Date day;
    for (size_t i = 0; i < 10; i++){
        day.set_month(months[rand() % months.size()]);
        day.set_day(1 + rand() % 30);
        day.set_year(1980 + rand() % 38);
        ivector.push_back(day);
    }
    cout << endl << endl;
    for (size_t i = 0; i < ivector.size(); i++) {
        ivector[i].showObj();
        cout << endl;
    }
Answer 1

В такой постановке задачи (месяц хранится как строка с его именем) вам понадобится какой-то способ перевода названия месяца в его порядковый номер. Например, ваша таблица months должна быть доступна глобально.

Тогда можно реализовать такой оператор сравнения

const std::vector<std::string> months = 
{ 
  "Январь", "Февраль", "Март", "Апрель", "Май", "Июнь",
  "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь" 
};
...
class Date {
  ...
  friend bool operator <(const Date &lhs, const Date &rhs)
  {
    if (lhs.year != rhs.year)
      return lhs.year < rhs.year;
    if (lhs.month != rhs.month)
    {
      auto it_lhs = std::find(months.begin(), months.end(), lhs.month);
      auto it_rhs = std::find(months.begin(), months.end(), rhs.month);
      return it_lhs < it_rhs;
    }
    return lhs.day < rhs.day;
  }
  ...
};

После этого

std::sort(ivector.begin(), ivector.end());

отсортирует ваш вектор по дате.

P.S. В реализации оператора отсутствует обработка ситуации, когда название месяца вдруг не нашлось в таблице. Текущая реализация полагает, что все "неправильные" месяцы являются тринадцатым месяцем. Это уже вам решать, как ее лучше обработать или оставить все как есть.

Answer 2

Векторы с пользовательским типом можно отсортировать через лямбда-предикат тем же методом sort

В вашем случае можно унаследовать класс std::string и создать поле priority.

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
class Employee {
    public: 
        Employee(std::string name, std::string country, int age)
        {
            this->name = name;
            this->age = age;
        }
        std::string getInfo()
        {
            return name + " " + country + " " + std::to_string(age);
        }
        std::string country;
        std::string name;
        int age;
};
int main()
{
    std::vector<Employee> employees = {
        Employee("Carl", "USA", 24), 
        Employee("Kirito", "Japan", 18), 
        Employee("Andrew", "Russia", 34), 
        Employee("Cheng", "China", 26), 
        Employee("Rengi", "Japan", 16)
    };
    std::cout << "Unsorted" << std::endl << std::endl;
    for (auto element : employees)
    {
        std::cout << element.getInfo() << std::endl;
    }
    //Sorting
    std::sort(employees.begin(), employees.end(), [](Employee &e1, Employee &e2){
         return e1.age < e2.age;
    });
    std::cout << std::endl;
    std::cout << "Sorted" << std::endl << std::endl;
    for (auto element : employees)
    {
        std::cout << element.getInfo() << std::endl;
    }
}
READ ALSO
Как собрать все objectName в ui_widgetname.h?

Как собрать все objectName в ui_widgetname.h?

Вопрос по Qt/ Создал много виджетов которые загружаются на одной главной формеМне нужно собрать все ключи чтобы менять объектам текст(лэйбл)

156
Указатели с C++ [дубликат]

Указатели с C++ [дубликат]

На данный вопрос уже ответили:

164
Типы С++ &amp;&amp; Литература об оптимизации С++

Типы С++ && Литература об оптимизации С++

Во-первых, можно ли как-нибудь узнать полное имя типа в с++? Я обычно использую typeid(

173
Как сделать долгое нажатие кнопки в android studio

Как сделать долгое нажатие кнопки в android studio

Всем приветТакая задача: нужно реализовать долгое нажатие кнопки

200