implementiamo un algoritmo di ordinamento da applicare agli array

Esercizio proposto: implementiamo un algoritmo di ordinamento da applicare agli array di strutture
che funzioni senza scambiare tra loro gli elementi dell’array.
Sia dato un array di strutture di tipo gruppo:
typedef struct{ int numero;
char *stringa;
float valore;} gruppo;
e si supponga di voler fare in modo che le strutture risultino disposte in modo tale che i valori dei membri valore
delle strutture stesse siano disposte in ordine crescente.
Metodo 1:
scorro l’array di strutture e scambio due elementi consecutivi tra loro quando i loro valori non rispettano
l’ordinamento scelto.
In questo modo ottengo l’ordinamento ma ho modificato la posizione degli elementi dell’array
3.5
1.2
-35.1
1.2
39.5
3.5
24.5
24.5
-35.1
39.5
Metodo 2:
definisco una nuova struttura
typedef{gruppo *elemento;} ordine;
e creo un array di strutture di tipo ordine; faccio poi in modo che ogni membro di una struttura di tipo ordine, elemento,
punti ad uno degli elementi dell’array di strutture di tipo gruppo. Faccio in modo di scambiare i valori dei membri
elemento, in modo tale che scorrendo l’array di strutture di tipo ordine sia possibile “vedere” l’array di strutture di tipo
gruppo disposte in modo ordinato. Così facendo non scambio gli elementi dell’array; posso inoltre definire un numero di
array di tipo ordine, in modo da poter implementare un numero arbitrario di ordinamenti contemporanei.
3.5
3.5
1.2
1.2
39.5
39.5
24.5
24.5
-35.1
-35.1
Sia dato un file con la seguente formattazione:
numero totale
di comuni
elencati
CAP
104
66010
66010
66010
66010
66010
66010
66010
.....
Ari
Canosa Sannita
Casacanditella
Civitella Messer Raimondo
Colledimacine
Fara Filiorum Petri
Gessopalena
.....
Definiamo una struttura che serva a memorizzare
tali informazioni:
typedef struct{ int numero;
char *nome_comune;} cap;
nome del comune
Definiamo ora una struttura che serva ad implementare un ordinamento:
typedef struct{cap *elemento;} ordine;
Passiamo ora all’esercizio. Non viene mai richiesto di verificare che le allocazioni di memoria e le aperture dei file
vadano a buon fine perché si dà per scontato che tali operazioni vengano svolte.
Implementazione delle funzioni (si supponga che esista una variabile globale di tipo int, num):
(a) parametri: FILE*in / restituisce: cap*. Leggere un valore di tipo intero dal file cui fa riferimento in e salvare tale valore nella
variabile num; allocare un’area di memoria di dimensione tale da contenere num elementi di tipo cap. Fatto questo
leggere il contenuto di ciascuna riga del file (un intero ed una stringa) e salvare tali valori all’interno di una delle
strutture dell’array appena creato. Restituire l’indirizzo dell’area di memoria in cui si trova l’array.
(b) parametri: cap* elenco / restituisce: ordine*. Allocare un’area di memoria sufficiente a contenere num elementi di tipo
ordine; assegnare al membro elemento di ciascuna delle strutture di questo array l’indirizzo della corrispondente struttura
all’interno dell’array cui fa riferimento elenco. Restituire l’indirizzo dell’area di memoria allocata.
(c) parametri: ordine*valori / restituisce: void. valori rappresenta il puntatore ad un array di strutture di tipo ordine; per
ciascuna struttura di tale array, visualizzare il valore dei campi numero e nome_comune che si trovano nella struttura di
tipo cap cui punta il membro elemento.
(d) parametri: ordine *tmp / restituisce: void. tmp rappresenta il puntatore ad un array di strutture di tipo ordine;
disporre i valori dei membri elemento di ciascuna delle strutture di tale array in modo tale che i membri numero
delle strutture di tipo cap cui essi fanno riferimento siano disposti in ordine crescente.
(e) parametri: ordine *tmp / restituisce: void. tmp rappresenta il puntatore ad un array di strutture di tipo ordine;
disporre i valori dei membri elemento di ciascuna delle strutture di tale array in modo tale che i membri
nome_comune delle strutture di tipo cap cui essi fanno riferimento siano disposti secondo l’ordine alfabetico.
Per implementare tale funzionalità utilizzare la funzione: int strcmp(char *str1,char *str2) definita in string.h. La
funzione restituisce un numero negativo se, secondo l’ordine alfabetico, str1 viene prima di str2, restituisce 0 se
str1 e str2 coincidono e restituisce un numero positivo se, secondo l’ordine alfabetico, str2 viene prima di str1.
(f) parametri: cap*elenco,FILE* out / restituisce: void. elenco rappresenta il puntatore ad un array di strutture di tipo
cap. Scorrere tale array e, per ogni valore del membro numero, salvare in ciascuna riga del file il valore di tale
variabile e, a fianco, il numero di comuni cui corrisponde quel valore del codice cap.
Facoltativo: modificando il prototipo della funzione definita al punto (d), o di quella definita al punto (e), fare in modo
di creare una nuova funzione che serva ad applicare un qualsiasi tipo di ordinamento, e la cui implementazione non
dipenda dal tipo di ordinamento che si sceglie di applicare.
Implementazione di main():
(1) implementare main() in modo tale che il programma possa accettare parametri da linea di comando; in totale ci si deve
aspettare che l’utente inserisca 2 parametri (oltre al nome del programma): il primo rappresenta il nome di un file da
leggere mentre il secondo rappresenta il nome di un file in cui scrivere dei dati.
(2) aprire in modalità lettura il file il cui nome è contenuto nel primo parametro passato dall’utente a main();
richiamare la funzione descritta al punto (a) usando come parametro il puntatore a tale file. Memorizzare il valore
restituito dalla funzione in una variabile di nome elenco.
(3) richiamare la funzione definita al punto (b), passandole elenco come parametro e memorizzare il valore restituito
in una variabile di nome OrdNum. Richiamare nuovamente la medesima funzione con lo stesso parametro e
memorizzare il valore restituito nella variabile OrdStr.
(4) richiamare la funzione definita al punto (d) passandole come parametro OrdNum.
(5) richiamare la funzione definita al punto (c) passandole come parametro OrdNum.
(6) richiamare la funzione definita al punto (e) passandole come parametro OrdStr.
(7) richiamare la funzione definita al punto (c) passandole come parametro OrdStr.
(8) aprire il file il cui nome è contenuto nel secondo parametro passato dall’utente a main(); richiamare la funzione
definita al punto (f) passandole come parametri il puntatore a tale file ed elenco.
(9) servendosi della funzione definita al punto (f), visualizzare le informazioni che al punto (8) sono state salvate su file.
(10)chiudere tutti i file, disallocare le aree di memoria allocate in modo dinamico e poi terminare il programma.