Čtěte prosím tuto stránku celou a pozorně.
Naprogramujte pomocí hashování "pole" řetězců, u kterého jsou jednotlivé prvky pole identifikovány řetězci. Vhodnou hashovací funkci zvolte podle vlastního uvážení.
Pole je možné používat tímto způsobem:
Uses hash.pas;
Var A : TStringArray;
Begin
A := TStringArray.Create(15);
A.Data['ahoj'] := 'nazdar';
A.Data['ahoj'] := 'cau';
Writeln(A.Data['ahoj']); { vypíše cau }
A.Destroy;
End.
Váš úkol bude implementovat objekt TStringArray, který je definovaný v souboru hash.pas následujícím způsobem:
TStringArray = Class
Private
Function GetData(Const key : String) : String;
Procedure SetData(Const key : String; s : String);
Public
Constructor Create(table_size : Integer);
Destructor Destroy; Override;
Function IsKey(key : String) : Boolean;
Procedure RemoveKey(key : String);
Property Data[Const key : String] : String Read GetData Write SetData;
End;
Soubor hash.pas včetně testovacího prostředí je v archivu zadani.tar.
Konstruktor objektu třídy TStringArray má jediný parametr - velikost hashovací tabulky. Je garantováno, že počet prvků uložených v poli v žádném testu nepřekročí hodnotu tohoto parametru.
Destruktor objektu by měl uvolnit večkerou paměť, kterou si objekt alokoval během svého života.
Metoda IsKey má vracet True v případě, že daný pro klíč existuje v poli nějaká hodnota, tj. v minulosti byl proveden příkaz A.Data[<klíč>] := 'cosi'. V opačném případě má metoda vracet False.
Metoda RemoveKey odstraní daný klíč i jeho hodnotu z pole.
Vlastnost Data představuje jen jiný způsob volání metod GetData a SetData. Příkaz A.Data[X] := Y způsobí volání metody A.SetData(X, Y), příkaz Z := A.Data[W] je ekvivalentní příkazu Z := A.GetData(W). Metody GetData a SetData však není možné používat přímo, protože jsou deklarovány v sekci Private. Jediný způsob, jak je zavolat z vnějšku objektu, je pomocí vlastnosti Data.
Pro implementaci je nutné připsat do deklarace třídy TStringArray datové položky ve kterých bude uložena hashovací tabulka a může být vhodné přidat některé vlastní (privátní) metody.
V případě, že uživatel objektu (tj. programátor, který váš objekt používá - typicky cvičící) zavolá metodu GetData, nebo RemoveKey na klíč, který v poli neexistuje, musí váš kód vygenerovat výjimku. Tuto výjimku lze vyvolat příkazem Raise EInvalidKey.Create(key). Tento příkaz vyskočí z aktuální procedury a ze všech předchozích procedur, které ještě nebyly dokončeny. Program bude pokračovat v nejbližším bloku Try Except End.
Následující příklad demonstruje chování programu v případě vyvolání výjimky:
Procedure A;
Begin
Raise EInvalidKey.Create('ahoj');
Writeln('A');
End;
Procedure B;
Begin
A;
Writeln('B');
End;
Begin
Try
B;
Writeln('OK');
Except
Writeln('Vyjimka')
End;
Writeln('Hotovo');
End.
Předchozí program vypíše pouze dvě slova: Vyjimka a Hotovo. Volání Raise způsobí skok na první příkaz za klíčovým slovem Except.
Výjimky se v programech obvykle používají pro ošetření chyb. V případě, že spustíte program z integrovaného prostředí Delphi a nastane volání Raise, zastaví debugger program na místě volání Raise. Program můžete opět spustit klávesou F9. Program v Delphi může navíc volitelně podat uživateli hlášení o výjimce pomocí dialogového okna (kód pro zobrazení okna je automaticky generován překladačem). Toto chování lze vypnout v nastavení překladače. Dialogové okno se objevuje i v případě, že program nebyl spuštěn z integrovaného prostředí. V projektu, který je umístěn v archivu zadani.tar je již toto chování vypnuto.
Testovací data jsou umístěna v souboru vstup.txt. Každému řádku odpovídá jedno volání metody objektu třídy TStringArray. Každý řádek začíná slovem, které identifikuje metodu. Za prvním slovem obvykle následují parametry metody a očekávaný (správný) výsledek volání.
Zde jsou možné případy, které se mohou ve vstupním souboru vyskytnout:
Create 5 - vytvoř pole s velikostí 5Get 'limonada' exception - zeptej se na klíč 'limonada', očekávej výjimkuSet 'rum' 'alkohol' - nastav klíč 'rum' na hodnotu 'alkohol'
Get 'rum' 'alkohol' - zjisti hodnotu klíče 'rum', očekávej hodnotu 'alkohol'
IsKey 'limonada' False - zeptej se, zda existuje klíč 'limonada', očekávej hodnotu False
IsKey 'rum' True - zeptej se, zda existuje klíč 'rum', očekávej hodnotu True
RemoveKey 'limonada' exception - odstraň klíč 'limonada', očekávej výjimku
RemoveKey 'rum' ok - odstraň klíč 'limonada', neočekávej výjimku
Destroy - zruš objekt
Run proběhne test podle souboru vstup.txt. Pokud byl program spuštěný z prostředí Delphi, bude debugger zastavovat program vždy, když dojde k výjimce. Program můžete nechat pokračovat klávesou F9. V případě, že celý test proběhne dobře, bude na konci seznamu řádek Test probehnul v poradku. V případě chybného chování implementace pole bude oznámeno číslo řádku, na kterém došlo k chybě, a další řádky vstupního souboru se již nebudou zpracovávat.
hruska (zavináč) popelka (tečka) ms (tečka) mff (tečka) cuni (tečka) cz s předmětem zprávy PGM - hash a s přiloženým souborem hash.pas..exe soubory.
Termín zadání: 3.5.2007.
Termín odevzdání: 20.5.2007.
Termín oprav: 27.5.2007.
hruska (zavináč) popelka (tečka) ms (tečka) mff (tečka) cuni (tečka) cz