Anteprima
Vedrai una selezione di 4 pagine su 13
Tipi aggregati - Algoritmi e strutture dati Pag. 1 Tipi aggregati - Algoritmi e strutture dati Pag. 2
Anteprima di 4 pagg. su 13.
Scarica il documento per vederlo tutto.
Tipi aggregati - Algoritmi e strutture dati Pag. 6
Anteprima di 4 pagg. su 13.
Scarica il documento per vederlo tutto.
Tipi aggregati - Algoritmi e strutture dati Pag. 11
1 su 13
D/illustrazione/soddisfatti o rimborsati
Disdici quando
vuoi
Acquista con carta
o PayPal
Scarica i documenti
tutte le volte che vuoi
Estratto del documento

Esempio: bag of integer: {1, 1, 3, 5, 5, 5}, in questo caso abbiamo due

istanze dell’elemento etichettato 1 e 3 istanze dell’elemento

etichettato 5. Gli elmenti in se sono indistinguibili: tutti i 5 sono uguali

ma ne ho 3.

Una possibile implementazione del bag è con i contatori, ad esempio

l’elemento 1 è presente 2 volte, se un elemento è presente 0 volte vuol

dire che non c’è, non fa parte del bag. Il fatto di tenere il conto di

quanti elementi ho di un certo valore ci permette anche qui di avere

rappresentazioni compatte.

Sui bag vengono definite le operazioni:

·8 Operatori di insiemi: c’è una leggera variante, infatti le

operazioni come quelle di unione e di intersezione tra due bag

vengono interpretate come operazioni di minimo e massimo, per

cui se io faccio l’unione di due bag, prendo gli elementi che ci

sono con il conteggio massimo, cioè se un bag contiene un

elemento che vale 1 e un altro ne contiene 2, l’unione ne

contiene 2, l’intersezione contiene invece il minimo

·9 Uguaglianza:

La struttura bag ci permete di capire quanti elementi dello stesso

valore sono presenti in una certa collezione quando non ci interessa

distinguere i singoli elementi, non hanno un’identità individuale ma

sono tutti interscambiabili.

L’ordinamento non è rilevante.

Le bag hanno un’importante applicazione nell’interpretazione

semantica dei testi, cioè capire i testi, quindi vengono ad esempio

utilizzate per le mail, o per capire se i luoghi da visitare sono belli o

meno

Sequence

SEQUENZE OF <BASE_TYPE>

La sequenza è un tipo omogeneo, quindi fatto di oggetti base dello

stesso tipo, i cui valori sono sequenze ordinate.

Stiamo aggiungendo elementi di aggregazione, infatti il set non ha

ordinamento e non conta il numero di volte in cui compaiono gli

elementi. Il bag non ha ordinamento ma conta il numero di elementi

uguali che ci sono. La sequenza non conta di per se ma considera

l’ordine e gli elementi possono avere lo stesso valore.

L’ordinamento è riferito all’ordine degli elementi, non ai valori,

l’ordinamento che c’è sui valori è un’altra cosa, l’ordinamento delle

sequenze è quello imposto dalla creazione della sequenza. Quindi

l’ordinamento delle sequenze lo imponiamo noi nel momento in cui

mettiamo i valori.

Esempio: Sequenze of integer: (1, 3, 2, 4, 1, 5) che è diverso da (1, 1,

2, 3, 4, 5)

Come nel bag due elementi possono avere l stesso valore, ma sono

elementi distinti.

Vedremo che ci sono algoritmi di ordinamento che hanno il compito di

riordinare una sequenza partendo dall’ordinamento che ha in input e

ottenendo una sequenza di uscita dove l’ordinamento della sequenza e

quello dei tipi base coincidono, quindi in questo caso diventerebbe (1,

1, 2, 3, 4, 5), cioè l’ordinamento che io ho imposto alla sequenza e

l’ordinamento che la sequenza avrebbe se io considerassi la relazione

d’ordine del tipo base vengono a coincidere.

Vediamo le operazioni sulle sequenze:

·10 isEmpty: è una domanda che ci dice se la sequenza è vuota

e non contiene elementi. La sequenza che non contiene elementi

è una sequenza.

·11 Head/Tail: Head è l’elemento che viene per primo

nell’ordine che io ho imposto, Tail è l’ultimo elemento che io ho

aggiunto alla coda

·12 First/Next: First è l’elemento a cui sono arrivato e next è il

successivo, è un iteratore, cioè una funzione che ha uno stato,

che sa dove è arrivata nella sequenza e permette di andare a

individuare l’elemento successivo sapendo l’elemento corrente

della sequenza. Questo serve ad accelerare l’esecuzione di molti

algoritmi che diversamente dovrebbero visitare nuovamente una

sequenza dall’inizio cioè enumerare tutti gli elementi nell’ordine

naturale di quella particolare struttura dati, nel caso delle liste

l’ordinamento è quello in cui vengono scritti gli elementi. La

visita di una struttura dati produce una sequenza. Questa

operazione di visita e produzione di sequenze, in alcuni linguaggi

è detta serializzazione, cioè se io visito una struttura dati in un

ordine particolare produco una sequenza che è l’equivalente

serializzato di quella struttura dati. L’utilità di una visita con

serializzazione è che io posso prendere una struttura dati

complessa, che può avere più dimensioni, e la trasformo in una

struttura monodimensionale, questo è un modo per generare dei

file che sono strutture seriali intrinsecamente sequenziali, un file

ha infatti una sequenza di elementi. Ovviamente esiste anche la

deserializzazione che è l’operazione inversa, cioè parto da un file

e costruisco di nuovo la struttura non serializzata.

La serializzazione è in generale una operazione semplice, la

deserializzazione (parsing) è invece molto complicata

·13 Equal: uguaglianza

·14 Empty

·15 Estrazione di prefissi, cioè dall’inizio fino a un certo punto

·16 Estrazione di suffissi, cioè da un certo punto fino alla fine

·17 sottosequenze, cioè pezzi di sequenza che si trovano da

una posizione a un’altra posizione

Nella teoria generale dell’elaborazione dei testi si definiscono

sottostringhe le sottosequenze che si trovano esattamente uguali

nella stringa originale, cioè nell’esempio fatto (3, 2, 4, 1) è una

sottostringa di simboli, invece si chiamano sottosequenze le

sequenze che compaiono nella sequenza originale ma

possibilmente con dei buchi, quindi se io considero la

sottosequenze (3, 4, 5) è una sottosequenza e non è una

sottostringa, è una sottosequenza perché gli elementi compaiono

nella stringa originale nello stesso ordine, però ci sono dei buchi

in mezzo, quindi non è una sottostringa.

Nell’eleborazione dei testi è importante distinguere sottostringhe

e sottosequenze perché una sottostringa deve esistere uguale a

una stringa originale.

Se voglio fare una ricerca spesso non sono interessato alle

sottostringhe ma alle sottosequenze perché le sottosequenze si

trovano nello stesso testo originale ma possibilmente con delle

varianti.

L’utilizzo della sottostringa va bene se siamo certi che non ci

sono errori o varianti nel testo originale, altrimenti si ricorre alla

sottosequenza o sottostringa approssimata, quindi qualcosa che

va abbastanza vicino

·18 Append: aggiunta elementi alla fine

·19 Togliere elementi all’inizio o alla fine della sequenza.

Quando tolgo un elemnto la sequenza di accorgia, se aggiungo

l’elemento si allunga. Ogni elemento che io aggiungo o tolgo da

una sequenza ne modifica la lunghezza, cioè il size cioè il

numero di elementi di quella sequenza.

Lo standard considera le sequenze come tipi aggregati omogenei, che

vuol dire tutti gli elementi base hanno lo stesso tipo, i linguaggi di

programmazione spesso consentono una generalizzazione delle

sequenze in cui i tipi base possono avere elementi diversi, un esempio

è proprio il linguaggio python: una lista in python, che è proprio di fatto

una sequenza, può essere fatta da oggetti di tipo diverso, questo ha

senso perché così questa struttura è molto più flessibile, quello che

rimane della sequenza è: eliminiamo il vincolo che sia una struttura

omogenea ma il resto è sempre come prima: esiste un ordinamento

che è quello di costruzione e posso andare a individuare elementi

all’interno della lista, togliere elementi, aggiungere elementi dove

voglio nella sequenza.

Esiste una categoria molto importante di sequenze che sono le

sequenze di caratteri, le chiameremo stringhe, quindi una stringa di

caratteri è una sequenza di caratteri, è così importante che le stringhe

esistono come tipo nativo in molte architetture di macchina.

Array

ARRAY <INDEX_TYPE> OF <BASE_TYPE>

Di solito si pensa all’array come array di numeri, come A[i] dove i è un

intero.

L’array è in realtà un tipo fatto da elementi omogenei, quella del tipo

base, quindi array di record, ed è un sottoinsieme del prodotto

cartesiano tra un insieme finito detto indice e il tipo base.

Esempio: array [1:4] of integer ((1, 56), (2, 35), (3, 77), (4, 78))

In questo caso il tipo base è [1:4] cioè il sottocampo di interi che va da

1 a 4, è un tipo finito ed è fondamentale che sia così. L’array mette in

collegamento gli interi, che sono invece uno spazio molto ampio, e

questo tipo base, avrò quindi i seguenti 4 elementi: (1, 56), (2, 35), (3,

77), (4, 78), quindi abbiamo che come primo valore da 1 a 4 e poi tutte

le altre possibili combinazioni, ma l’array che consideriamo è un

elemento del prodotto cartesiano, cioè un sottoinsieme particolare.

Quindi l’array in se mappa un insieme finito su un insieme

potenzialmente infinito (che non può essere infinito nella macchina ma

potenzialmente molto numeroso).

Il tipo astratto non ha in se una nozione di ordinamento dell’indice,

cioè 1, 2, 3, 4 sono ordinati perché gli interi sono ordinati, ma potrei

fare un array indicizzato sugli insiemi rosso, verde e blu, che è un

insieme enumerato e i tipi enumerati non sono ordinati.

Quindi l’array non è ordinato su un indice perché l’indice potrebbe non

avere un ordinamento naturale. L’importante è che sia un sottotipo

finito, cioè che comunque noi possiamo enumerare i valori e mettere in

collegamento il valore del tipo indice con un valore che sta invece nel

tipo base. Gli array sono omogenei.

Se noi poniamo ulteriori restrizioni a queste cose otteniamo

rappresentazioni (con tipi concreti) degli array che possono essere

diverse e più o meno efficienti in termini di tempo di accesso, ad

esempio se limitiamo il tipo indice ad essere un sottotipo intero

abbiamo gli array che sono normalmente implementati nelle macchine,

dove addirittura l’architettura di macchina ci mette a disposizione

l’indirizzamento base più indice e noi a velocità estremamente elevata

riusciamo a individuare l’elemento corrispondente all’indice che

consideriamo, questo è però un caso molto particolare in cui gli indici

sono interi e nel caso delle macchine partono da 0, se lo faccio partire

da 100 ho sprecato 100 elementi di memoria. Se poi andiamo ai tipi

enumerati, ad esempio considerando i colori, allora non abbi

Dettagli
Publisher
A.A. 2023-2024
13 pagine
SSD Scienze matematiche e informatiche INF/01 Informatica

I contenuti di questa pagina costituiscono rielaborazioni personali del Publisher ab502 di informazioni apprese con la frequenza delle lezioni di Algoritmi e strutture dati e studio autonomo di eventuali libri di riferimento in preparazione dell'esame finale o della tesi. Non devono intendersi come materiale ufficiale dell'università Università degli Studi di Pavia o del prof Barili Antonio.