Сортировка по алфавиту и по приоритету

125
10 февраля 2021, 22:50

Сделал сортировку фамилий пузырьком по алфавиту , но не удаётся сделать по приоритету (Статус). Суть моей задачи в том, что надо вводимую информацию сортировать в алфавитном порядке и приоритетом. Подскажите пожалуйста, как правильно это реализовать.

// Сортировка фамилий по алфавиту
void sorting(Student *s, int n)
{
    Student temp;
    int i, j;
    for (i = 0; i < n - 1; i++)
        for (j = n - 1; j > i; j--)
            if (s[j].lastname < s[i].lastname) {
                temp = s[j]; 
                s[j] = s[j - 1];
                s[j - 1] = temp;
            }
}
// Вводимая информация
Student* s = new Student[n];
            for (i = 0; i < n; i++)
            {
                cout << "Фамилия: ";
                cin >> s[i].lastname;
                for (;;)
                {
                    cout << "Статус: ";
                    cin >> s[i].rank;
                    if (s[i].rank == "Студент")
                    {
                        k = 3;
                        break;
                    }
                    if (s[i].rank == "группы")
                    {
                        k == 2;
                        break;
                    }
                    if (s[i].rank == "курса")
                    {
                        k = 1;
                        break;
                    }
                }
Answer 1

Изучайте, в общем.

Единственное мне было лень с указателями заморачиваться, поэтому вектора. Кучу if-ов мне тоже лень было писать, поэтому я соответствие символьного описания приоритета и его числового значения в std::map положил.

Вроде все варианты, предложенные в комментариях, указал.

#include <iostream>
#include <map>
#include <vector>
#include <functional>
#include <algorithm>
class Student{
public:
    Student():
        m_lastName{},
        m_rank{}
    {}
    Student(const Student&) = default;
    Student& operator=(const Student&) = default;
    void setLastName(const std::string& lastName){
        m_lastName = lastName;
    }
    const std::string& getLastName() const{
        return m_lastName;
    }
    /**
     * @brief setRank
     * @param rank
     * @return false если не удалось найти числовое значение
     * приоритета по его символьному описанию
     */
    bool setRank(const std::string& rank){
        if (RankToValueMap.count(rank) > 0){
            m_rank = rank;
            return true;
        }else{
            m_rank = "Unknow";
            return false;
        }
    }
    const std::string& getRank() const{
        return m_rank;
    }
    int                getRankValue() const{
        if (RankToValueMap.count(m_rank) > 0){
            return RankToValueMap.at(m_rank);
        }else{
            return 0;
        }
    }

    bool operator<(const Student& other) const{
        const int l = getRankValue();
        const int r = other.getRankValue();
        if (l < r){
            return true;
        }else if (l == r){
            return m_lastName < other.getLastName();
        }
        return false;
    }
private:
    std::string m_lastName;
    std::string m_rank;
    static const std::map<std::string, int> RankToValueMap;
};
const std::map<std::string, int> Student::RankToValueMap = {
    {"Student", 3},
    {"Group", 2},
    {"Course", 1}
};

bool predicate(const Student& l, const Student& r){
    const int lRank = l.getRankValue();
    const int rRank = r.getRankValue();
    if (lRank < rRank){
        return true;
    }else if (lRank == rRank){
        return l.getLastName() < r.getLastName();
    }
    return false;
}
///
/// \brief sorting1 сортируем вектор с помощью оператора <
/// \param s
///
void sorting1(std::vector<Student>& s)
{
    Student temp;
    std::size_t i, j;
    auto n = s.size();
    for (i = 0; i < n - 1; i++)
        for (j = n - 1; j > i; j--)
            if (s[j] < s[i])
                std::swap(s[j], s[i]);
}
///
/// \brief sorting2 сортируем вектор s с помощью функции predicate
/// \param s
///
void sorting2(std::vector<Student>& s)
{
    Student temp;
    std::size_t i, j;
    auto n = s.size();
    for (i = 0; i < n - 1; i++)
        for (j = n - 1; j > i; j--)
            if (predicate(s[j],s[i]))
                std::swap(s[j], s[i]);
}

///
/// \brief sorting3 сортируем вектор с помощью функтора (вроде это так называется)
/// Обратите внимание, тип задаётся как параметр шаблона
///
template<typename T>
void sorting3(std::vector<T>& s, std::function<bool(const T&, const T&)> func){
    Student temp;
    std::size_t i, j;
    auto n = s.size();
    for (i = 0; i < n - 1; i++)
        for (j = n - 1; j > i; j--)
            if (func(s[j],s[i]))
                std::swap(s[j], s[i]);
}

void print(const std::vector<Student>& s){
    std::cout << "Students:" << std::endl;
    for (const auto& student: s){
        std::cout << "LastName: " << student.getLastName() << "\t\trank:" << student.getRank() << std::endl;
    }
}
int main()
{
    static const std::size_t StudentsCount = 5;
    std::vector<Student> students;
    students.resize(StudentsCount); //резервируем место в векторе под всех студентов
    std::string lastName;
    std::string rank;
    //в цикле вводим
    for (std::size_t i = 0; i < StudentsCount; i++){
        std::cout << "Last name[" << i << "]:" << std::endl;
        std::cin >> lastName;
        students[i].setLastName(lastName);
        for (;;){
            std::cout << "Rank:" << std::endl;
            std::cin >> rank;
            if (!students[i].setRank(rank)){
                std::cout << "Try again ..." << std::endl;
            }else{
                break;
            }
        }
    }
    //делаем копии
    auto copy1 = students;
    auto copy2 = students;
    auto copy3 = students;
    auto copy4 = students;
    auto copy5 = students;
    auto copy6 = students;
    auto copy7 = students;
    //изголяемся с сортировками
    sorting1(copy1);
    sorting2(copy2);
    sorting3<Student>(copy3, predicate);
    // вместо описанное нами функции, используется шаблонный функтор(??) less, ожидающий тип с оператором <
    sorting3<Student>(copy4, std::less<Student>());
    // используется алгоритм сортировки из stl, ожидающий итератор на начало, на конец контейнера и компаратор для сравнения
    std::sort(copy5.begin(), copy5.end(), std::less<Student>());
    // так как в классе Student есть оператор <, функтор можно и не отдавать
    std::sort(copy6.begin(), copy6.end());

    // а ещё можно отдать тот самый predicate как функтор в стандартную сортировку.
    std::sort(copy7.begin(), copy7.end(), predicate);
    std::cout << "Sorting1:" << std::endl;
    print(copy1);
    std::cout << "Sorting2:" << std::endl;
    print(copy2);
    std::cout << "Sorting3:" << std::endl;
    print(copy3);
    std::cout << "Sorting4:" << std::endl;
    print(copy4);
    std::cout << "Sorting5:" << std::endl;
    print(copy5);
    std::cout << "Sorting6:" << std::endl;
    print(copy6);
    std::cout << "Sorting7:" << std::endl;
    print(copy7);
    std::cout << "Original:" << std::endl;
    print(students);
    return 0;
}
READ ALSO
Как найти путь src картинки по числу в data

Как найти путь src картинки по числу в data

Хочу расписать весь принцип работы просмотра изображений, который я на половину смог сделать

120
Слайдер работает по разному

Слайдер работает по разному

Использую один и тот же слайдер просто разный текст и картинки(картинки все одного размера)Но в одном примере, как видно, работает и переключает,...

92
Сериализация и десериализация полей ASP .Net MVC

Сериализация и десериализация полей ASP .Net MVC

Никогда не приходилось работать с MVC, а задание горит

116
Как загрузить несколько dll на c# .NET Core

Как загрузить несколько dll на c# .NET Core

Занимаюсь разработкой виртуальной машины на C# используяNET Core 1

97