TESTI UFFICIALI
Download
1 / 117

TESTI UFFICIALI MEYERS R.A. PASCAL Prentice Hall - PowerPoint PPT Presentation


  • 60 Views
  • Uploaded on

TESTI UFFICIALI MEYERS R.A. PASCAL Prentice Hall FIORENTINO G., LAGANA’ M.R., ROMANI F., TURINI F. PASCAL LABORATORIO DI PROGRAMMAZIONE McGraw-Hill. ESAMI FEBBRAIO 2001 - MOD. A. ESAMI MOD. A.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' TESTI UFFICIALI MEYERS R.A. PASCAL Prentice Hall' - jaimie


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

TESTI UFFICIALI

MEYERS R.A.

PASCAL

Prentice Hall

FIORENTINO G., LAGANA’ M.R., ROMANI F., TURINI F.

PASCAL

LABORATORIO DI PROGRAMMAZIONE

McGraw-Hill



ESAMI MOD. A

  • Sia dato un file di testo riguardante un insieme di soggetti di cui è fornito il cognome seguito dalla nazionalità e dalla data di nascita, giorno mese anno. Nel primo rigo sono indicati e nome e cognome dell’autore della registrazione e il numero di soggetti registrati.

  • Il file sarà perciò così composto:

  • tipo dato esempio rigo

  • stringa, integer <eoln> carlo bruni^ 76 1

  • stringa stringa^ integer integer integer <eoln> rossi italiano^22 12 1930 2

  • stringa stringa^ integer integer integer <eoln> smith inglese^ 28 9 1990 3

  • ……………………………………………………………………………………………

  • …………………………………………………………………………………………….

  • …………………………………………………………………………………………….

  • <eof>

  • Leggere il file mostrando a video i nomi ordinati per nazionalità e con la data di nascita.


PROGRAM Esercizio1(output,Client);

CONST

LunMax=40;

MassimoCli=100;

TYPE

StringaNome=STRING[LunMax];

AnagraficaRecord=RECORD

Cognome,

Nome:StringaNome;

END;

DataRecord=RECORD

Giorno,

Mese,

Anno:integer;

END;

ClienteRecord=RECORD

CognCli:StringaNome;

Nazione:StringaNome;

Nascita:DataRecord;

END;

RappresentanteRecord=RECORD

Anagrafe:AnagraficaRecord;

NumeroCli:integer;

END;

IndiceTipo=0.. MassimoCli;

CliArray=ARRAY[IndiceTipo] OF ClienteRecord;

VAR

Clienti:CliArray;

IndiceCli:IndiceTipo;

ClientiFile:text;

UnCliente: ClienteRecord;

UnRappresentante: RappresentanteRecord; 

AnagraficaRecord

Cognome

Nome

DataRecord

ClienteRecord

Giorno

CognCli

Mese

Nazione

Anno

Nascita

RappresentanteRecord

Numero

Anagrafe

BEGIN

assign(ClientiFile,'C:\Modapr\test1.TXT');

reset(ClientiFile);

LeggiRappresentante(ClientiFile, IndiceCli);

readln;

OrdinaClienti(IndiceCli,Clienti, ClientiFile);

MostraRisultati(Clienti,IndiceCli);

readln

END.


Clienti

IndiceCli

Clienti

ClientiFile

ClientiFile

IndiceCli

ClientiFile

IndiceCli

ApriFile

LeggiRappresentante

OrdinaClienti

MostraRisultati

ClientiFile

ClientiFile

ClientiFile

Clienti[I]

IndiceCli

Sentinella

Sentinella

Cognome

Nome

CostruisciRecordCliente

LeggiParola

LeggiParola

ClientiFile

ClientiFile

ClientiFile

ClientiFile

ClientiFile

Sent

Sent

Sent

Nazione

Mese

Anno

Sent

CognCli

Sent

Giorno

LeggiParola

LeggiParola

LeggiParola

LeggiParola

LeggiParola

BEGIN

assign(ClientiFile,'C:\Modapr\test1.TXT');

reset(ClientiFile);

LeggiRappresentante(ClientiFile, IndiceCli);

readln;

OrdinaClienti(IndiceCli,Clienti, ClientiFile);

MostraRisultati(Clienti,IndiceCli);

readln

END.


PROCEDURE LeggiParola(Sentinella:char;VAR Parola:StringaNome;VAR Clienti:text);

VAR

Carattere:char;

BEGIN

Parola:='';

read(Clienti,Carattere);

WHILE (Carattere<>Sentinella) DO

BEGIN

Parola:=Parola+Carattere;

read( Clienti,Carattere)

END;

END;


PROCEDURE CostruisciRecordCliente(UnCliente:ClienteRecord;VAR ClientiFile:text);

BEGIN

WITH UnCliente, Nascita DO

BEGIN

LeggiParola(' ',CognCli, ClientiFile);

LeggiParola('^',Nazione, ClientiFile);

read(ClientiFile,Giorno);

read(ClientiFile,Mese);

read(ClientiFile,Anno);

readln(ClientiFile);

writeln(' Cliente ',CognCli,' ',' Nazionalita'' ',Nazione);

writeln(' Nato il ',Giorno,'/',Mese,'/',Anno);

writeln

END

END;

PROCEDURE LeggiRappresentante (VAR ClientiFile:text; VAR IndiceCli1:IndiceTipo);

VAR

UnRappresentante: RappresentanteRecord;

BEGIN

WITH UnRappresentante, Anagrafe DO

BEGIN

LeggiParola(' ',Cognome, ClientiFile);

LeggiParola('^',Nome, ClientiFile);

read(ClientiFile,IndiceCli1);

readln(ClientiFile);

writeln('Rappresentante ',Cognome,' ',Nome,'N. Clienti',IndiceCli);

END

END;


PROCEDURE Scambia(VAR Ch1,Ch2: StringaNome);

VAR

Temp: StringaNome;

BEGIN

Temp:=Ch1;

Ch1:=Ch2;

Ch2:=Temp

END;

PROCEDURE Ordina(VAR Clienti:CliArray; IndiceCli:IndiceTipo);

VAR

Ordinato,

Indice: IndiceTipo;

BEGIN

WITH UnCliente DO

FOR Ordinato:=1 TO IndiceCli DO

FOR Indice:= IndiceCli DOWNTO Ordinato DO

IF Clienti[Indice].Nazione > Clienti[Indice+1].Nazione THEN

Scambia(Clienti[Indice].Nazione,Clienti[Indice+1].Nazione);

END;


PROCEDURE OrdinaClienti(VAR IndiceCli:IndiceTipo;VAR Clienti:CliArray; VAR ClientiFile:text);

VAR

Indice:IndiceTipo;

BEGIN

FOR Indice:=1 TO IndiceCli DO

BEGIN

CostruisciRecordCliente(Clienti[Indice],ClientiFile);

END;

Ordina(Clienti,IndiceCli)

END;

PROCEDURE MostraRisultati(VAR Clienti:CliArray;IndiceCli:IndiceTipo);

VAR I:integer;

BEGIN

WITH UnCLiente DO

FOR I:=1 TO IndiceCli DO

writeln(Clienti[I].CognCli,' ',Clienti[I].Nazione,' ',Clienti[I].Nascita.Giorno,'/',Clienti[I].Nascita.Mese,'/',Clienti[I].Nascita.Anno);

END;


BEGIN

assign(ClientiFile,'C:\Modapr\test1.TXT');

reset(ClientiFile);

LeggiRappresentante(ClientiFile, UnRappresentante, IndiceCli);

readln;

OrdinaClienti(IndiceCli,Clienti, ClientiFile);

MostraRisultati(Clienti,IndiceCli);

readln

END.

TP\ESEMPI|MODA


Esercizio n° 5

Scrivere un programma che, dato un file testo prova.txt estragga dal testo tutti i caratteri di tipo numerico sostituendoli con spazi vuoti. Memorizzare il file così corretto con il nome di prova1.txt.

Fare la somma dei numeri estratti.

Es. DATI

Ab73cqSw1yt

Ab cqSw yt

A video deve comparire

73

1

Somma = 74


ProInput

ProOut

ProInput

ProOut

Somma

Somma

CercaNumero

ChiudiEStampa

ApriFile

Ch

Pot

Numero

CostruisciNumero

Pot

Potenza

ApriFile(ProInput,ProOut);

CercaNumero(ProInput,ProOut,Somma);

ChiudiEStampa(ProInput,ProOut,Somma);

readln


PROGRAM Esercizio5(output,ProInput,ProOut);

VAR

ProInput,ProOut: text;

Somma:integer;

FUNCTION Potenza(P:integer):integer;

VAR

I,Pote:integer;

BEGIN

Pote:=1;

FOR I:=1 TO P DO

Pote:=Pote*10;

Potenza:=Pote

END;

PROCEDURE CostruisciNumero(VAR Numero,Pot:integer;Ch:char);

VAR CharNum:integer;

BEGIN

CharNum:=ord(Ch)-ord('0');

Numero:= CharNum +Numero*potenza(Pot);

END;

PROCEDURE ApriFile(VAR PrIn,Prout:text);

BEGIN

assign(PrIn,'C:\TP\ESEMPI\TEST5.TXT');

assign(Prout,'C:\TP\ESEMPI\COPIA5.TXT');

reset(PrIn);

rewrite(Prout);

END;


PROCEDURE CercaNumero(VAR ProInp,ProOu:text; VAR Somm:integer);

VAR

Numero, Pot:integer; Ch: Char;

BEGIN

WHILE NOT eof(ProInp) DO

BEGIN

WHILE NOT eoln(ProInp) DO

BEGIN

Numero:=0; Pot:=0;

read(ProInp,Ch);

IF (ord(Ch)<58) AND (ord(Ch)>47) THEN

BEGIN

WHILE (ord(Ch)<58) AND (ord(Ch)>47) DO

BEGIN

write(ProOu,' ');

CostruisciNumero(Numero,Pot,Ch);

Pot:=Pot+1;

read(ProInp,Ch);

END;

writeln(Numero);

Somm:=Somm+Numero;

write(ProOu,Ch);

END

ELSE

write(ProOut,Ch);

END;

END;

END;


PROCEDURE ChiudiEStampa(VAR ProInpu,ProOu:text;Som:integer);

BEGIN

close(ProInpu);

close(ProOu);

writeln('File Duplicato -- La somma vale: ',Som);

END;

{*************MAIN**************}

BEGIN

ApriFile(ProInput,ProOut);

CercaNumero(ProInput,ProOut,Somma);

ChiudiEStampa(ProInput,ProOut,Somma);

readln

END.

TP\ESEMPI|MODA


Esercizio 3

Sia data la successione:

an=an-3+3*an-2 -2*an-1+c

Calcolare la somma dei valori della successione per n che va da 3 a un valore prefissato K sapendo che:

a0=-1 a1=2 a2=-5

e che c è una costante prefissata a priori.


PROGRAM Esercizio3(input,output);

VAR

C,K,I:integer;

An,An1,An2,An3:real;

PROCEDURE AssegnaValori(VAR C1,K1:integer);

BEGIN

Write(' Dammi C ');

Readln(C1);

Write(' Dammi K ');

Readln(K1);

END;

PROCEDURE CalcolaSuccessione(an11,an22,an33:real;C1,K1:integer);

VAR An:real;

BEGIN

writeln('Valori della successione da 1 a ',K);

writeln('1 = ',an11:5:0);

writeln('2 = ',an22:5:0);

writeln('3 = ',an33:5:0);

FOR I:=3 TO K1 DO

BEGIN

An:=an3+3*an2*an1+C1;

An3:=an2;

An2:=an1;

An1:=an;

writeln(I:1,' = ',An:5:0);

END;

END;


{****************** MAIN ****************}

BEGIN

An3:=-1;

An2:=2;

An1:=-5;

AssegnaValori(C,K);

CalcolaSuccessione(an1,an2,an3,C,K);

writeln(' FINE COMPUTAZIONE ');

readln

END.

TP\ESEMPI|MODA



PROGETTO

PROGRAMMA PRINCIPALE -

Program

…………………...…..

end.

uses xxxx, yyyy;

unit xxxx

………………...

end.

MODULO 1 -

………………………………………….

unit yyyy

………………...

end.

MODULO n -


DATA ABSTRACTION

Qualunque tipo di dati può essere descritto sulla base dei valori

che esso può prendere e delle operazioni che ad esso si possono

applicare.

ESEMPIO

TipoValoriOperazioni

integer - maxint ÷ + maxint +, -, *, DIV

real 10-38 ÷ 10+38 +, -, *, /

boolean TRUE, FALSE AND, OR, NOT


Un abstract data type (ADT) e’ un Type definito in termini del nome logico che gli si attribuisce e delle operazioni che possono essere applicate ad esso.

DATA ABSTRACTION

Separazione del significato logico delle operazioni in un ADT dai dettagli implementativi.


ESEMPIO

NUMERI COMPLESSI

Un numero complesso in genere è scritto come

a + bi

dove a e b sono dei numeri reali e i, detta parte immaginaria, ed è tale che

i2=-1


Nel 1572 tale Raffaele Bombelli, colui che per primo introdusse le parentesi, propose di trattare la come una entità a parte e di applicare ad essa tutte le regole che valevano per i numeri normali.

Cartesio chiamò i numeri che prevedevano la presenza della

numeri “immaginari” mentre Gauss li chiamò “complessi”.

Solo nel 1777 Eulero propose di sostituire con la lettera “i”.

I numeri complessi sono usati in elettrotecnica, dinamica dei fluidi, aerodinamica etc.

Notizie sui numeri complessi si trovano in il TEOREMA DEL PAPPAGALLO di Denis Guedj, ed. Longanesi, pag.326


Rappresentazione grafica dei numeri complessi introdusse le parentesi, propose di trattare la come una entità a parte e di applicare ad essa tutte le regole che valevano per i numeri normali.


Progettare una ADT per i numeri complessi significa realizzare un software che permette di definire un TypeComplesso e implementi tutta una serie di operazioni tipiche dei numeri complessi. Es. addizione, sottrazione, moltiplicazione, divisione, valore assoluto, ……………………………..

Una ADT, una volta implementata viene memorizzata su un file e richiamata da un programma solo quando richiesta. Ognuno di questi file è definito come unit e come tale è riconosciuto dal programma principale quando viene richiamato.


UNIT realizzare un software che permette di definire un

(pag. 906 testo)

E’ un insieme di costanti, tipi, dati, variabili funzioni e procedure che può essere memorizzato su un file e compilato separatamente dal programma principale che lo chiama.

Nel Turbo Pascal per compilare una unit si deve scegliere sotto la voce COMPILE l’option DISK (per i programmi generali si usa invece MEMORY).

Per richiamare una unit in un programma si usa la parola chiave

uses nome_unit, ….;


UNIT realizzare un software che permette di definire un

interfaccia

Contiene le dichiarazioni globali a tutta la unit e le definizioni di procedure e funzioni da esportare

implementazione

Contiene i corpi delle procedure e funzioni sopra dichiarate insieme alle dichiarazioni di costanti, tipo, variabili e procedure locali all’unità.

unit xxxxxxxx;

interface

……….

implementation

………………

end.


ComplexNo realizzare un software che permette di definire un

XRe

YIm

NUMERI COMPLESSI

X + Yi

TYPE

ComplexNo=RECORD

XRe, YIm: real

END;


UNIT realizzare un software che permette di definire un ADTComplexNo;

{documentazione}

INTERFACE {sezione interfaccia}

{definizioni dell’ADT}

TYPE

ComplexNo=RECORD

XRe, YIm: real

END;

{ le operazioni }

PROCEDURE ……………………..

FUNCTION ………………………….

IMPLEMENTATION {sezione implementazioni}

PROCEDURE ……………………..

FUNCTION ………………………….


NUMERI COMPLESSI realizzare un software che permette di definire un

a + bi

Le operazioni con i numeri complessi:

Parte Reale: a

Parte Immaginaria: b

Modulo:

Somma : (a + bi) + (c + di) = (a + c) + (b + d) i

Sottrazione: (a + bi) - (c + di) = (a - c) + (b - d) i

Moltiplicazione: (a + bi) * (c + di) = (ac - bd) -(ad + bc) i

Divisione:


UNIT realizzare un software che permette di definire un ADTComplexNo;

{documentazione}

INTERFACE {inizio della sezione INTERFACE}

{ definizioni dell’ADT }

TYPE

ComplexNo=RECORD

Xre, Yim: real

END;

{ le operazioni }

PROCEDURE MakeComp(Xpart, Ypart:real;

VAR Cnumber: ComplexNo);

{ costruisci il numero complesso }

FUNCTION RealPart(Cnumber: ComplexNo):real;

{ identifica la parte reale del numero complesso }

FUNCTION ImaginaryPart(Cnumber: ComplexNo):real;

{ identifica la parte immaginaria del numero complesso }

FUNCTION Magnitude(Cnumber: ComplexNo):real;

{ identifica il modulo del numero complesso }


PROCEDURE realizzare un software che permette di definire un AddComp(Term1, Term2:ComplexNo;

VAR Sum: ComplexNo);

{ addiziona i numeri complessi Term1 e Term2 }

PROCEDURE SubtrComp(Term1, Term2: ComplexNo;

VAR Difference: ComplexNo);

{ sottrae i numeri complessi Term1 e Term2 }

PROCEDURE MultComp(Factor1, Factor2: ComplexNo;

VAR Product: ComplexNo);

{ moltiplica i numeri complessi Factor1 e Factor2 }

PROCEDURE DivComp(Factor1, Factor2: ComplexNo;

VAR Quotient: ComplexNo);

{ divide i numeri complessi Factor1 e Factor2 }

{ fine della sezione INTERFACE }


IMPLEMENTATION realizzare un software che permette di definire un {inizio della sezione IMPLEMENTATION}

PROCEDUREMakeComp(Xpart, Ypart:real;

VAR Cnumber: ComplexNo);

{ costruisci il numero complesso }

BEGIN

Cnumber.Xre:=Xpart;

Cnumber.Yim:=Ypart

END;

FUNCTIONRealPart(Cnumber: ComplexNo):real;

{ identifica la parte reale del numero complesso }

BEGIN

RealPart:= Cnumber.Xre

END;

FUNCTIONImaginaryPart(Cnumber: ComplexNo):real;

{ identifica la parte immaginaria del numero complesso }

BEGIN

ImaginaryPart:= Cnumber.Yim

END;


FUNCTION realizzare un software che permette di definire un Magnitude(Cnumber: ComplexNo):real;

{ identifica il modulo del numero complesso

}

BEGIN

Magnitude:= sqrt(sqr(Cnumber.Xre)+sqr(Cnumber.Yim))

END;

PROCEDUREAddComp(Term1, Term2:ComplexNo;

VAR Sum: ComplexNo);

{ addiziona i numeri complessi Term1 e Term2

(a + bi) + (c + di) = (a + c) + (b + d) i }

BEGIN

WITH Sum DO

BEGIN

Xre:=Term1.Xre+Term2.Xre;

Yim:=Term1.Yim+Term2.Yim

END

END;


PROCEDURE realizzare un software che permette di definire un SubtrComp(Term1, Term2:ComplexNo;

VAR Difference: ComplexNo);

{ addiziona i numeri complessi Term1 e Term2

(a + bi) - (c + di) = (a - c) + (b - d) i }

BEGIN

WITH Difference DO

BEGIN

Xre:=Term1.Xre - Term2.Xre;

Yim:=Term1.Yim - Term2.Yim

END;

END;


PROCEDURE realizzare un software che permette di definire un MultComp(Factor1, Factor2:ComplexNo;

VAR Product: ComplexNo);

{ addiziona i numeri complessi Term1 e Term2

(a + bi) * (c + di) = (ac - bd) -(ad + bc) i }

BEGIN

WITH Product DO

BEGIN

Xre:=Factor1.Xre * Factor2.Xre - Factor1.Yim * Factor2.Yim;

Yim:=Factor1.Xre * Factor2.Yim + Factor2.Xre * Factor1.Yim

END

END;


PROCEDURE realizzare un software che permette di definire un DivComp(Factor1, Factor2:ComplexNo;

VAR Quotient: ComplexNo);

{ addiziona i numeri complessi Term1 e Term2

}

VAR

Divisor: real;{divisore del quoziente}

BEGIN

Divisor:=sqr(Factor2.Xre) + sqr(Factor2.Yim);

WITH Quotient DO

BEGIN

Xre:=(Factor1.Xre * Factor2.Xre + Factor1.Yim * Factor2.Yim)/Divisor;

Yim:= (Factor1.Yim *Factor2.Xre - Factor1.Xre * Factor2.Yim)/Divisor

END

END;


ESEMPIO realizzare un software che permette di definire un

Risolvere l’equazione di primo grado AX+B=C con A, B, C numeri complessi. Supponiamo A 0.

Soluzione: X=(C-B)/A

Input: Introdurre i coefficienti nell’ordine: A, B, C

Per ogni coefficiente introdurre prima la parte reale e poi la parte immaginaria.

Ouput: Mostrare la soluzione X sotto forma di numero complesso


Equazione realizzare un software che permette di definire un

A

A

B

B

X

X

C

C

Mostra Istr.

Leggi

Calcola

Mostra Ris.

ADTComplexNo

ADTComplexNo

ADTComplexNo

Pseudo codice

Richiama la unit per i numeri complessi;

Mostra le istruzioni per l’introduzione dei dati;

Leggi i coefficienti;

Calcola la soluzione;

Mostra la soluzione.


PROGRAM realizzare un software che permette di definire un Equazione(input,output);

USES

Compl;

VAR

A,B,C, {coefficienti}

X: ComplexNo; {soluzione}

PROCEDURE MostraIstruzioni;

BEGIN

writeln('L'' equazione e'' immaginata sotto la forma AX+B=C. ' );

writeln('I coefficienti A,B,C vanno introdotti come coppie di numeri:');

writeln('prima la parte reale e poi quella immaginaria')

END;


PROCEDURE realizzare un software che permette di definire un MC(Z:ComplexNo);

{mostra il numero complesso Z}

VAR

Segno:STRING[3];

BEGIN

Segno:=' ';

IF ImaginaryPart(Z)>=0 THEN Segno:=' + ';

writeln(RealPart(Z):3:1,Segno,ImaginaryPart(Z):3:1,'i');

writeln

END;


PROCEDURE realizzare un software che permette di definire un LeggiCoefficienti(VAR A,B,C:ComplexNo);

VAR

ARe,BRe,CRe,AIm,BIm,CIm:real;

BEGIN

write('Coefficiente A= ');

readln(ARe,AIm);

write('Coefficiente B= ');

readln(BRe,BIm);

write('Coefficiente C= ');

readln(CRe,CIm);

MakeComp(ARe,AIm,A);

MakeComp(BRe,BIm,B);

MakeComp(CRe,CIm,C)

END;


PROCEDURE realizzare un software che permette di definire un Soluzione(A,B,C:ComplexNo; VAR X:ComplexNo);

{documentazione}

VAR

CmenoB:ComplexNo;

BEGIN

SubtrComp(C,B,CmenoB);

DivComp(CmenoB,A,X)

END;

PROCEDURE MostraRisultato(X:ComplexNo);

BEGIN

writeln('La radice dell''equazione assegnata e'': ');

MC(X)

END;


{ realizzare un software che permette di definire un BODY }

BEGIN

MostraIstruzioni;

LeggiCoefficienti(A,B,C);

Soluzione(A,B,C,X);

MostraRisultato(X)

END.


OUTPUT realizzare un software che permette di definire un

L' equazione e' immaginata sotto la forma AX+B=C.

I coefficienti A,B,C vanno introdotti come coppie di numeri:

prima la parte reale e poi quella immaginaria

Coefficiente A= 5 66

Coefficiente B= 77 55

Coefficiente C= 4 2

La radice dell'equazione assegnata e':

-0.9 + 1.0i


c realizzare un software che permette di definire un

b

d

a

f

ESERCIZIO 1-B

Progettare e realizzare una Unit che permetta il calcolo delle aree e dei perimetri delle seguenti figure geometriche:

Triangolo rettangolo – assegnata la base e l’altezza

Rettangolo – assegnata la base e l’altezza

Utilizzando la Unit di cui sopra trovare l’area dell’appartamento la cui planimetria è data in figura assegnando alle dimensioni a,b,c,d,e,f valori a piacere (da tastiera) e per ogni vano calcolare la superficie complessiva dei muri sapendo che l’altezza di ogni vano vale k.

e


REGOLE GENERALI PER LA PROGETTAZIONE DI realizzare un software che permette di definire un

UNIT ADT

Completezza: non necessita di operazioni addizionali per essere usata

Ogni operazione deve appartenere ad una delle seguenti categorie:

Constructor - cambia o inizializza i valori di una variabile astratta

Primitive constructor - assegna un valore ad una variabile astratta senza fare uso di altre variabili astratte dello stesso tipo. Ha una sola variabile di output e quelle di input servono per costruire l’output.

Es.

MakeComp(Xpart, Ypart:real; VAR Cnumber: ComplexNo);

{ costruisci il numero complesso }

Ogni ADT richiede almeno un Primitive constructor così che il client può assegnare un valore iniziale alla variabile astratta.


Non-primitive constructor realizzare un software che permette di definire un -. Ha almeno una variabile di input il cui tipo è uguale a quello dell’output.

Es.

AddComp(Term1, Term2:ComplexNo; VAR Sum: ComplexNo);

{ addiziona i numeri complessi Term1 e Term2 }


SELECTOR realizzare un software che permette di definire un - fornisce informazioni su una variabile di input ADT ad un parametro di uscita. Spesso è una funzione (il parametro di uscita in tal caso è la funzione stessa).

Primitive selector - ritorna il valore di uno dei componenti della variabile astratta. Es.

RealPart(Cnumber: ComplexNo):real;

{ identifica la parte reale del numero complesso }

Ogni unit necessita di un Primitive selector altrimenti il client non può mostrare i valori della variabile.

Non-primitive selector - ritorna il valore che non è relativo ad uno dei componenti della variabile astratta ma ciò nonostante è utile al client.

Es.

Magnitude(Cnumber: ComplexNo):real;

{ identifica il modulo del numero complesso }


PREDICATE realizzare un software che permette di definire un - è una funzione booleana che ritorna informazioni sul valore o lo stato di una variabile astratta.


  • Un ADT è realizzare un software che permette di definire un completa se il client :

  • fa riferimento solo al type dell’ADT (es. ComplexNo)

  • non deve mai cambiare la logica delle operazioni dell’unit

  • non deve mai aver bisogno di altre operazioni

  • Ogni unit ADT deve avere :

  • un primitive constructor

  • i valori devono poter essere letti e scritti

  • tutte le operazioni prevedibili per il tipo di ADT


Head realizzare un software che permette di definire un

Head

Tail

LE CODE (QUEUE)


LE CODE (QUEUE) realizzare un software che permette di definire un

Le operazioni fondamentali che si fanno sulle code sono:

riempimento e svuotamento.

Questo implica che durante lo svolgimento del programma il numero di oggetti in coda può cambiare.

Dynamic data type: il numero di componenti nel Data Type cambia nel corso del programma.

Dobbiamo descrivere una queue in funzione della sua head (testa), della sua tail (coda), degli oggetti in coda e del loro numero in ogni istante della computazione.


OPERAZIONI SULLE CODE realizzare un software che permette di definire un

In una coda l’elemento inserito per primo viene anche estratto per primo (FIFO).

In una coda occorerrà allora distinguere tra un inizio o TESTA della coda (punto di estrazione e/o cancellazione di un elemento) ed una fine o CODA della coda (punto di inserimento di un nuovo elemento).

Aggiungere ed eliminare oggetti.

Se Items[ ] è un array in cui si collocano gli oggetti. Head l’indice dell’array corrispondente alla Testa, Tail l’indice corrispondente alla coda e Item l’oggetto da aggiungere potremmo usare i seguenti algoritmi:


OPERAZIONI SULLE CODE realizzare un software che permette di definire un

AGGIUNGERE

Tail  Tail+1

Items[Tail] Item

InUse InUse + 1

ELIMINARE

Head  Head+1

InUse InUse - 1

SOLUZIONE IMPROPONIBILE !!!!!!!!!!!!

Ogni volta che esce un oggetto bisogna spostare in avanti di un posto tutti quelli in coda altrimenti lo spazio disponibile si esaurisce rapidamente pur essendoci posti vuoti.


Testa realizzare un software che permette di definire un

N°=6

Coda

Testa

Coda

1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9

N°=6

Coda

Testa

N°=7

1 2 3 4 5 6 7 8 9

Escono due oggetti e ne entrano due

Escono due oggetti e ne entrano tre


Gli indici che caratterizzano Head e Tail devono variare tra 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

entra esce head tail in use

0 0 1 6 6

0 1 2 6 5

0 1 3 6 4

1 0 3 7 5

1 0 3 8 6

0 1 4 8 5

0 1 5 8 4

1 0 5 9 5

1 0 5 1 6

1 0 5 2 7


Possiamo descrivere una 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.queue in funzione della sua head (testa), della sua tail (coda), degli oggetti in coda e del loro numero in ogni istante della computazione utilizzando l’espressione

Tail:=Tail MOD MaxQueue + 1

Head:=Head MOD MaxQueue + 1

è infatti facile mostrare che con queste espressioni Tail e Head assumeranno giusto i valori indicati nella tabella precedente nel caso dell’esempio mostrato.


LE CODE (QUEUE) 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Le queue si riempiono aggiungendo oggetti in coda e si svuotano a partire dalla testa.

Supponiamo di voler gestire con un meccanismo a coda 100 oggetti di tipo stringa.


QueueType 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Head

Tail

InUse

Items

UNITCode;

{documentazione}

INTERFACE {sezione interfaccia}

{definizioni dell’ADT}

CONST

MaxQueue=100;

NullItem=‘’;

TYPE

ItemType=STRING[20] massima lunghezza delle stringhe

QueueType=RECORD

Head, primo oggetto nella coda

Tail : 1..MaxQueue; ultimo oggetto nella coda

InUse :0..MaxQueue; numero di oggetti in coda

Items: ARRAY[1..MaxQueue] OF ItemType contiene gli oggetti in coda

END;


{ 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.le operazioni }

PROCEDURE MakeQueue(VAR Queue:QueueType);

{ inizializza la coda vuota }

PROCEDURE AddQueue(Item:ItemType; VAR Queue:QueueType);

{ se la coda non è piena aggiungi oggetti altrimenti segnala errore }

PROCEDURE DeleteQueue(VAR Queue:QueueType);

{se la coda non è vuota elimina il primo oggetto altrimenti segnala errore}

PROCEDURE FirstOnQueue(VAR Queue:QueueType;

VAR Item:ItemType);

{assegna a Item il valore del primo oggetto in coda, in mancanza assegna valore nullo}


FUNCTION 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili. QCount(VAR Queue:QueueType; ):integer;

{ identifica quanti oggetti sono in coda }

FUNCTION QEmpty(VAR Queue:QueueType; ):boolean;

{ vera se non ci sono oggetti in coda }

FUNCTION QFull(VAR Queue:QueueType; ):boolean;

{ vera se la coda è piena }

{ fine della sezione INTERFACE }


IMPLEMENTATION 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.{inizio della sezione IMPLEMENTATION}

QueueType

Head

Tail

InUse

Items

PROCEDURE MakeQueue(VAR Queue:QueueType);

{ inizializza la coda vuota }

BEGIN

WITH Queue DO

BEGIN

Head:=1;

Tail:=MaxQueue;

InUse:=0

END

END;


QueueType 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Head

Tail

InUse

Items

PROCEDURE AddQueue(Item:ItemType; VAR Queue:QueueType);

{ se la coda non è piena aggiungi oggetti altrimenti segnala errore }

BEGIN

WITHQueueDO

IFInUse<>MaxQueueTHEN

BEGIN

Tail:=Tail MOD MaxQueue+1

Items[Tail]:=Item;

InUse:=InUse+1

END

ELSE

writeln(‘Errore: la coda è piena’)

END;


QueueType 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Head

Tail

InUse

Items

PROCEDURE DeleteQueue(VAR Queue:QueueType);

{se la coda non è vuota elimina il primo oggetto altrimenti segnala errore}

BEGIN

WITHQueueDO

IFInUse<>0THEN

BEGIN

Head:=Head MOD MaxQueue+1

InUse:=InUse-1

END

ELSE

writeln(‘Errore: la coda è vuota)

END;


QueueType 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Head

Tail

InUse

Items

PROCEDURE FirstOnQueue(VAR Queue:QueueType;

VAR Item:ItemType);

{assegna a Item il valore del primo oggetto in coda, in mancanza assegna valore nullo}

BEGIN

WITHQueueDO

IFInUse<>0THEN

Item:=Items[Head]

ELSE

Item:=NullItem

END;


QueueType 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Head

Tail

InUse

Items

FUNCTION QCount(VAR Queue:QueueType; ):integer;

{ identifica quanti oggetti sono in coda }

BEGIN

QCount:=Queue.InUse

END;

FUNCTION QEmpty(VAR Queue:QueueType; ):boolean;

{ vera se non ci sono oggetti in coda }

BEGIN

QEmpty:=(Queue.InUse=0)

END;


QueueType 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Head

Tail

InUse

Items

FUNCTION QFull(VAR Queue:QueueType; ):boolean;

{ vera se la coda è piena }

BEGIN

QFull:=(Queue.InUse=MaxQueue)

END;

{ fine della sezione IMPLEMENTATION }


Alcune considerazioni sulla complessità. 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Si noti che abbiamo sempre usato la chiamata VAR per la variabile Queue perché in questa maniera in un solo passo di computazione O(1) abbiamo a disposizione l’array Queue mentre in caso contrario ogni volta avremmo usato la copia dell’array che ci costa O(N) passi.


Constructor 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili. - cambia o inizializza i valori di una variabile astratta

Primitive constructor - assegna un valore ad una variabile astratta senza fare uso di altre variabile astratte dello stesso tipo. Ha una sola variabile di output e quelle di input servono per costruire l’output.

PROCEDURE MakeQueue(VAR Queue:QueueType);

{ inizializza la coda vuota }

Ogni ADT richiede almeno un Primitive constructor così che il client può assegnare un valore iniziale alla variabile astratta.

Non-primitive constructor -. Ha almeno una variabile di input e il cui tipo è uguale a quello dell’output.

Es.

PROCEDURE AddQueue(Item:ItemType; VAR Queue:QueueType);

{ se la coda non è piena aggiungi oggetti altrimenti segnala errore }


SELECTOR 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili. - fornisce informazioni su una variabile di input ADT ad un parametro di uscita. Spesso è una funzione (il parametro di uscita in tal caso è la funzione stessa).

Primitive selector - ritorna il valore di uno dei componenti della variabile astratta. Es.

PROCEDURE FirstOnQueue(VAR Queue:QueueType;

VAR Item:ItemType);

{assegna a Item il valore del primo oggetto in coda, in mancanza assegna valore nullo}

Ogni unit necessita di una Primitive selector altrimenti il client non può mostrare i valori della variabile.


Non-primitive selector 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili. - ritorna il valore che non è relativo ad uno dei componenti della variabile astratta ma ciò nonostante è utile al client.

Es.

FUNCTION QCount(VAR Queue:QueueType; ):integer;

{ identifica quanti oggetti sono in coda }


PREDICATE 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili. - è una funzione booleana che ritorna informazioni sul valore o lo stato di una variabile astratta.

FUNCTION QEmpty(VAR Queue:QueueType; ):boolean;

{ vera se non ci sono oggetti in coda }

BEGIN

QEmpty:=(Queue.InUse=0)

END;


Questo parametro è inutile e fuorviante 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

CONSIGLI PER UNA CORRETTA PROGRAMMAZIONE

Per un corretto funzionamento delle Unit è necessario che ogni operatore esegua una e una sola operazione e che solo i parametri necessari e sufficienti siano passati alla procedura. Se una operazione soddisfa questi criteri è detta pura.

PROCEDURE DeleteQueue(VAR Queue:QueueType);

BEGIN

WITHQueueDO

IFInUse<>0THEN

BEGIN

Head:=Head MOD MaxQueue+1

InUse:=InUse-1

END

ELSE

writeln(‘Errore: la coda è vuota)

END;

PROCEDURE DeleteQueue(VAR Queue:QueueType;VAR Item:ItemType);

BEGIN

WITHQueueDO

IFInUse<>0THEN

BEGIN

Head:=Head MOD MaxQueue+1

InUse:=InUse-1

END

ELSE

writeln(‘Errore: la coda è vuota)

END;


CONSIGLI PER UNA CORRETTA PROGRAMMAZIONE 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Ogni UNIT deve avere solo operazioni pure.

Ogni operazione deve essere assolutamente necessaria altrimenti non va inserita nella UNIT.

Ogni operazione deve fare una sola cosa altrimenti si corrono rischi di errori.

Ogni operazione deve fare una sola cosa altrimenti si corrono rischi di errori che possono, in maniera nascosta riversarsi su tutto il programma.

La logica utilizzata all’interno della UNIT deve essere del tutto trasparente per il client.


GESTIONE ERRORI 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Ogni operazione deve essere dotata di sistemi di controllo per evitare errori.

PROCEDURE DeleteQueue(VAR Queue:QueueType);

{se la coda non è vuota elimina il primo oggetto altrimenti segnala errore}

BEGIN

WITHQueueDO

IFInUse<>0THEN

BEGIN

Head:=Head MOD MaxQueue+1

InUse:=InUse-1

END

ELSE

writeln(‘Errore: la coda è vuota’)

END;


GESTIONE ERRORI 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Ogni operazione di una unit deve possedere messaggi di errore che arrestino la computazione e consentano all’utente di fare le opportune correzioni senza mandare in crash il sistema.

Una adeguata illustrazione delle segnalazioni di errore, delle cause che li possono produrre e dei provvedimenti da prendere va fatta nell’ambito del manuale di accompagnamento del software.


NORME PER FARE GLI ESERCIZI 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Nome file: cognome+iniziale nome

In testa ad ogni programma devono essere scritti i dati dello

studente.

Es.

nome file -> BianchiG

{programma sviluppato da Bianchi Giulio mat. 050/888}

PROGRAM …….


ESERCIZIO 2 B 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Vogliamo simulare l’attività di un bistrot parigino che vende solo caffè a coppie di giovani. Il numero di tavolini è limitato e il numero di caffè da vendere è stabilito all’inizio. Useremo una coda fatta di stringhe, ognuna delle quali è il nome dei clienti ai tavoli che attendono il caffè.

Il barman si comporta così.

Inizialmente stabilisce quanti caffè deve vendere (un numero pari).

Successivamente si predispone ad accettare uno dei seguenti comandi e quindi li esegue.

- A (fai accomodare): se in coda ci sono meno di tre clienti il barman accetta la nuova coppia e la fa accomodare altrimenti rifiuta il posto.

- S (porta il caffè) se almeno un tavolino è occupato porta il caffè al primo arrivato, se non c’è nessuno si arrabbia. Se sono terminati i caffè si mandano via quelli che sono rimasti al tavolo. Si presume che preso il caffè il tavolo si libera subito.

- R (riassunto): comunica il numero di caffè venduti, il numero di caffè rimasti e la lunghezza della coda.


ALGORITMO del Bistrot 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Inizializza(VAR Queue: QueueType; VAR TotaleDaVendere:integer);

TotaleVenduto 0;

ChiedereNumeroCaffè DaVendere

WHILE DaVendere>0

Azione

IF Azione IN [‘a’,’A’,‘V’,’v’,’r’,’R’] THEN

CASE Azione OF

‘a’,’A’: IncrementaCoda(Queue);

‘s’,’S’: Vendita(Queue,TotaleVenduto,TotaleDaVendere)

‘r’,’R’: Riassunto(TotaleVenduto,TotaleDaVendere,ContaCoda)

MostraMessaggioPerFineCaffè.


PROGRAM 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili. Bistrot(input,output);

{Simula una coda per servire il caffè a coppie di giovani }

{La coda finisce quando tutti i tavolini sono occupati}

USES Coda;

CONST

MaxSize=3; {dimensione massima della coda}

Urlo=’xxxxxxxxxxxxxx’;

Urlo2=’ssssssssssssss';

VAR

Queue:QueueType;

TotaleVenduto, {totale caffè venduti }

TotaleDaVendere: integer; {caffè da vendere }

Azione: char; {lettera del menu per fare le scelte }


PROCEDURE 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili. Inizializza(VAR Queue:QueueType; VAR TotaleDaVendere:integer);

{fa partire la coda e legge un numero pari di caffè da vendere }

BEGIN

MakeQueue(Queue);

write('Quanti caffè dobbiamo preparare oggi? ');

readln(TotaleDaVendere);

TotaleDaVendere:=abs(TotaleDaVendere); {garanzia contro I numeri negativi }

IF TotaleDaVendere MOD 2 <>0 THEN

TotaleDaVendere:=TotaleDaVendere-1

END;

PROCEDURE IncrementaCoda(VAR Queue:QueueType);

{ }

VAR

Name:ItemType; {Nome da aggiungere alla coda }

BEGIN

IF Qcount(Queue)<MaxSize THEN

BEGIN

write('Nome: ');

readln(Name);

writeln(Name, ' accomodatevi al tavolo, prego.'.');writeln;

AddQueue(Name,Queue)

END

ELSE

writeln('Mi dispiace i tavoli sono tutti occupati. ‘);

writeln;

END;


PROCEDURE 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili. Vendita(VAR Queue:QueueType; VAR TotaleVenduto, TotaleDaVendere:integer);

{ }

VAR

Name:ItemType; {nome del cliente }

BEGIN

IF NOT Qempty(Queue) THEN

BEGIN

FirstOnQueue(Queue,Name);

TotaleVenduto:=TotaleVenduto+2;

TotaleDaVendere:=TotaleDaVendere-2;

write(Name);

writeln(' Prego accomodatevi');

DeleteQueue(Queue)

END

ELSE

writeln(Urlo2)

END;


PROCEDURE 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili. Riassunto(TotaleVenduto, TotaleDaVendere, OnQueue:integer);

{ mostra la situazione dei biglietti e della coda}

BEGIN

write(TotaleVenduto:1,' biglietti venduti, e ');

writeln(' la lunghezza della coda e'' ',OnQueue,'.');

writeln(' Sono rimasti ancora ',TotaleDaVendere:1,' biglietti da vendere.')

END;

PROCEDURE MostraRifiuto(Queue:QueueType);

{ }

VAR

Name:ItemType; {nome della persona a cui chiede scusa }

BEGIN

WHILE NOT Qempty(Queue) DO

BEGIN

FirstOnQueue(Queue,Name);

writeln('Scusate don ',Name,', i bigliette sono finiti.');

DeleteQueue(Queue)

END

END;


{ 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.BODY }

BEGIN

Inizializza(Queue,TotaleDaVendere);

TotaleVenduto:=0;

writeln(Urlo);

WHILE TotaleDaVendere>0 DO

BEGIN

write('Azione: ');

readln(Azione);

IF Azione IN ['A','a', 'S','s','R','r'] THEN

CASE Azione OF

'A','a': IncrementaCoda(Queue);

'S','s': Vendita(Queue,TotaleVenduto,TotaleDaVendere);

'R','r': Riassunto(TotaleVenduto,TotaleDaVendere,QCount(Queue))

END

END;

MostraRifiuto(Queue);

readln

END.


Top 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Top

STACK


STACK 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Le operazioni fondamentali che si fanno sugli stack sono:

riempimento e svuotamento.

Questo implica che durante lo svolgimento del programma il numero di oggetti nello stack può cambiare.

Anche lo stack come la queue è un Dynamic data type (il numero di componenti nel Data Type cambia nel corso del programma).

Per descrivere uno stack è sufficiente sapere quali sono gli oggetti (Items) nello stack e il loro numero (Top).


OPERAZIONI SUGLI STACK 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

In uno stack l’elemento inserito per ultimo viene estratto per primo (LIFO - Last In First Out).

In uno stack occorrerrà solo conoscere il numero di oggetti (Top).

Aggiungere ed eliminare oggetti.

Items[ ] è un array in cui si collocano gli oggetti, Top il numero di oggetti, l’operazione di aggiungere oggetti si chiama push e quella di eliminare oggetti pop.

Quando Top=0 allora lo stack è vuoto.


OPERAZIONI SUGLI STACK 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

AGGIUNGERE

Top  Top + 1

Items[Top] Item

ELIMINARE

Top  Top - 1


STACK 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Supponiamo di voler gestire con un meccanismo a STACK 100 caratteri.


StackType 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Items

Top

UNITStack;

{documentazione}

INTERFACE {sezione interfaccia}

{definizioni dell’ADT}

CONST

MaxStack=100; massimo numero di caratteri che si possono trattare

TYPE

ItemType=char;

StackType=RECORD

Top : 0..MaxStack; numero di oggetti presenti

Items: ARRAY[1..MaxStack] OF ItemType contiene gli oggetti 

END;


{ 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.le operazioni }

PROCEDURE MakeStack(VAR Stack:StackType);

{ inizializza lo stack vuoto }

PROCEDURE Push(Item:ItemType; VAR Stack:StackType);

{ se lo stack non è pieno aggiungi oggetti altrimenti segnala errore }

PROCEDURE Pop(VAR Stack:StackType);

{se lo stack non è vuoto elimina il primo oggetto altrimenti segnala errore}

FUNCTION StackTop(VAR Stack:StackType): ItemType;

{se lo stack non è vuoto la funzione assume il valore dell’oggetto al top dello stack , in mancanza assume valore nullo chr(0)}


FUNCTION 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili. StackEmpty(VAR Stack:StackType; ):boolean;

{ vera se non ci sono oggetti nello stack }

FUNCTION StackFull(VAR Stack:StackType; ):boolean;

{ vera se lo stack è pieno }

{ fine della sezione INTERFACE }


IMPLEMENTATION 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.{inizio della sezione IMPLEMENTATION}

StackType

Items

Top

PROCEDURE MakeStack(VAR Stack:StackType);

{ inizializza lo stack vuoto }

BEGIN

Stack.Top:=0;

END;


StackType 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Items

Top

FUNCTION StackEmpty(VAR Stack:StackType; ):boolean;

{ vera se non ci sono oggetti nello stack }

BEGIN

StackEmpty:=(Stack.Top=0)

END;

FUNCTION StackFull(VAR Stack:StackType; ):boolean;

{ vera se lo stack è pieno }

BEGIN

StackFull:=(Stack.Top=MaxStack)

END;


StackType 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Items

Top

FUNCTION StackTop(VAR Stack:StackType): ItemType);

{se lo stack non è vuoto la funzione assume il valore dell’oggetto al top dello stack , in mancanza assume valore nullo chr(0)}

BEGIN

WITHStackDO

IFTop=0THEN

StackTop:=chr(0)

ELSE

StackTop :=Items[Top]

END;


StackType 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Items

Top

PROCEDURE Push(Item:ItemType; VAR Stack:StackType);

{ se lo stack non è pieno aggiungi oggetti altrimenti segnala errore }

WITHStackDO

IFTop<>MaxStackTHEN

BEGIN

Top:=Top+1;

Items[Top]:=Item;

END

ELSE

writeln(‘Errore: lo stack è pieno’)

END;


StackType 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Items

Top

PROCEDURE Pop(VAR Stack:StackType);

{se lo stack non è vuoto elimina il primo oggetto altrimenti segnala errore}

BEGIN

WITHStackDO

IFTop<>0THEN

Top:=Top-1

ELSE

writeln(‘Errore: lo stack è vuoto)

END;

{ fine della sezione IMPLEMENTATION }


Constructor 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Primitive constructor - assegna un valore ad una variabile astratta senza fare uso di altre variabile astratte dello stesso tipo. Ha una sola variabile di output e quelle di input servono per costruire l’output.

PROCEDURE MakeStack(VAR Stack:StackType);

{ inizializza lo stack vuoto }

Ogni ADT richiede almeno un Primitive constructor così che il client può assegnare un valore iniziale alla variabile astratta.

Non-primitive constructor -. Ha almeno una variabile di input e il cui tipo è uguale a quello dell’output.

Es.

PROCEDURE Push(Item:ItemType; VAR Stack:StackType);

{ se lo stack non è pieno aggiungi oggetti altrimenti segnala errore }


SELECTOR 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili. - fornisce informazioni su una variabile di input ADT ad un parametro di uscita. Spesso è una funzione (il parametro di uscita in tal caso è la funzione stessa).

Primitive selector - ritorna il valore di uno dei componenti della variabile astratta. Es.

FUNCTION StackTop(VAR Stack:StackType): ItemType;

{se lo stack non è vuoto la funzione assume il valore dell’oggetto al top dello stack , in mancanza assume valore nullo chr(0)}

Ogni unit necessita di una Primitive selector altrimenti il client non può mostrare i valori della variabile.


Non-primitive selector 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili. - ritorna il valore che non è relativo ad uno dei componenti della variabile astratta ma ciò nonostante è utile al client.

NESSUNA


PREDICATE 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili. - è una funzione booleana che ritorna informazioni sul valore o lo stato di una variabile astratta.

FUNCTION StackEmpty(VAR Stack:StackType; ):boolean;

{ vera se non ci sono oggetti nello stack }

FUNCTION StackFull(VAR Stack:StackType; ):boolean;

{ vera se lo stack è pieno }


Alcuni commenti 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Si noti che sia nella unit della QUEUE che in quella degli STACK abbiamo adoperato una variabile ItemType per indicare il tipo di oggetti che volevamo trattare con le nostre strutture.

Questo sistema ci permette di modificare in maniera molto semplice le due Unit nel momento in cui volessi trattare integer invece che stringhe o real invece che caratteri. Non è però sufficiente la modifica del solo ItemType in alcune funzioni o procedure, ad esempio quelle di controllo dell’errore.

La scelta di usare nelle FUNCTION la call per VAR invece che per valore pur se questa scelta impegna più memoria però in compenso la chiamata avviene in un tempo di complessità pari a O(1) invece che O(N).


ESEMPIO N.1 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Assegnato un file contenente stringhe di caratteri riscrivere, rigo per rigo, il file con i caratteri in ordine inverso.

Esempio:

Oggi è una bella giornata

che diventa

atanroig alleb anu è iggo

Soluzione

Leggere il file carattere per carattere e introdurre i singoli caratteri, nell’ordine in cui appaiono in uno stack.

Il contenuto dello stack a partire dal Top andando verso sinistra sarà la risposta al nostro problema.


Pseudo Codice 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

MakeStack(ChStack) {inizializza uno stack vuoto}

WHILE NOT eoln DO

read(Ch)

push Ch in ChStack

readln

WHILE ChStack non è vuoto DO

mostra il valore di Ch nel Top

pop il valore di Ch dal Top dello Stack

writeln


PROGRAM 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili. InvertiRigo(input,output);

{documentazione}

USES Stack;

VAR

ChStack:StackType

Ch:char {carattere da inserire o eliminare dallo stack}

BEGIN

MakeStack(ChStack);

WHILE NOT eoln DO

BEGIN

read(Ch);

Push(Ch,ChStack);

END;

readln;

WHILE NOT StackEmpty(ChStack) DO

BEGIN

Ch:=StackTop(ChStack);

Pop(ChStack);

write(Ch)

END;

writeln;

END.


ESEMPIO N. 2 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Assegnata una espressione contenente parentesi controllare che l’apertura e chiusura di queste sia bilanciata.

Supponiamo che le parentesi siano del tipo:

Aperta Chiusa

{ }

[ ]

( )

Esempio

{a+[ b*c - (d-a) ]+d}

Re:=sqrt(sqr(A[3,5]+33)


Soluzione 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Si legge la stringa contenente le parentesi. Quando appare una parentesi aperta si inserisce in uno stack.

Non appena appare la prima parentesi chiusa si confronta questa con la parentesi contenuta nel Top dello Stack. Se le parentesi sono uguali si prosegue altrimenti si dichiara che le parentesi non sono ben bilanciate.

Pseudo Codice

MakeStack(ChStack)

Bilanciato  TRUE

FOR Posizione  1 TO lenght(Linea) DO

Ch  Linea[Posizione]

IF Ch è una parentesi aperta THEN

Push(Ch,ChStack)

ELSE IF Ch è una parentesi chiusa THEN

IF NOT Matched(StackTop(ChStack),Ch) THEN

Bilanciato  FALSE

Pop(ChStack)

Linea Bilanciata  Bilanciato AND StackEmpty(ChStack)


FUNCTION Matched(LeftCh, RightCh:char):boolean; 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

{ritorna vero se la parentesi aperta e

quella chiusa sono dello stesso tipo}

BEGIN

Matched:= (LeftCh=‘{‘) AND (RightCh=‘}’) OR

(LeftCh=‘[‘) AND (RightCh=‘]’) OR

(LeftCh=‘(‘) AND (RightCh=‘)’)

END;


FUNCTION 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.LineaBilanciata (Linea:LineString):boolean;

{ritorna vero se la parentesi aperte e chiuse sono bilanciate}

VAR

Posizione:1..80;

Ch:char;

Bilanciato : boolean;

ChStack: StackType;

BEGIN

MakeStack(ChStack);

Bilanciato :=TRUE;

FOR Posizione:=1 TO lenght(Linea) DO

BEGIN

Ch:=Linea[Posizione];

IF Ch IN [‘{‘,’[‘,’(‘] THEN

Push(Ch,ChStack)

ELSE IF Ch IN [‘}’, ’], ‘,’)‘] THEN

BEGIN

IF NOT Matched(StackTop(ChStack),Ch) THEN

Bilanciato :=FALSE;

Pop(ChStack)

END;

END;

BalancedLine:= Bilanciato AND StackEmpty(ChStack)

END;


ESEMPIO PROCEDURE ANNIDATE 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Proc A

Proc B

Proc C

…………….

Proc B

Proc A


Esercizio 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Dato un numero verificare se esso è palindromo.

Si definisce palindromo un numero (o stringa) che può essere letto indifferentemente da sinistra verso destra e da destra verso sinistra.

Es. 1232442321 7659567

Un numero (o stringa) palindromo si dice pari se il numero delle cifre (caratteri) che lo compongono è pari, dispari altrimenti.

Esercizio

Addizionare due numeri interi di grandezza superiore a 215 .


Un suggerimento 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Quando si scrivono delle ADT invece di inserire scritte che ne controllino la correttezza di funzionamento è opportuno inserire in esse funzioni o procedure aventi lo stesso scopo così da poterle utilizzare anche dopo che la Unit è stata compilata per ulteriori controlli.


Primo progetto intercorso 1 e 9. Se si supera 9 e nelle posizioni da 1 a indice di Head c’è ancora posto allora gli indici di Head e Tail devono adeguatamente modificarsi per sfruttare sempre tutti gli spazi disponibili.

Simulare l’attività di un distributore automatico di generi alimentari in cui sono in vendita prodotti con data di scadenza.

Siano tre le linee di prodotti: A, B, C.

I prodotti A possono rimanere nel distributore 3 giorni

I prodotti B possono rimanere nel distributore 5 giorni

I prodotti C possono rimanere nel distributore 4 giorni

I prodotti vengono dati al pubblico in funzione della data di scadenza, prima quelli più antichi.

Simulare il caricamento di ogni prodotto con un massimo numero di pezzi (maxA, maxB, maxC).

Simulare la vendita dei tre prodotti con segnalazione di fine prodotto.

Simulare la raccolta a fine settimana dei prodotti scaduti tenendo presente che essi vanno riconsegnati a diversi distributori. Poiché i distributori sono in luoghi diversi verranno caricati sui camion prima i prodotti di tipo B, poi quelli C e infine quelli A.

Simulare infine la consegna dei prodotti ai distributori.


ad