sortowanie wg imion, nazwisk, etc.

0

Mam problem z sortowaniem.

Chcę żeby dane z kontenera można było posortować wg nazwisk, nr indeksu, etc., a następnie wyprowadzić na ekran.

Myślę, że można do tego użyć algorytmu opisanego pod poniższym adresem.

http://pl.wikibooks.org/wiki/[...]cje_sortuj%C4%85ce#sort.28.29

Problem w tym, że nie wiem jak to przerobić, żeby pracowało, wg wcześniej wspomnianych założeń, tzn. sortowało dane w kontenerze, który zawiera dane o typie zadeklarowanym w klasie. Proszę o pomoc.

Mogę wstawić kod, o ile komuś będzie się chciało patrzeć na 400 linijek. Bo piszę prostą bazę danych.

1

Święta!

Oczywiście można napisać 3/4 mniej kodu, żeby osiągnąć to, co chcesz, ale ja chciałem, żeby ładnie się z tego korzystało, tj. .ById(Descending).ByAge().ByLastName().Sort();.

#include <iostream>

#include "Student.h"
#include "StudentCollection.h"

int main(int argc, char *argv[])
{
    StudentCollection sc;
    sc.push_back(Student(1, "imie", "nazwisko", 10));
    sc.push_back(Student(2, "imie", "nazwisko", 9));
    sc.push_back(Student(2, "imie", "costam", 11));
    sc.push_back(Student(2, "imie", "jakistam", 11));
    sc.push_back(Student(2, "wqe", "rewqe", 55));
    sc.push_back(Student(1, "costam", "innego", 9));

    sc.ById(Descending).ByAge().ByLastName().Sort();

    for(std::list<Student>::iterator it = sc.begin(); it != sc.end(); it++)
    {
        std::cout << it->Id << ": " << it->FirstName.c_str() << " " << it->LastName.c_str() <<
            " (" << it->Age << ")\n";
    }

    return 0;
}

Student.h

#pragma once

#include <iostream>

struct Student
{
    int Id;
    std::string FirstName;
    std::string LastName;
    int Age;

    Student(int id, std::string firstName, std::string lastName, int age) :
    Id(id), FirstName(firstName), LastName(lastName), Age(age) { }
};

StudentCollection.h

#pragma once

#include <list>
#include <vector>
#include "Student.h"

enum Field
{
    Id, FirstName, LastName, Age
};

enum Order
{
    Ascending, Descending
};

struct Sorting
{
    Field Field;
    Order Order;

    Sorting(::Field field, ::Order order) : Field(field), Order(order) { }
};

class StudentCollection : public std::list<Student>
{
private:
    std::vector<Sorting> _sortings;
public:
    StudentCollection(void);
    ~StudentCollection(void);

    bool operator() (const Student& first, const Student& second) const;

    StudentCollection& ById(Order order = Ascending);
    StudentCollection& ByFirstName(Order order = Ascending);
    StudentCollection& ByLastName(Order order = Ascending);
    StudentCollection& ByAge(Order order = Ascending);

    StudentCollection& Sort();
};

StudentCollection.cpp

#include "StudentCollection.h"

StudentCollection::StudentCollection(void)
{

}

StudentCollection::~StudentCollection(void)
{

}

StudentCollection& StudentCollection::ById(Order order)
{
    _sortings.push_back(Sorting(Id, order));
    return *this;
}

StudentCollection& StudentCollection::ByFirstName(Order order)
{
    _sortings.push_back(Sorting(FirstName, order));
    return *this;
}

StudentCollection& StudentCollection::ByLastName(Order order)
{
    _sortings.push_back(Sorting(LastName, order));
    return *this;
}

StudentCollection& StudentCollection::ByAge(Order order)
{
    _sortings.push_back(Sorting(Age, order));
    return *this;
}

StudentCollection& StudentCollection::Sort()
{
    if(_sortings.size() > 0)
        sort(*this);

    _sortings.clear();
    return *this;
}

bool StudentCollection::operator() (const Student& first, const Student& second) const
{
    for(std::vector<Sorting>::const_iterator it = _sortings.begin(); it != _sortings.end(); it++)
    {
        switch(it->Field)
        {
        case Id:
            if(first.Id == second.Id) continue;
            return it->Order == Ascending ? first.Id < second.Id : first.Id > second.Id;

            break;
        case FirstName:
            if(first.FirstName.compare(second.FirstName) == 0) continue;

            return it->Order == Ascending ? first.FirstName.compare(second.FirstName) < 0 :
                first.FirstName.compare(second.FirstName) > 0;

            break;
        case LastName:
            if(first.LastName.compare(second.LastName) == 0) continue;

            return it->Order == Ascending ? first.LastName.compare(second.LastName) < 0 :
                first.LastName.compare(second.LastName) > 0;

            break;
        case Age:
            if(first.Age == second.Age) continue;
            return it->Order == Ascending ? first.Age < second.Age : first.Age > second.Age;

            break;
        }
    }
}
2

Nie no, aż tak atmosfera świąteczna mi się nie udziela, żeby babrać w takim kodzie.

Wbrew pozorom (!) dzielenie projektu na pliki to jedna z najbardziej podstawowych rzeczy, dzięki którym kod jest czytelniejszy.

0

Nie da się jakoś prościej tego ugryźć, z użyciem sort(studenci.begin(), studenci.end(), funkcja_porownujaca) ? Właśnie próbuję stworzyć tą funkcję porównującą.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0