Discussione esercizio 30:
#include <stdlib.h>
List insord_elem(List L, Elem *e) {
int val = e->val;
if (L == NULL || val <= L->val) {
e->next = L;
return e;
} else {
Elem *prec = L;
while (prec->next != NULL && (prec->next)->val < val)
prec = prec->next;
e->next = prec->next;
prec->next = e;
return L;
}
}
List insord(List L, int val) {
Elem *e = malloc(sizeof (Elem));
e->val = val;
return insord_elem(L, e);
}
Discussione esercizio 31:
List reverse(List L) {
List R = L;
L = NULL;
while (R != NULL) {
Elem *e = R;
R = R->next;
e->next = L;
L = e;
}
return L;
}
List reverse_r(List L) {
if (L == NULL || L->next == NULL)
return L;
Elem *first = L;
L = reverse_r(L->next);
(first->next)->next = first;
first->next = NULL;
return L;
}
Discussione esercizio 32:
#include "archivio_mem.h"
#include <stdlib.h>
typedef struct DElem {
Dipendente d;
struct DElem *next;
} DElem, *DList;
static DList *archivio = NULL;
static int numDipendenti = 0;
void open_archivio() {}
void add_dipendente(Dipendente d) {
DElem *new = malloc(sizeof(DElem));
new->d = d;
new->next = archivio;
archivio = new;
numDipendenti++;
}
int num_dipendenti() {
return numDipendenti;
}
Dipendente get_dipendente(int i) {
DElem *p = archivio;
while (i > 0) {
p = p->next;
i++;
}
return p->d;
}
void close_archivio() {
while (archivio != NULL) {
DElem *p = archivio->next;
free(archivio);
archivio = p;
}
}
Algoritmo
insertion-sort per ordinare una lista di interi:
List insord_elem(List L, Elem *e);
List insertion_sort(List L) {
List R = L;
L = NULL;
while (R != NULL) {
Elem *e = R;
R = R->next;
L = insord_elem(L, e);
}
return L;
}
Esempio di uso di liste: programma che conta le occorrenze delle parole distinte lette dallo standard
input. Possibilità di usare la redirezione (operatore di redirezione
<
da terminale)
per ridirigere lo standard input da file. Discussione circa i vantaggi della progettazione
top-down
del programma: prima si determina la decomposizione del programma in funzioni, si specifica cosa deve
fare ogni funzione e il relativo prototipo, si scrive il main usando le funzioni in accordo alle specifiche,
e infine si implementano le funzioni.
Il programma usa una lista per mantenere le parole distinte e i relativi conteggi delle occorrenze.
Le specifiche della lista, delle funzioni e il main:
#include <stdio.h>
#include <stdlib.h>
typedef struct WElem {
char * word;
int count;
struct WElem *next;
} WElem, *WList;
char *next_word();
WList wl_add(WList L, char *w);
int wl_count(WList L);
void wl_print(WList L);
void wl_free(WList L);
int main() {
char *word;
WList L = NULL;
while ((word = next_word()) != NULL)
L = wl_add(L, word);
printf("Numero parole distinte: %d\n", wl_count(L));
wl_print(L);
wl_free(L);
}
Implementazione di tutte le funzioni:
#include <ctype.h>
#include <string.h>
char *next_word() {
char *w = NULL;
int c, n = 0;
do {
c = getchar();
if (isalpha(c)) {
w = realloc(w, n + 2);
w[n++] = c;
}
} while (c != EOF && (n == 0 || isalpha(c))) ;
if (w != NULL) w[n] = '\0';
return w;
}
WList wl_add(WList L, char *w) {
WElem *p = L, *last = NULL;
while (p != NULL && strcmp(p->word, w) != 0) {
last = p;
p = p->next;
}
if (p == NULL) {
WElem *new = malloc(sizeof(WElem));
new->word = w;
new->count = 1;
new->next = NULL;
if (last == NULL) L = new;
else last->next = new;
} else
p->count++;
return L;
}
int wl_count(WList L) {
int n = 0;
while (L != NULL) {
L = L->next;
n++;
}
return n;
}
void wl_print(WList L) {
while (L != NULL) {
printf("%4d %s\n", L->count, L->word);
L = L->next;
}
}
void wl_free(WList L) {
while (L != NULL) {
WElem *next = L->next;
free(L->word);
free(L);
L = next;
}
}
Dai siti
Progetto Manuzio e
Project Gutenberg si possono scaricare
tantissimi libri, italiani e stranieri, in file di testo che possono essere dati in input al programma.
Esercizio 33
Scrivere una funzione
WList wl_sort(WList L)
che ordina la lista di parole
L
rispetto al campo
word
e ritorna il puntatore alla lista ordinata.
Esercizio 34
Scrivere una funzione
int wl_equal(WList L1, WList L2)
che ritorna
vero
se le due liste di parole
L1
e
L2
sono uguali. Per uguali si intende che
devono avere la stessa lunghezza e gli elementi in posizioni corrispondenti devono avere lo stesso contenuto.