Per la soluzione di un certo problema disponiamo di un algoritmo iterativo con costo computazionale
Ci viene proposto in alternativa un algoritmo ricorsivo il cui costo è catturato dalla seguente ricorrenza:
Dove a è una certa costante intera positiva con
Determinare qual'è il valore massimo che la costante intera a può avere perchè l’algoritmo ricorsivo risulti asintoticamente più efficiente dell’algoritmo iterativo di cui disponiamo. Motivare bene la vostra risposta.
Generalizzando la ricorrenza in
vengono individuati
Per ogni
Fino a quando
Il valore massimo che la costante intera a potrà assumere affinchè l’algoritmo ricorsivo risulti asintoticamente più efficiente dell’algoritmo iterativo sarà 15.
Sia A un array di n interi.
Con la coppia ordinata
Progettare un algoritmo che, dato un array A di interi positivi ed un intero positivo s, restituisce la coppia ordinata che rappresenta il sottoarray di A più a sinistra che ha valore s.
Se un tale sottoarray non esiste, la funzione deve restituire None.
L’algoritmo deve avere costo computazionale
Ad esempio, per A = [1, 3, 5, 2, 9, 3, 3, 1, 6]
-
con s = 7 l’algoritmo deve restituire la coppia
$(2, 3)$ (ci sono infatti in A tre sottoarray con valore 7 le cui coppie nell’ordine da sinistra a destra sono$(2, 3), (5, 7), (7, 8)$ ). -
con s = 21 l’algoritmo deve restituire None in quanto A non ha sottoarray con valore 21.
Dell’algoritmo proposto:
a) si dia la descrizione a parole;
Si utilizzano due indici i e j per tenere traccia dei 2 estremi del sottoarray corrente ed una variabile somma per tenere traccia della somma tra tutti i suoi elementi.
Partendo dal sottoarray più a sinistra (ovvero quello composto solamente dal primo elemento dell'array), si procederà secondo la seguente logica:
-
viene calcolata la somma del sottoarray corrente
-
se la somma corrente è minore di s, si incrementa j di 1 in modo da aggiungere un nuovo elemento al sottoarray corrente
-
se la somma corrente è maggiore di s, l'indice i verrà incrementato fino a quando la somma del sottoarray risultante non tornerà ad essere minore di s
-
se la somma corrente è uguale a s, si restituisce la coppia ordinata
$(i, j)$ (se non dovesse venire trovata nessuna somma uguale a s, verrá restituito None)
b) si scriva lo pseudocodice;
def es2(A, s):
i = 0
j = 0
somma = 0
while j < len(A):
somma += A[j]
while somma > s:
somma -= A[i]
i += 1
if somma == s:
return (i, j)
j += 1
return None
c) si giustifichi il costo computazionale.
Ad ogni iterazione dei due cicli while, viene incrementato di 1+ almeno uno dei due indici i e j.
Nel caso peggiore in cui non venga trovata alcuna somma uguale a s, entrambi gli indici verranno incrementati fino a raggiungere la lunghezza dell'array A, per un totale di
Si consideri una lista concatenata dove ogni nodo ha 2 campi,
-
il campo key contenente un intero
-
ed il campo next con il puntatore al nodo seguente (next vale None per l’ultimo nodo della lista).
Bisogna aggiornare i puntatori della lista in modo da creare una nuova lista priva dei nodi con valore superiore a 10 e in cui i nodi rimanenti appaiono in ordine inverso rispetto all’originale.
Ad esempio per la lista di seguito a sinistra la funzione deve restituire la lista di seguito a destra:
11 --> 10 --> 3 --> 7 --> 11 --> 12 --> 4 --> 15 4 --> 7 --> 3 --> 10
Progettare un algoritmo che, dato il puntatore p alla testa della lista, risolve il problema in tempo
Lo spazio di lavoro dell’algoritmo proposto deve essere
Dell’algoritmo proposto:
a) si dia la descrizione a parole
Viene inizializzato un puntatore q il quale, al termine della funzione, punterà alla testa della nuova lista.
Iterando la lista originaria, per ogni nodo
-
se la sua chiave ha valore superiore a 10, lo si "elimina" facendo puntare il nodo precedente al successivo del nodo corrente
-
altrimenti, lo si inserisce alla testa della lista punta da q nel seguente modo:
-
si salva il puntatore al nodo successivo del nodo corrente in una variabile temporanea t
-
si fa puntare il nodo successivo del nodo corrente a q
-
si fa puntare q al nodo corrente
-
si fa puntare il nodo corrente a t (ovvero al suo nodo successivo che era stato salvato in precedenza)
-
per quanto possa sembrare confusionario, si può ottenere una rappresentazione visiva di quanto descritto usando strumenti come python tutor
Al termine della funzione, q punterà alla testa della nuova lista e verrà restituito come valore di ritorno.
b) si scriva lo pseudocodice
def es3(p):
q = None
while p != None:
if p.key > 10:
p = p.next
else:
t = p.next
p.next = q
q = p
p = t
return q
c) si giustifichi il costo computazionale
Viene visitata una sola volta tutta la lista, da cui il costo computazionale