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/C%2B%2B/Algorytmy_w_STL/Operacje_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