Esercizi del 21/10/2021⚓︎
Esercizio 1⚓︎
Leggere in input due interi \(n, k > 0\) e calcolare i primi \(n\) multipli di \(k\). Realizzare l'algoritmo in pseudo-codice, considerando i controlli sull'input.
Esempio:
Dati \(n = 3\) e \(k = 4\), i primi \(3\) multipli di \(4\) sono \(4, 8, 12\).
- INPUT:
- \(n\) – numero di multipli di \(k\) da calcolare, \(n \in \N^\ast\)
- \(k\) – numero di cui calcolare gli \(n\) multipli, \(n \in \N^\ast\)
- OUTPUT:
multipli
– Insieme di \(n\) multipli di \(k\), insieme di naturali, cardinalità \(n\).
ALGORITMO
Bozza | |
---|---|
Il precedente non è un algoritmo ma, come sempre, un'idea di come risolvere il problema. Il controllo, come accennato, è possibile effettuarlo in due modi.
Bisogna rendere chiari i vincoli, magari con un messaggio che li specifichi o che chiarisca il comportamento aspettato. Poiché vengono richiesti due valori positivi dando in input, ad esempio, \(5, -1\) l'algoritmo tornerebbe al primo punto e richiederebbe entrambi i numeri, nonostante il primo fosse corretto. Sarebbe quindi consigliato controllare ogni dato separatamente.
Bozza, v2b.1 | |
---|---|
In questo modo vengono evitate operazioni inutili. Dunque, traducendo:
Algoritmo, v1 | |
---|---|
Con questa sintassi l'algoritmo non procede finché non riceve i dati corretti in input, per questo è possibile aggiungere un messaggio che renda noto che il valore di \(n\) o di \(k\) è errato.
Una possibile alternativa sarebbe:
Algoritmo, v1a | |
---|---|
Dal punto di vista dell'efficienza, questo algoritmo è migliore. Inoltre
rimuove il problema di assegnare dei valori sia ad \(n\) che a \(k\). Entrambe le
soluzioni sono valide, ma in questo caso è preferibile utilizzare il blocco
ESEGUI [...] FINCHÉ
.
Dopo aver migliorato la struttura di controllo, ora è necessario specificare
cosa significhi calcolare i multipli
. Bisogna calcolare \(n\) volte i multipli
di \(k\) e poiché è presente una ripetizione è necessario usare un'iterazione.
Dunque:
Calcolo dei multipli | |
---|---|
Attenzione
una cosa che non è possibile fare è la seguente
poiché multipli
è un insieme e non un singolo elemento. Questo significa
che bisogna assegnare un valore in una posizione specifica.
Bisogna ora specificare il messaggio da mostrare nel caso in cui vengano inseriti dei dati non corretti.
Nel C sono presenti funzioni che permettono di stampare a video ciò che si
desidera (printf()
), nello pseudo-codice scriveremo StampareAVideo()
,
quindi, ad esempio:
Leggere in input
Per leggere dei dati in input, il C offre la funzione scanf()
, in
pseudo-codice useremo LeggereDaTastiera()
. In questo modo il programma
si blocca finché non riceve un dato in input.
Mettendo tutto insieme si ottiene:
Esercizio 2⚓︎
Leggere in input due interi \(n,k > 0\) e verificare se \(n\) è divisibile per \(k\). Realizzare l’algoritmo in pseudo-codice, considerando i controlli sugli input.
Esempio: Dati \(n = 3\) e \(k = 4\), \(n\) non è divisibile per \(k\).
- INPUT:
- \(n\) - numero di cui verificare la divisibilità per \(k\), \(n \in \N^\ast\)
- \(k\) - numero di cui verificare se sia divisore di \(n\), \(k \in \N^\ast\)
- OUTPUT:
- divisibile - indica se \(n\) sia divisibile (vero) o meno (falso) per \(k\), booleano
La prima bozza di questo algoritmo è molto simile a quella del'algoritmo dell'esercizio precedente, l'unica differenza consiste nel verificare la divisibilità anziché calcolare i multipli.
Algoritmo, v1 | |
---|---|
Nel caso in cui il resto (ovvero il modulo) sia zero, allora \(n\) è divisibile
per \(k\). Ma com'è di preciso definita l'operazione modulo
? Va specificata.
È possibile risolvere il problema senza utilizzare l'operazione modulo
facendo
uso di sottrazioni ripetute. Nel caso in cui il risultato sia zero allora non
è presente resto, se invece il risultato fosse maggiore di zero, allora il
resto è presente.
Algoritmo, v2 | |
---|---|
In questo algoritmo si va a perdere il valore di \(n\) e sarebbe meglio
preservarlo utilizzando una variabile come temp
.
È importante notare come la prima versione dell'algoritmo nel caso in cui venga
tradotto in un linguaggio che non possegga l'operazione modulo
, l'esecutore
non saprebbe come fare. Dunque o si risolve il problema in maniera differente,
oppure si specifica cosa fa l'operazione modulo
.
Abbiamo dato per scontato che esista una funzione
il che non è sempre vero ed è quindi un errore.