Feladat: Adott egy pályaudvar k darab vágánnyal rendelkezik. A pályaudvarra érkező vonatok napi forgalmi adatait egy szekvenciális fájlban találjuk. A fájl egy eleme tartalmazza a vonat egyedi azonosítóját, továbbá annak érkezési és indulási idejét. Ezek nem negatív egészek, az érkezési idő kisebb, mint az indulási. A fájl érkezési idő szerint monoton növekvően rendezett. A nap kezdetén a pályaudvar összes vágánya üres. Egy érkező vonat tetszőleges szabad vágányra beállhat és azt az indulási idejéig foglalja. Adjuk meg azon vonatok azonosítóit egy szekvenciális fájlban, amelyeket a pályaudvar nem tud fogadni, mert érkezésük idején nem lenne szabad vágány! Ezek a vonatok figyelmen kívül hagyandók. Megoldás A pályaudvar egy olyan típussal reprezentálható, mely mindig tudja, melyik eleme az, amelyik kimegy és az, amely pontosan k számosságú adatot tárol le. Ilyen típus a prioritási sor. Van egy kimenő és egy bemenő fájlunk, az egyik összetett típusokat olvas be, a másik az összetett típus egyik részét írja csak ki. Ezeket iteráltan kell megoldani, tehát lesz egy iterált absztrakt osztályunk is. Továbbá az összetett típust is meg kell adni. És kell egy rész, amely magát a feladatot oldja meg, elvégzi a példányosításokat és származtatásokat. Összetett típus (CTrain.hpp): struct CTrain { unsigned int trainId; unsigned int arrivalTime; unsigned int leaveTime; friend std::ifstream& operator>>(std::ifstream& s, CTrain& myTrain) { s >> myTrain.trainId
>> myTrain.arrivalTime >> myTrain.leaveTime; return s; } friend std::ofstream& operator<<(std::ofstream& s, const CTrain& myTrain) { s << myTrain.trainId; return s; } friend bool operator>(const CTrain& a, const CTrain&
b) { return (a.arrivalTime
> b.leaveTime); } CTrain &operator=(const CTrain &b) { this->trainId = b.trainId; this->arrivalTime
= b.arrivalTime; this->leaveTime = b.leaveTime; } }; Prioritási sor (CPriorityQue.hpp): push() egy elemet tesz a sorba pop() kiveszi az elsőbbséget élvező elemet (azt a vonatot, amely már elment) isEmpty() megadja, hogy a sor üres-e first() visszaadja az elsőbbséget élvező elem értékét template <class Item> class CPriorityQue {
private:
Item* myQue;
unsigned int size;
unsigned int max;
int act; // ő lehet
-1 is
public:
enum Exceptions {EQueIsFull, EQueIsEmpty};
CPriorityQue(unsigned int k);
~CPriorityQue();
void push(Item e);
void pop(Item &e);
bool isEmpty();
Item first(); }; Magát a megvalósítást nem írtam bele a dokumentációba, az egész az algoritmusok és adatszerkezetek alapján vektoros ábrázolással implementálódott Iterált típus (CIterated.hpp) #ifndef
CITERATED #define
CITERATED template <class Item> class CIterated {
protected:
CIterated() {}
public:
// virtual methods (abstract class)
virtual ~CIterated() {}
virtual void open() {}
virtual void close() {}
virtual void first() {
read(); }
virtual void read() {}
virtual void write(const Item& e) {}
virtual bool end() {
return true; }
virtual Item current() {
Item e; return e; } }; #endif Mivel az osztály absztrakt, így minden metódus szinte virtuális (kivéve a konstrukort), amelyeket később a származtatás során felülbírálunk, ha akarjuk. Származtatott bemenő fájl típus (CSeqInFile.hpp): template <class Item> class CSeqInFile : public CIterated<Item> {
private:
std::ifstream f;
Item data;
std::string fileName;
public:
CSeqInFile(const std::string& s) : fileName(s) { open(); }
~CSeqInFile() {
close(); }
void open() {
f.open(fileName.c_str()); }
void read() {
f >> data; }
bool end() const { return f.eof(); }
Item current() const { return
data; }
void close() {
f.close(); } }; Származtatott kimenő fájl típus (CSeqOutFile.hpp): template <class Item> class CSeqOutFile : public CIterated<Item> { private: std::ofstream f; std::string fileName; public: CSeqOutFile(const std::string&
s) : fileName(s) {
open(); } ~CSeqOutFile() {
close(); } void open() {
f.open(fileName.c_str()); } void write(const Item&
data) {
f << data << endl;
} void close() {
f.close(); } }; Megoldó rész (CStation.hpp): #ifndef
CSTATION #define
CSTATION #include
"CSeqInFile.hpp" #include
"CSeqOutFile.hpp" #include
"CPriorityQue.hpp" #include
"CTrain.hpp" class CStation {
private:
CPriorityQue<CTrain>* station;
CSeqInFile<CTrain>* input;
CSeqOutFile<unsigned int>* output;
public:
CStation(const std::string InFileName, const std::string
OutFileName, unsigned int NumberOfPlatforms)
{
station = new CPriorityQue<CTrain> (NumberOfPlatforms);
input =
new CSeqInFile<CTrain> (InFileName);
output =
new CSeqOutFile<unsigned int> (OutFileName);
} // end of constructor Fent létrehozzuk a példányokat típusuk szerint. ~CStation()
{
delete
station;
delete
input;
delete
output;
} // end of destructor
void Do()
{ CTrain trainRead; CTrain dummy; input->first(); trainRead =
input->current(); while ((!station->isEmpty())
&& (trainRead > station->first())) { station->pop(dummy); if (station->isEmpty()) continue; } try { station->push(trainRead); } catch (...) { output->write(trainRead.trainId); } while(!input->end()) { input->read(); trainRead = input->current(); while ((!station->isEmpty())
&& (trainRead > station->first())) { station->pop(dummy); if (station->isEmpty())
continue; } try { station->push(trainRead); } catch (...) { output->write(trainRead.trainId); }
}
} // end of main procedure
do }; #endif A program olvassa a fájlt
(előolvasás fontos!) és ha az aktuális vonat érkezési ideje nagyobb
mint a bentlévő vonatok valamelyikének az indulási
időpontja, úgy azokat a vonatokat kiveszi a sorból, majd utána elhelyezi a
beolvasottat. Főprogram (main.cpp): #include
<stdlib.h> #include
<iostream> #include
"CStation.hpp" using namespace std; int main(int argc,
char *argv[]) {
CStation* myStation;
myStation = new CStation("vonat.txt",
"rossz.txt", 10);
myStation->Do();
char dummy;
cout << " Gombnyomas es <ENTER> a vege... ";
cin
>> dummy;
return 0; } |