http://www.cplusplus.com/reference/
2 - FUNZIONI
versione 19/12/2012
|
Costruire un programma che generi una sequenza di numeri casuali (da 2 a 100) ed evidenzi tra questi quelli che sono primi. Il test sui numeri deve essere svolto da una funzione.
|
|
SOLUZIONE:
/**************************************************************************
* Nome: lab1-primi.c *
* Autore: Alessandro Saetti *
* Data: 30/3/11 *
**************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#define DIM 10
/* FUNZIONE
* Nome: primo
* Scopo: Determina se un dato intero e' primo
* Input: int n: l'intero che di intende esaminare
* Output: true se n e' primo, false altrimenti
*/
bool primo(int n)
{
for (int i=2 ; i < n ; i++ )
if (n%i==0) return false;
return true;
}
/*
* Nome: main
* Scopo: Inizializza un vettore di DIM variabili intere con dati interi
* pseudo-casuali compresi tra 2 e 100. Visualizza i dati interi primi
* contenuti nel vettore in ordine contrario.
* Input: --
* Output: 0 se il programma termina correttamente
*/
int main()
{
int x, primi[DIM]={0}, n = 0, i;
// INIZIALIZZAZIONE + ALGORITMO
printf("Numeri generati:\n");
for ( i=0; i < DIM; i++ )
{
x = rand() % 99 + 2;
printf("%5d", x);
if (primo(x))
primi[n++] = x;
}
// OUTPUT
printf("\nI numeri primi sono:\n");
for (i = n - 1; i >= 0; i--)
printf("%5d", primi[i]);
printf("\n\n");
// metto in stop il programma prima della sua chiusura
system("pause");
return 0;
}
|
Costruire un programma che legge la sequenza di numeri interi posti sulla linea di comando e mostri a video, per ogni numero pari della sequenza,
due numeri primi la cui somma coincide con il numero analizzato.
PS: L'esercizio prende spunto dalla congettura di Goldbach che è uno dei più vecchi problemi irrisolti nella teoria dei numeri.
Essa afferma che ogni numero pari >= 2 può essere scritto come somma di due numeri primi (che possono essere anche uguali).
|
|
SOLUZIONE:
NOTE:
I parametri di linea possono essere passati utilizzando l'apposito menu

int atoi ( const char * str ); => Analizza il parametro str, che è di tipo stringa, e lo interpreta come numero intero. Tale valore viene poi restituito
come int dalla funzione stessa. Se non è possibile effettuare una conversione allora la funzione restituisce 0.
Non ci sono specifiche standard sul comportamento della funzione quando il valore intero convertito non rientra nel range del tipo int. La funzione strtol rappresenta
una più valida cross-platform alternativa quando questo è possibile. Richiede <stdlib.h>.
/**************************************************************************
* Nome: lab2-goldbach.c *
* Autore: Alessandro Saetti *
* Data: 30/3/11 *
**************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#define DIM 10
/* FUNZIONE
* Nome: primo
* Scopo: Determina se un dato intero e' primo
* Input: int n: l'intero che di intende esaminare
* Output: true se n e' primo, false altrimenti
*/
bool primo(int n)
{
for (int i=2 ; i < n ; i++ )
if (n%i==0)
return false;
return true;
}
/* FUNZIONE
* Nome: primi
* Scopo: Calcola una coppia di numeri primi la cui somma e' pari ad un dato intero n
* Input: int n: l'intero che di intende esaminare
* int *p1: un puntatore al primo numero primo calcolato
* int *p2: un puntatore al secondo numero primo calcolato
* Output: -- poichè si ritiene vera la congettura di Goldbach non occorre restituire TRUE o FALSE.
*/
void ScomponiSommaPrimi(int n, int *p1, int *p2)
{
int i;
for (i = 2; i < n; i++)
{
if ( primo(i) && primo(n-i) )
{
*p1 = i;
*p2 = n - i;
return;
}
}
}
/*
* Nome: main
* Scopo: Inizializza una matrice di DIM righe e 2 colonne con i numeri primi
* la cui somma e' pari ai numeri pari specificati tramite la linea di
* comando
* Input: int argc: il numero di argomenti presenti sulla linea di comando + 1
* char *argv: le stringhe corrispondenti agli argomenti specificati
* Uso: comando n1 n2 ... ni
* Output: 0 se il programma termina correttamente
*/
int main(int argc, char *argv[])
{
int i, x, m[DIM][2], n = 0;
// Scorro gli argomenti sulla linea di comando
for (i = 1; i < argc; i++)
{
x=atoi(argv[i]);
// Se x è pari ricerco i due numeri primi la cui somma
// restituisce x.
if (x % 2 == 0)
{
ScomponiSommaPrimi(x, &m[n][0], &m[n][1]);
n++;
}
}
for (i = 0; i < n; i++)
printf("%d=%d+%d\n", m[i][0]+m[i][1], m[i][0], m[i][1]);
system("pause");
return 0;
}
|
Costruire un programma che genera una sequenza di frazioni (memorizzate in una array bidimensionale
dove gli elementi sulla colonna 0 rappresentano il numeratore mentre quelli sulla colonna 1 il denominatore delle frazioni) e visualizza e stampa a video le frazioni ridotte ai minimi termini.
|
|
SOLUZIONE:
NOTE:
int rand() => Restituisce un numero intero casuale tra 0 e RAND_MAX. Il valore RAND_MAX dipende dalla libreria. Vale almeno 32767. Richiede <stdlib.h>.
void srand ( unsigned int seed ); => Inizializza il generatore di numeri casuali. Richiede <stdlib.h>. Usando come argomento time(NULL) facciamo variare il seme (seed) in funzione del tempo e di conseguenza anche le sequenze generate.
time_t time ( time_t * timer ); => Restituisce l'orario corrente come oggetto time_t e lo registra anche nel parametro *timer (se questo non è posto a NULL!).
Il tipo time_t restituito dalla funzione time() è un numero intero che contiene il numero di secondi trascorsi dalle 00:00 del 1 gennaio 1970 (corrisponde al timestamp di unix). In questo modo la rappresentazione del tempo consente di effettuare delle operazioni aritmentiche. Richiede <time.h>.
/**************************************************************************
* Nome: lab3-mcd.c *
* Autore: Alessandro Saetti *
* Data: 30/3/11 *
**************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#include <time.h> // Richiesta da time(NULL);
#define DIM 10
/* FUNZIONE
* Nome: MCD
* Scopo: Calcola il massimo comune divisore di 2 dati interi
* Input: int n1, n2: i due interi di cui si intende calcolare il MCD
* Output: il MCD calcolato
*/
int MCD(int n1, int n2)
{
int i, min, MCD;
min=(n1 < n2 ? n1 : n2);
for (MCD=min ; ((n1%MCD)+(n2%MCD))>0 ; MCD--);
return MCD;
}
/*
* Nome: main
* Supponendo che le colonne della matrice rappresentino il numeratore
* ed il denominatore di frazioni, stampa a video le frazioni ridotte
* ai minimi termini
* Input: -
* Output: 0 se il programma termina correttamente
*/
int main()
{
int m[DIM][2], i, d;
// INIZIALIZZAZIONE - INPUT
// Inizializza la prima colonna di una matrice di DIM righe con dati
// pseudo-casuali interi compresi tra 10 e 100 e la seconda colonna
// con dati pseudo-casuali compresi tra la prima colonna e 100.
srand(time(NULL));
for (i = 0; i < DIM; i++)
{
m[i][0] = rand() % 91 + 10;
m[i][1] = rand() % (100 - m[i][0] + 1) + m[i][0];
}
for (i = 0; i < DIM; i++)
{
d=MCD(m[i][0],m[i][1]);
printf("%d^ Frazione ridotta di %d/%d => %d/%d\n",i+1,
m[i][0], m[i][1], m[i][0]/d, m[i][1]/d);
}
system("pause");
return 0;
}
|
Costruire una funzione che inizializza gli elementi di un vettore (passato come parametro) con una sequenza di numeri casuali. I valori min e max generabili devono essere parametri della nostra funzione.
Ogni vettore è una riga di una matrice NxM. Costruire poi la funzione che stampa il contenuto di un vettore (la dimensione deve essere uno dei parametri). Infine
costruire la funzione che, dato un vettore, restituisca la somma degli elementi pari. Sfruttando le precedenti funzioni costruire il programma che
inizializza una matrice NxM, la stampa ed infine mostra per ogni riga la somma dei suo elementi pari.
|
|
SOLUZIONE:
NOTE:
int rand() => Restituisce un numero intero casuale tra 0 e RAND_MAX. Il valore RAND_MAX dipende dalla libreria. Vale almeno 32767. Richiede <stdlib.h>.
void srand ( unsigned int seed ); => Inizializza il generatore di numeri casuali. Richiede <stdlib.h>. Usando come argomento time(NULL) facciamo variare il seme (seed) in funzione del tempo e di conseguenza anche le sequenze generate.
time_t time ( time_t * timer ); => Restituisce l'orario corrente come oggetto time_t e lo registra anche nel parametro *timer (se questo non è posto a NULL!).
Il tipo time_t restituito dalla funzione time() è un numero intero che contiene il numero di secondi trascorsi dalle 00:00 del 1 gennaio 1970 (corrisponde al timestamp di unix). In questo modo la rappresentazione del tempo consente di effettuare delle operazioni aritmentiche. Richiede <time.h>.
/**************************************************************************
* Nome: lab1-somma_pari.c *
* Autore: Alessandro Saetti *
* Data: 23/3/10 *
**************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#include <time.h> // Richiesta da time(NULL);
#define N 10
#define M 5
/*
* Nome: inizializza
* Scopo: Inizializza un vettore di n interi con numeri casuali compresi tra 1 e 9
* Input: int v[]: vettore dove memorizzo i valori generati
* int n : dimensione del vettore
* int min: minimo numero pseudo-casuale generabile
* int max: massimo numero pseudo-casuale generabile
* Output: -
*/
void Inizializza(int v[], int n, int min, int max)
{
for (int c = 0; c < n; c++)
v[c] = rand() % (max - min + 1) + min;
}
/*
* Nome: stampa
* Scopo: Stampa un vettore di n interi
* Input: int v[]: vettore
* int n: dimensione del vettore
* Output: -
*/
void Stampa(const int v[], int n)
{
for (int c = 0; c < n; c++)
printf("%4d", v[c]);
printf("\n");
}
/*
* Nome: somma_pari
* Scopo: Somma i numeri pari presenti in un vettore v di lunghezza n
* Input: const int v[]: vettore
* int n: dimensione del vettore
* Output: somma dei numeri pari presenti in v
*/
int somma_pari(const int v[], int n)
{
int c, somma;
for (somma=0, c = 0; c < n; c++)
if (v[c] % 2 == 0)
somma += v[c];
return somma;
}
/*
* Nome: main
* Scopo: Stampa le somme dei numeri pari sulle righe di una matrice
* Input: --
* Output: 0 se il programma termina correttamente
*/
int main()
{
int m[N][M], s[N], r;
// INPUT - Inizializzazione
srand(time(NULL));
for (r = 0; r < N ; r++)
Inizializza(m[r],M, 1, 9);
// ALGORITMO
for (r=0; r < N; r++)
s[r] = somma_pari(m[r],M);
// OUTPUT
printf("Matrice iniziale:\n\n");
for (r = 0; r < N ; r++)
Stampa(m[r],M);
printf("\nVettore Somma Pari:\n\n");
Stampa(s,N);
system("pause");
return 0;
}
|
Costruire una funzione che, dato un vettore (riga della matrice) calcoli la somma degli elementi pari e dispari.
Sfruttando questa funzione e riutilizzando le funzioni Inizializza() e Stampa() dell'esercizio 2.5 costruire il programma che
inizializza una matrice NxM, la stampa ed infine mostra per ogni riga la somma dei suoi elementi pari e dispari.
|
|
SOLUZIONE:
/**************************************************************************
* Nome: lab2-sommapari_dispari.c *
* Autore: Alessandro Saetti *
* Data: 23/3/10 *
**************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#include <time.h> // Richiesta da time(NULL);
#define N 10
#define M 5
/*
* Nome: inizializza
* Scopo: Inizializza un vettore di n interi con numeri casuali compresi tra 1 e 9
* Input: int v[]: vettore dove memorizzo i valori generati
* int n : dimensione del vettore
* int min: minimo numero pseudo-casuale generabile
* int max: massimo numero pseudo-casuale generabile
* Output: -
*/
void Inizializza(int v[], int n, int min, int max)
{
for (int c = 0; c < n; c++)
v[c] = rand() % (max - min + 1) + min;
}
/*
* Nome: stampa
* Scopo: Stampa un vettore di n interi
* Input: int v[]: vettore
* int n: dimensione del vettore
* Output: -
*/
void Stampa(const int v[], int n)
{
for (int c = 0; c < n; c++)
printf("%4d", v[c]);
printf("\n");
}
/*
* Nome: somme
* Scopo: Calcola la somma dei numeri pari e dispari presenti in un vettore v di lunghezza n
* Input: const int v[]: vettore
* int n: dimensione del vettore
* int *somma_pari: puntatore alla variabile in cui memorizzo la somma dei numeri pari
* int *somma_dispari: puntatore alla variabile in cui memorizzo la somma dei numeri dispari
* Output: -
*/
void somme(const int v[], int n, int *somma_pari, int *somma_dispari)
{
for (int c = 0; c < n; c++)
if (v[c] %2 == 0)
*somma_pari += v[c];
else
*somma_dispari += v[c];
}
/*
* Nome: main
* Scopo: Stampa le somme dei numeri pari e dispari sulle righe di una matrice
* Input: --
* Output: 0 se il programma termina correttamente
*/
int main()
{
int m[N][M], p[N]={0}, d[N]={0}, r;
// INPUT - Inizializzazione
srand(time(NULL));
for (r = 0; r < N ; r++)
Inizializza(m[r],M, 1, 9);
// ALGORITMO
for (r=0; r < N; r++)
somme(m[r],M, &p[r], &d[r]);
// OUTPUT
printf("Matrice iniziale:\n\n");
for (r = 0; r < N ; r++)
Stampa(m[r],M);
printf("\nVettore Somma Pari:\n\n");
Stampa(p,N);
printf("\nVettore Somma Dispari:\n\n");
Stampa(d,N);
system("pause");
return 0;
}
|
Costruire una funzione che legge una sequenza di parole e segnala quelle palindrome. La sequenza è terminata quando l'utente scrive la stringa "0"
oppure se sono state digitate NWords parole.
|
|
SOLUZIONE:
OSSERVAZIONI:
1) Per le prove usa il seguente elenco di parole (cut & paste).
onorarono
argento
ottetto
radar
Anna
aveva
oro
ingegni
ottavo
vivi
0
2) La maschera di formato "%-30s" nel printf permette di scrivere la stringa in uno spazio fisso di 30 caratteri allineandolo a sinistra.
3) La maschera di formato "%30s" nello scanf permette di leggere una sequenza di caratteri fino all'inserimento di un simbolo di separazione (esempio spazio, tab, newline etc. : vedi funzione isspace()) oppure quando
sono arrivato al 30 carattere.
4) Quando passo ad una procedura una matrice posso omettere la 1° dimensione per cui posso scrivere: M[][100] oppure (*M)[100].
/**************************************************************************
* Nome: lab4-palindroma.c *
* Autore: Alessandro Saetti *
* Data: 23/3/10 *
**************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#include <string.h> // Richiesta da strlen;
#define NWords 20
#define LStr 30
/*
* Nome: palindroma
* Scopo: Determina se una parola e' palindroma
* Input: char *parola: la parola da verificare
* Output: true se la parola e' palindroma; false altrimenti
*/
bool palindroma (char *parola)
{
int i, j;
for (i = 0, j = strlen(parola) - 1; i < j ; i++, j--)
if (parola[i]!=parola[j]) return false;
return true;
}
/*
* Nome: acquisisci
* Scopo: Acquisisce parole da tastiera finchè non digito "0" fino ad un
* massimo di NWords
* Input: char (*m)[DIM]: la matrice nella quale salvare le parole
* Output: il numero di parole acquisite
*/
int Acquisisci (char m[][LStr])
{
// Potevo anche scrivere:
// int Acquisisci (char (*m)[LStr])
// Le dimensioni successive alla prima sono obbligatorie
int n = 0;
do
{
printf("Digita la %2d^ parola: ",n+1);
// Specifico il nr. massimo di caratteri da òeggere
scanf("%30s", m[n]);
if (strcmp(m[n], "0") != 0)
n++;
} while(n < NWords && strcmp(m[n], "0") != 0 );
return n;
}
/*
* Nome: main
* Scopo: Trova le parole palindrome in un gruppo di parola
* acquisite da tastiera
* Input: -
* Output: 0 se il programma termina correttamente
*/
int main()
{
char Vocaboli[NWords][LStr];
int i, n = 0;
// INPUT
n = Acquisisci(Vocaboli);
// ALGORITMO+OUTPUT
for (i = 0; i < n; i++)
if (palindroma(Vocaboli[i]))
printf("%-30s: palindroma\n", Vocaboli[i]);
else
printf("%-30s: //\n", Vocaboli[i]);
printf("\n");
system("pause");
return 0;
}
|
Costruire un programma ...
|
|
SOLUZIONE:
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#include <time.h> // Richiesta da time(NULL);
|
Costruire una funzione che inizializza gli elementi di un vettore (passato come parametro) con una sequenza di numeri casuali.
I valori min e max generabili devono essere parametri della nostra funzione. Ogni vettore è una riga di una matrice NxM (con M pari).
Costruire poi la funzione che stampa il contenuto di un vettore (la dimensione deve essere uno dei parametri).
Infine costruire la funzione che, dato un vettore, restituisca il minimo comune multiplo tra gli elementi del vettore.
Sfruttando queste funzioni costruire il programma che inizializza una matrice NxM, la stampa ed
infine mostra i minimi comune multipli dei numeri contenuti in ogni mezza riga (lunga quindi M/2) della matrice originale.
|
|
SOLUZIONE:
OSSERVAZIONI:
1) La notazione &m[r][M/2] fornisce il puntatore all'elemento a metà sulla riga r.
/**************************************************************************
* Nome: casa1-mcm.c *
* Autore: Alessandro Saetti *
* Data: 23/3/10 *
**************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#include <time.h> // Richiesta da time(NULL);
#define N 10 // Le dimensioni devono essere pari.
#define M 10
/*
* Nome: mcm
* Scopo: Calcola il minimo comune multiplo tra numeri presenti in un vettore v di lunghezza n
* Input: const int v[]: vettore
* int n: dimensione del vettore
* Output: Il minimo comune multiplo
*/
int Calcola_mcm(const int v[], int n)
{
int i, t_mcm, prodotto, max, mcm;
// Effettuo la produttoria di tutti gli elementi
// e determino il valore massimo
for (prodotto=1, i=0 , max=v[0] ; i < n ; i++)
{
prodotto *= v[i];
if (max < v[i])
max = v[i];
}
// Il mcm è un numero compreso tra la produttoria dei numeri
// e il max valore
for (t_mcm = prodotto; t_mcm >= max; t_mcm--)
{
for (i = 0 ; i < n ; i++)
if (t_mcm % v[i] != 0) break;
// se i == n ==> che tutti gli elementi del vettore dividono il
// t_mcm per cui è sicuramente un loro multiplo
if (i == n) mcm = t_mcm;
}
return mcm;
}
/*
* Nome: inizializza
* Scopo: Inizializza un vettore di n interi con numeri casuali compresi tra 1 e 9
* Input: int v[]: vettore dove memorizzo i valori generati
* int n : dimensione del vettore
* int min: minimo numero pseudo-casuale generabile
* int max: massimo numero pseudo-casuale generabile
* Output: -
*/
void Inizializza(int v[], int n, int min, int max)
{
for (int c = 0; c < n; c++)
v[c] = rand() % (max - min + 1) + min;
}
/*
* Nome: stampa
* Scopo: Stampa un vettore di n interi
* Input: int v[]: vettore
* int n: dimensione del vettore
* Output: -
*/
void Stampa(const int v[], int n)
{
for (int c = 0; c < n; c++)
printf("%4d", v[c]);
printf("\n");
}
/*
* Nome: main
* Scopo: Stampa i minimi comuni multipli tra i numeri nella prima e
* seconda meta' di ciascuna riga
* Input: --
* Output: 0 se il programma termina correttamente
*/
int main()
{
int m[N][M], m1[N]={0}, m2[N]={0}, r;
// INPUT - Inizializzazione
srand(time(NULL));
for (r = 0; r < N ; r++)
Inizializza(m[r],M, 1, 9);
// ALGORITMO
for (r=0; r < N; r++)
{
m1[r] = Calcola_mcm(m[r], M/2);
m2[r] = Calcola_mcm(&m[r][M/2], M/2);
}
// OUTPUT
printf("Matrice iniziale:\n\n");
for (r = 0; r < N ; r++)
Stampa(m[r],M);
printf("\nVettore mcm 1^ meta':\n\n");
Stampa(m1,N);
printf("\nVettore mcm 2^ meta':\n\n");
Stampa(m2,N);
system("pause");
return 0;
}
|
Costruire una funzione che inizializza gli elementi di un vettore (passato come parametro) con una sequenza di numeri casuali.
I valori min e max generabili devono essere parametri della nostra funzione. Ogni vettore è una riga di una matrice NxM (con M pari).
Costruire poi la funzione che stampa il contenuto di un vettore (la dimensione deve essere uno dei parametri).
Infine costruire la funzione che, dato un vettore, restituisca il numero di valori primi in esso contenuti.
Sfruttando queste funzioni costruire il programma che inizializza una matrice NxM, la stampa ed
infine mostra la riga contenente il numero maggiore di numeri primi
|
|
SOLUZIONE:
/**************************************************************************
* Nome: casa2-primi.c *
* Autore: Alessandro Saetti *
* Data: 23/3/10 *
**************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#include <time.h> // Richiesta da time(NULL);
#define N 10
#define M 10
/*
* Nome: Conta_I_Primi
* Scopo: Calcola la quantita' di numeri primi in un vettore v di lunghezza n
* Input: const int v[]: vettore
* int n: dimensione del vettore
* Output: La quantita' di numeri primi nel vettore
*/
int Conta_I_Primi(const int v[], int n)
{
int i, j, div, n_primi = 0;
// Scorro ogni elemento dell'array
for (i = 0; i < n; i++)
{
for (j = 2; j < v[i]; j++)
if (v[i] % j == 0)
break;
if (j >= v[i])
n_primi++;
}
return n_primi;
}
/*
* Nome: inizializza
* Scopo: Inizializza un vettore di n interi con numeri casuali compresi tra 1 e 9
* Input: int v[]: vettore dove memorizzo i valori generati
* int n : dimensione del vettore
* int min: minimo numero pseudo-casuale generabile
* int max: massimo numero pseudo-casuale generabile
* Output: -
*/
void Inizializza(int v[], int n, int min, int max)
{
for (int c = 0; c < n; c++)
v[c] = rand() % (max - min + 1) + min;
}
/*
* Nome: stampa
* Scopo: Stampa un vettore di n interi
* Input: int v[]: vettore
* int n: dimensione del vettore
* Output: -
*/
void Stampa(const int v[], int n)
{
for (int c = 0; c < n; c++)
printf("%4d", v[c]);
printf("\n");
}
/*
* Nome: main
* Scopo: Stampa la riga della matrice con piu' numeri primi
* Input: --
* Output: 0 se il programma termina correttamente
*/
int main()
{
int m[N][M], r, best_r, max, n_primi;
// INPUT - Inizializzazione
srand(time(NULL));
for (r = 0; r < N ; r++)
Inizializza(m[r],M, 1,9);
// ALGORITMO
for (max=0, best_r=0, r=0; r < N; r++)
{
n_primi = Conta_I_Primi(m[r], M);
if (n_primi > max)
{
max = n_primi;
best_r = r;
}
}
// OUTPUT
printf("Matrice iniziale:\n\n");
for (r = 0; r < N ; r++)
Stampa(m[r],M);
printf("\nLa %d riga e' quella con piu' numeri primi (%d):\n\n",best_r+1, max);
Stampa(m[best_r],M);
system("pause");
return 0;
}
|
Costruire una funzione che codifica una stringa utilizzando il cifrario di Cesare. Questo cifrario codifica una frase sostituendo
a ciascuna lettere la lettera n posizioni in avanti nell'alfabeto.

E' uno dei più antichi algoritmi crittografici di cui
si abbia traccia storica. E' un cifrario a sostituzione monoalfabetica in cui ogni lettera del testo in chiaro è sostituita
nel testo cifrato dalla lettera che si trova un certo numero di posizioni dopo nell'alfabeto.
Questo tipo di cifrario è detto anche cifrario a sostituzione o cifrario a scorrimento a causa del loro modo di operare.
|
|
SOLUZIONE:
NOTE:
I parametri di linea possono essere passati utilizzando l'apposito menu

char * strncpy ( char * Dest, const char * Orig, size_t Num ); => Il parametro Dest è un puntatore ad un array di char dove verrà copiata la stringa
indicata nel parametro Orig. Num indica il massimo numero di caratteri da copiare. La copia si interrompe appena viene incontrato
il carattere '0' nella stringa Orig. Num è un unsigned int. Richiede <string.h>.
int isalpha ( int c ); => Testa se il carattere cè una lettera alfabetica (minuscola o maiuscola).
Restituisce un valore diverso da 0 (true) se c è una lettera alfabetica, zero (false) altrimenti.
Richiede <ctype.h>.
/**************************************************************************
* Nome: lab3-cifrare.c *
* Autore: Alessandro Saetti *
* Data: 23/3/10 *
**************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#include <string.h> // Richiesta da strncpy(char *d, char *o,int n)
// Se uso isalpha()
// #include <cctype> // Richiesta da isalpha(char)
#define NChar 50
/*
* Nome: CodificaDiCesare
* Scopo: Cifra una frase sostituendo a ciascuna lettere la lettera n
* posizioni in avanti nell'alfabeto
* Input: char frase[]: vettore contenente la frase da cifrare
* int n: spostando nell'alfabeto
* Output: -
*/
void CodificaDiCesare(char frase[], int nc, int chiave)
{
// Al posto di if (frase[i] <= 'z' && frase[i]>='a')
// potevo usare: if (isalpha(frase[i]))
// In questo modo posso includere nella cifratura le maiuscole
// Questa funzione richiede <cctype.h>
for(int i = 0; i < nc && frase[i]!='\0'; i++)
if (frase[i] <= 'z' && frase[i]>='a')
frase[i]='a'+(frase[i]-'a'+chiave) % 26;
}
/* Alternativamente:
void cifrare(char frase[], int nc, int chiave)
{
int i;
for(i = 0; i < nc && frase[i]!='\0'; i++)
{
if (frase[i] <= 'z' && frase[i]>='a')
{
if (frase[i] + chiave <= 'z' && frase[i] + chiave >= 'a')
frase[i]=frase[i]+chiave;
else if (frase[i] + chiave > 'z')
frase[i]=(frase[i]+num)-'z'+'a'-1;
else if (frase[i] + chiave < 'a')
frase[i]=(frase[i]+chiave)-'a'+'z'+1;
}
}
}
*/
/*
* Nome: main
* Scopo: Stampa a video una frase cifrata
* Input: una frase da cifrare e un intero
* Output: 0 se il programma termina correttamente
*/
int main(int argc, char *argv[])
{
char vet[NChar];
int i, chiave;
// INPUT
if (argc != 3)
{
printf("Comando errato - Sintassi: cifra \n");
return(0);
}
else
{ // copia n caratteri
strncpy (vet, argv[1], NChar);
// strncpy(vet,"abcdefghijklmnopqrstuvwxyz",NChar);
chiave = atoi(argv[2]);
}
// ALGORITMO
CodificaDiCesare(vet, NChar, chiave);
// OUTPUT
printf(">> Parola in chiaro: %s\n", argv[1]);
printf(">> Parola cifrata : %s\n\n", vet);
system("pause");
return(0);
}
|
Costruire un programma che legge una sequenza di parole e alla fine evidenzia qualla con il maggior numero di consonanti e di vocali.
La sequenza è terminata quando l'utente scrive la stringa "0" oppure se sono state digitate NWords parole.
|
|
SOLUZIONE:
NOTE:
Per le prove usa il seguente elenco di parole (cut & paste).
Precipizio
Vocabolario
Novembre
Chiocciola
Asinara
Universiadi
Aiuola
Illustre
Caseggiato
Formaggio
0
#define identifier replacement =>
Si tratta di una direttiva di definizione per il precompilatore. Una direttiva per il precompilatore inizia sempre con il carattere
# ed occupa una sola riga. Su tale riga possono essere messi dei commenti ( // o /* ) o il simbolo di continuazione alla riga successiva ( ).
Il file sorgente contenente le direttive, viene tradotto dal pre-processore in quella che viene chiamata la translation unit
(anch’essa formata solamente da codice sorgente), la quale viene poi compilata in codice binario, dando origine al corrispondente file oggetto.
Tutti i file oggetto, infine, vengono collegati dal linker, generando un unico programma eseguibile.
Le direttive di inclusione sono quelle che iniziano con #include.
Le direttive di definizione sono sostanzialmente due, #define e #undef, che, come vedremo sotto, possono essere usate
congiuntamente per definire o meno qualcosa in modo condizionale. La sintassi è:
#define identificatore espressione
in cui sostanzialmente il pre-processore sostituisce tutte le occorrenze di "identificatore" con l’espressione corrispondente
(che può contenere anche spazi o virgolette). Quando la direttiva serve per definire una macro ha una sintassi leggermente diversa:
#define identificatore(argomenti) espressione
In questo caso, invece, si suppone che l’espressione contenga gli argomenti come variabili sulle quali operare.
Il pre-processore non fa altro che sostituire il codice di espressione, modificando gli argomenti definiti nella macro con quelli attuali,
ad ogni occorrenza dell’identificatore.
Ovviamente #undef serve solo per annullare il compito di ciò che abbiamo definito con l’eventuale #define. Ecco un esempio di
utilizzo:
#undef NUMERO
#define NUMERO 7
Le direttive condizionali permettono di definire una serie di istruzioni che verranno compilate in determinate condizioni.
Questo tipo di direttive viene usato spesso per compilare il medesimo sorgente su diversi sistemi operativi
(cambiando dei parametri che in Linux funzionano ed in Windows no, e viceversa). Le direttive condizionali sono sei:
#if espressione
Se il valore dell'espressione è zero (quindi FALSO) allora l’#if non farà niente,
Se il valore è diverso da zero (TRUE), allora si eseguirà il codice sotto l’if fino a che non si incontra un #elif, un #else o un #endif.
#ifdef identificatore
Riferendosi all’identificatore passato come parametro, se è già stato definito (TRUE) si eseguirà il codice sotto l’if fino a che non si incontra un #elif, un #else o un #endif.
#ifndef identificatore
Complementare al precedente. Esegue l’#if solo se l’identificatore passato non è stato definito.
#elif espressione
Corrisponde al costrutto ELSE IF, e quindi verifica la propria espressione ed agisce di conseguenza.
Può essere usato per definire scelte multiple (tranne l’ultima).
#else
Nell’ultima voce delle scelte condizionali bisogna mettere l’else che copre la casistica non ricoperta dall’#if e dagli #elif precedenti.
Tutto il codice che sta dopo l’else verrà eseguito fino a quando non si incontra un #endif.
#endif
Chiude la direttiva #if e, corrisponde, nel linguaggio C, alle famose parentesi graffe..
Vediamo ora un esempio completo che consente di testare il SO dove il nostro programma viene eseguito:
Ci sono delle macro predefinite che sono usate dalla maggior parte dei compilatori. Ad esempio se uso il compilatore GCC (GNU Compiler Collection: è
un compilatore per linguaggi di programmazione. Creato da Richard Stallman (fondatore del movimento Free Software Fondation) nel 1987 come semplice
compilatore C, nel tempo e grazie al lavoro di diversi programmatori, è stato via via ampliato fino a supportare molti altri linguaggi
{tra cui C++, Java, ecc.} ed è stata ampliata la compatibilità alla maggior parte dei sistemi operativi UNIX-based. Oggi è utilizzato come punto di
riferimento per molti programmatori open source) posso usare questo codice
#include <stdio.h>
#ifdef _WIN64
// per SO Windows a 64-bit
#define DoveSono() printf("Sono in Win 64-bit")
#elif _WIN32
// per SO Windows a 32-bit
#define DoveSono() printf("Sono in Win 32-bit")
#elif _WIN16
// per SO Windows a 16-bit
#define DoveSono() printf("Sono in Win 16-bit")
#elif __APPLE__
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE
// device iOS
#define DoveSono() printf("Sono in device iOS")
#elif TARGET_IPHONE_SIMULATOR
// Simulatore iOS
#define DoveSono() printf("Sono in simulatore iOS")
#elif TARGET_OS_MAC
// Altri tipi di Mac OS
#define DoveSono() printf("Sono in Mac OS")
#else
// SO Sconosciuto
#define DoveSono() printf("Sono in OS Apple sconosciuto")
#endif
#elif __linux
// linux
#define DoveSono() printf("Sono in Linux")
#elif __unix // SO unix non riconducibili a linux
// Unix
#define DoveSono() printf("Sono in UNIX")
#elif __posix
// POSIX
#define DoveSono() printf("Sono in POSIX")
#else
// SO Sconosciuto
#define DoveSono() printf("Sono in SO sconosciuto")
#endif
int main()
{
DoveSono();
// metto in stop il programma prima della sua chiusura
fflush(stdin);
getchar();
return(0);
}
SOLUZIONE:
/**************************************************************************
* Nome: casa3-vocali_consonanti.c *
* Autore: Alessandro Saetti *
* Data: 23/3/10 *
**************************************************************************/
#include <stdio.h>
#include <stdlib.h> // richiesta da system();
#include <string.h> // richiesta da strcmp();
#define NWords 20
#define LStr 30
/*
* Nome: Lettera
* Scopo: Determina se un carattere e' una lettera
* Input: char c: il carattere da esaminare
* Output: 1 se il carattere e' una lettera; 0 altrimenti
*/
// Potevo usare la funzione isalpha() in alternativa
// #include <ctype.h> // richiesta da isalpha();
// #define EUnaLettera(c) isalpha(c)
// Oppure
// #define EUnaLettera(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
bool EUnaLettera(char c)
{
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
return true;
else
return false;
}
/*
* Nome: vocale
* Scopo: Determina se un carattere e' una vocale
* Input: char c: il carattere da esaminare
* Output: true se il carattere e' una vocale; false altrimenti
*/
bool EUnaVocale(char c)
{
bool IsVowel;
IsVowel=(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u');
IsVowel=IsVowel || (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U');
/* In alternativa
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' ||
c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U')
return true;
else
return false;
*/
return IsVowel;
}
/*
* Nome: conta_vocali_consonanti
* Scopo: Conta il numero di vocali e consonanti in una stringa
* Input: char *vet: il vettore che contiene la stringa
* int n: la lunghezza della stringa
* int *voc: il numero di vocali ritornato
* int *cons: il numero di consonanti ritornato
* Output: 1 -
*/
void Conta_Vocali_Consonanti(char *Parola, int n, int *voc, int *cons)
{
for (int i = 0; i < n && Parola[i] != '\0'; i++)
{
if (EUnaVocale(Parola[i]))
(*voc)++;
else if (EUnaLettera(Parola[i]))
(*cons)++;
}
}
/*
* Nome: acquisisci
* Scopo: Acquisisce parole da tastiera finchè non digito "0" fino ad un
* massimo di NWords
* Input: char (*m)[DIM]: la matrice nella quale salvare le parole
* Output: il numero di parole acquisite
*/
int Acquisisci (char m[][LStr])
{
// Potevo anche scrivere:
// int Acquisisci (char (*m)[LStr])
// Le dimensioni successive alla prima sono obbligatorie
int n = 0;
do
{
printf("Digita la %2d^ parola: ",n+1);
// Specifico il nr. massimo di caratteri da òeggere
scanf("%30s", m[n]);
if (strcmp(m[n], "0") != 0)
n++;
} while(n < NWords && strcmp(m[n], "0") != 0 );
return n;
}
/*
* Nome: main
* Scopo: Acquisisce un gruppo di parole da tastiera e stampa a video la parola
* con piu' vocali e la parola con piu' consonanti
* Input: -
* Output: 0 se il programma termina correttamente
*/
int main()
{
char Vocaboli[NWords][LStr];
int r, n, NrVoc, NrCons;
int max_v = 0, max_c = 0, best_v = 0, best_c = 0;
// INPUT
n=Acquisisci(Vocaboli);
// ALGORITMO
for (r = 0; r < n; r++)
{
NrVoc = NrCons = 0;
Conta_Vocali_Consonanti(Vocaboli[r], LStr, &NrVoc, &NrCons);
if (NrVoc >= max_v)
{
max_v = NrVoc;
best_v = r;
}
if (NrCons >= max_c)
{
max_c = NrCons;
best_c = r;
}
}
// OUTPUT
printf("Parola con piu' vocali (%2d) : %s\n", max_v, Vocaboli[best_v]);
printf("Parola con piu' consonanti (%2d): %s\n", max_c, Vocaboli[best_c]);
system("pause");
return(0);
}
|
Costruire una funzione che legge una sequenza di parole e stampa le coppie di anagrammi.
La sequenza è terminata quando l'utente scrive la stringa "0" oppure se sono state digitate NWords parole.
|
|
SOLUZIONE:
NOTE:
Per le prove usa il seguente elenco di parole (cut & paste).
ROMA
BORA
BRESCIA
CALENDARIO
LOCANDIERA
ASCOLTATELI
SOLLECITATA
Orba
amor
SOLLETICATA
baro
RITAGLIERAI
roba
Artiglieria
0
int isalpha ( int c ); => Converte l'argomento c nel suo corrispondente miniuscolo se c è una lettera maiuscola.
Se nessuna conversione è possibile allora la funzione restituisce c. Richiede <ctype.h>.
/**************************************************************************
* Nome: casa4-anagramma.c *
* Autore: Alessandro Saetti *
* Data: 23/3/10 *
**************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#include <string.h> // Richiesta da strncpy(char *d, char *o,int n)
#include <ctype.h> // richiesta da tolower();
#define NWords 20
#define LStr 30
/*
* Nome: Anagramma
* Scopo: Determina se due parole sono l'una l'anagramma dell'altra
* Input: char *p1: la prima parola
* char *p2: la seconda parola
* int n: la lunghezza massima dei vettori p1 e p2
* Output: 1 se le due parole sono degli anagrammi; 0 altrimenti
*/
// int Anagramma (char p1[], char p2[], int n)
bool Anagramma (char *p1, char *p2, int n)
{
int i, p, c1[26] = {0}, c2[26] = {0};
if (strlen(p1)!=strlen(p2)) return false;
// Conteggio le occorrenze di ogni singola lettera nella 1° parola
for ( i=0; i < LStr && p1[i]!='\0' ; i++ )
{
p=tolower(p1[i])-'a';
c1[p]++;
}
// Conteggio le occorrenze di singola lettera nella 2° parola
for ( i=0; i < LStr && p2[i]!='\0' ; i++ )
{
p=tolower(p2[i])-'a';
c2[p]++;
}
// Se il conteggio delle occorrenze è identico allora la prima parola è
// un anagramma della seconda.
for(i=0 ; i < 26 ; i++)
if ( c1[i] != c2[i] )
return false;
return true;
}
/*
* Nome: acquisisci
* Scopo: Acquisisce parole da tastiera finchè non digito "0" fino ad un
* massimo di NWords
* Input: char (*m)[DIM]: la matrice nella quale salvare le parole
* Output: il numero di parole acquisite
*/
int Acquisisci (char m[][LStr])
{
// Potevo anche scrivere:
// int Acquisisci (char (*m)[LStr])
// Le dimensioni successive alla prima sono obbligatorie
int n = 0;
do
{
printf("Digita la %2d^ parola: ",n+1);
// Specifico il nr. massimo di caratteri da leggere
scanf("%30s", m[n]);
if (strcmp(m[n], "0") != 0)
n++;
} while(n < NWords && strcmp(m[n], "0") != 0 );
return n;
}
/*
* Nome: main
* Scopo: Acquisisce da tastiera un gruppo di parole e stampa a video le coppie di anagrammi
* Input: -
* Output: 0 se il programma termina correttamente
*/
int main()
{
char Vocaboli[NWords][LStr];
int n, r1 , r2;
// INPUT
n=Acquisisci(Vocaboli);
// ALGORITMO + OUTPUT
printf("ANAGRAMMI TROVATI:\n ");
for (r1 = 0; r1 < n; r1++)
for (r2 = r1 + 1; r2 < n; r2++)
if (Anagramma(Vocaboli[r1], Vocaboli[r2], LStr))
printf("%30s <==> %-30s\n", Vocaboli[r1], Vocaboli[r2]);
// metto in stop il programma prima della sua chiusura
system("pause");
return 0;
}
SOLUZIONE:
Soluzione C++
Soluzione JavaScript
Soluzione VBA
Soluzione ASP
Soluzione PHP