• Nem Talált Eredményt

ORMQAAI 2009.10.09. II.OAF beadandó dokumentáció

N/A
N/A
Protected

Academic year: 2024

Ossza meg "ORMQAAI 2009.10.09. II.OAF beadandó dokumentáció"

Copied!
8
0
0

Teljes szövegt

(1)

Feladat

5. Készítsen egy sor típust! Alkalmazzon osztályt! A sorokat kétirányú fejelemes ciklikus láncolt

listával ábrázolja! Implementálja a szokásos műveleteket, és egy összefűző műveletet is, ami az első sorhoz sorban hozzáfűzi a második sor elemeit! (A második sor végül legyen üres!) Egészítse ki az osztályt a kényelmes és biztonságos használat érdekében megfelelő metódusokkal (sorbeolvasó operátor>>, sorkiíró operátor<<), alkalmazzon kivételkezelést, és bontsa modulokra a

programját! A teszt környezet hívja meg azt a műveletet is, amely kiszámítja két sor összefűzését! Az összefűzés és a többi operáció műveletigénye is Ơ(1), kivéve a sorbeolvasó és sorkiíró

operátorokat.

Sor típus

Típusérték-halmaz

- elemek sorozata

- végére tudunk csak betenni

- elejéről tudunk csak kivenni, illetve lekérdezni

Típus-műveletek

(Q,E)

Empty: → Q Üres sor létrehozása IsEmpty: Q → L Lekérdezés, üres-e a sor

In: Q x E → Q Sorba új elem berakása (utolsó helyre) Out: Q → Q x E Sorból elem kivétele (első)

First: Q → E Sor első elemének lekérdezése

Link: Q x Q → Q Kér sor összefűzése (a második sor törlésével)

Reprezentáció

Láncolt adatszerkezettel.

Helyett:

Kétirányú, fejelemes ciklikus lista

(2)

Implementáció

Kétirányú, fejelemes ciklikus listán könnyedén elérhető mind az első, mind pedig az utolsó elem, így az implementálás közben igen könnyű a műveletek kezelése, nincs szükség többnyire segédpointerek használatára.

Fejelem: Item* Head

Az utolsó elem: Head->prev Első elem: Head->next

Üres lista esetén csak a fejelem van meg: Head->prev=Head->next = NULL

Elem hozzávétele: A sor végére beláncolunk egy új elemet, melynek pointereit az eddigi utolsó elemmel illetve a fejelemmel kölcsönös összeköttetésbe hozzuk.

Elem kivétele: Az első elemre pointert állítunk, majd ezt az elemet megkerülve folytonossá

alakítjuk a listát, végül a segédpointerrel visszaadjuk az értékét majd töröljük a felesleges elemet a memóriából.

Összefűzés: Ki kell küszöbölni a második sor fejelemét, és össze kell kötni az utána következő valós elemmel a sort, mintha csak egy új elemet tennék hozzá, valamint a második sor végét kölcsönös összeköttetésbe kell hozni a sor elejével.

C++ megvalósítás

Osztály

A sorok típusát egy osztály segítségével valósítjuk meg.

class Queue { … };

Melyhez felhasználásra kerül az elemek struktúrája:

struct Item { ... };

#ifndef ITEM_H_INCLUDED

#define ITEM_H_INCLUDED struct Item

{

Item* prev;

char data;

Item* next;

Item(Item* p, char d, Item* n ) {

prev = p;

data = d;

next = n;

} };

#endif

(3)

#ifndef Queue_H_INCLUDED

#define Queue_H_INCLUDED

#include <iostream>

#include "Item.h"

class Queue {

public:

Queue();

~Queue();

Queue(const Queue& s);

bool IsEmpty();

char First();

void In(char x);

char Out();

Queue& operator= (const Queue& s);

void Link(Queue &s);

friend std::ostream& operator<<(std::ostream& out, const Queue& s);

friend std::istream& operator>>(std::istream& in, Queue& s);

enum Exceptions{EMPTY_QUEUE, INPUT_END};

private:

Item* Head;

void copy(const Queue& s);

void deallocate();

};

std::ostream& operator<<(std::ostream& out, const Queue& s);

std::istream& operator>>(std::istream& in, Queue& s);

#endif

A metódusok megvalósítása a Queue.cpp forrásállományba kerül. Ennek elején helyezzük el a #include

”Queue.h” direktívát.

(4)

1. Konstruktor

Tevékenység: A konstruktor létrehoz egy üres sort, amely csak egy '0'-t tartalmazó fejelemet tárol.

Bemenő adatok: paraméter nélkül Kimenő adatok: új sor

Definíció:

Queue::Queue() {

Head = new Item(0,'0',0);

}

2. Másoló konstruktor

Tevékenység: A konstruktor létrehoz egy új sort, melynek elemeit rendre beállítja egy másik sor megfelelő elemeinek értékére.

Bemenő adatok: sor Kimenő adatok: új sor Definíció:

void Queue::copy(const Queue& s) {

Head = new Item(0,'0',0);

Item* r = Head;

for (Item *p = s.Head->next; p != Head; p = p->next) {

r->next = new Item(r,p->data,Head);

r = r->next;

}

Head->prev = r;

}

Queue::Queue(const Queue& s) {

copy(s);

}

3. Értékadás operátor

Tevékenység: Az operátor értékül adja az értékadás jobboldalán adott sort a baloldalán álló (az operátor által alapértelmezett) sornak.

Bemenő adatok: sor

Kimenő adatok: alapértelmezett sor Definíció:

void Queue::deallocate() {

if ( !IsEmpty() ) {

Item* a;

Item* n = Head->next;

while(n != Head)

(5)

{ a=n;

n=a->next;

delete a;

}

Head->next=Head->prev=0;

} }

Queue& Queue::operator= (const Queue& s) {

if (this != &s) {

deallocate();

copy(s);

}

return *this;

}

4. Destruktor

Tevékenység: Megsemmisíti a létrehozott láncolt listát, felszabadítva ezzel a helyet.

Bemenő adatok: sor Kimenő adatok: - Definíció:

Queue::~Queue() {

deallocate();

delete Head;

}

5. IsEmpty

Tevékenység: Megállapítja egy sorról, hogy üres-e.

Bemenő adatok: sor

Kimenő adatok: logikai érték Definíció:

bool Queue::IsEmpty() {

return (Head->next == 0);

} 6. First

Tevékenység: A sor első elemének lekérdezése.

Bemenő adatok: sor

Kimenő adatok: első elem értéke Definíció:

char Queue::First() {

if (IsEmpty()) throw EMPTY_QUEUE;

return Head->next->data;

(6)

}

7. In

Tevékenység: Egy elem a sorhoz csatolása, a sor végére.

Bemenő adatok: sor

Kimenő adatok: sor az új elemmel Definíció:

void Queue::In(char x) {

if ( !IsEmpty() ) {

Item* e=new Item(Head->prev, x, Head);

Head->prev->next=e;

Head->prev=e;

} else {

Item* e=new Item(Head, x, Head);

Head->prev=e;

Head->next=e;

} } 8. Out

Tevékenység: Az első elem kivétele a sorból és visszatérési értékként való átadása.

Bemenő adatok: sor

Kimenő adatok: sor (első elem nélkül) + első elem értéke Definíció:

char Queue::Out() {

if (Head->next==0) throw EMPTY_QUEUE;

Item* s;

s=Head->next;

if (s->next==Head) Head->next=0;

else Head->next=s->next;

if (s->next==Head) Head->prev=0;

else (s->next)->prev=Head;

char c;

c=s->data;

delete s;

return c;

} 9. Link

Tevékenység: Két sor összecsatlakoztatása, elemeik összefűzése, a második sor megsemmisítésével.

Bemenő adatok: sor Kimenő adatok: sor Definíció:

void Queue::Link(Queue &s) {

Head->prev->next=s.Head->next;

(7)

s.Head->next->prev=Head->prev;

s.Head->prev->next=Head;

Head->prev=s.Head->prev;

s.Head->prev = s.Head->next = 0;

}

10. Kiíró operátor

Tevékenység: Egy sor kiírása.

Bemenő adatok: sor Kimenő adatok: ostream Definíció:

std::ostream& operator<<(std::ostream& out,const Queue& s) {

if ( s.Head->next==0 ) throw Queue::EMPTY_QUEUE;

for (Item *p = s.Head->next; p != s.Head; p = p->next) {

out << p->data;

}

return out;

}

11. Beolvasó operátor

Tevékenység: Sorba való beolvasás.

Bemenő adatok: istream Kimenő adatok: sor Definíció:

std::istream& operator>>(std::istream& in, Queue& s) {

char x='0';

while (in) {

in >> x;

if (x=='q') throw Queue::INPUT_END;

s.In(x);

}

return in;

}

(8)

Tesztkörnyezet

#include <iostream>

#include "Queue.h"

using namespace std;

int main() {

Queue Sor;

cout << Sor.IsEmpty() << endl;

Sor.In('a');

cout << Sor.IsEmpty() << endl;

cout << Sor.Out() << endl;

cout << Sor.IsEmpty() << endl;;

Queue Sor2;

try {

Sor.Out();

}

catch(Queue::Exceptions i) {

if (i==Queue::EMPTY_QUEUE) cout << "Ures sor!" << endl;

} try {

cin >> Sor;

}

catch(Queue::Exceptions i) {

if (i==Queue::INPUT_END);

}

cout << Sor << endl << endl;

try {

cin >> Sor2;

}

catch(Queue::Exceptions i) {

if (i==Queue::INPUT_END);

}

cout << Sor2 << endl << endl;

Sor.Link(Sor2);

cout << Sor << endl;

try {

cout << Sor2;

}

catch(Queue::Exceptions i) {

if (i==Queue::EMPTY_QUEUE) cout << "Ures sor!" << endl;

}

return 0;

}

Hivatkozások

KAPCSOLÓDÓ DOKUMENTUMOK