Programmazione 1    (P-Z) a.a. 2007-08


Docente: R. Silvestri
Esercitatore: A. Carosi
Tutor: J. Stefa


Esercitazioni del 06 novembre 2007

Esercizio 1

Scrivere una funzione che presa in input una stringa di caratteri ed uno specifico carattere, restituisce la stringa ottenuta eliminando le occorrenze del carattere indicato dalla stringa di input (es. se str = "Io programmo in C" e ch = m, restituisce la stringa "Io prograo in C"). Integrare la funzione in un programma main, che prende la stringa ed il carattere da tastiera, e stampa la stringa risultante.
Nota: si richiede allo studente di utilizzare le funzioni di allocazione dinamica della memoria.

Esercizio 2

Scrivere una funzione che presa in input una stringa di caratteri, restituisce la stringa ottenuta raddoppiando le occorrenze delle vocali (es. se str = "Io programmo in C", restituisce la stringa "IIoo proograammoo iin C"). Integrare la funzione in un programma main, che prende la stringa di caratteri da tastiera, e stampa la stringa risultante.
Nota: si richiede allo studente di utilizzare le funzioni di allocazione dinamica della memoria.

Esercizio 3

Scrivere una funzione che prese in input due stringhe di caratteri, restituisce la stringa ottenuta concatenando le due stringhe (es. se str1 = "Io programmo " e str2 = "in C", restituisce la stringa "Io programmo in C"). Integrare la funzione in un programma main, che prende le due stringhe da tastiera, e stampa la stringa risultante.
Nota: si richiede allo studente di utilizzare le funzioni di allocazione dinamica della memoria.

Esercizio 4

Scrivere un programma che, dati in input da tastiera due numeri interi positivi, rappresenta i due numeri come due vettori e restituisce il vettore risultato dell'operazione di somma. Il programma deve simulare il calcolo della somma attraverso il metodo di calcolo posizionale (es. se in input viene data la coppia di interi 4 e 98, i due vettori saranno [4] e [8,9], per ciò il risultato sarà il vettore [2,0,1], ovvero 102).
Nota: si richede allo studente di utilizzare le funzioni di allocazione della memoria, è inoltre consigliato considerare le seguenti funzioni:

1) int* init(int n) che trasforma un intero in un vettore di interi, sfruttando il resto della divisione per 10.
2) int* somma(int vect1[], int vect2[]) che esegue la somma in base alle posizioni.









Soluzioni



Soluzione Esercizio 1

#include <stdio.h>
#include <stdlib.h>

char* filtra(char [], char);
void print(char []);
char* init(void);

int main (void) {
  char *str, c;

  str = init();
  printf ("Inserisci un carattere: ");
  c = getchar();
  
  print (str);
  str = filtra (str, c);
  print (str);

  return 0;
}

void print(char str[]) {
  int i = 0;

  while (str[i] != '\0') {
    printf ("%c", str[i]);
    i++;
  }
  printf ("\n");
}

char* init(void) {
  char c, *str = NULL;
  int index = 0, alloc = 0;

  printf ("Inserisci la stringa: ");
  while ((c = getchar()) != '\n') {
    str = (char *) realloc (str, (alloc + 1) * sizeof(char));
    str[index++] = c;
    alloc += sizeof(char);
  }

  str = (char *) realloc (str, (alloc + 1) * sizeof(char));
  str[index] = '\0';

  return str;
}

char* filtra(char str[], char c) {
  int i = 0, index = 0, alloc = 0;
  char *tmp = NULL;

  while(str[i] != '\0') {
    if (str[i] != c) {
      tmp = (char *)realloc(tmp, (alloc + 1) * sizeof(char));
      tmp[index++] = str[i];
      alloc += sizeof(char);
    }
    i++;
  }
  
  tmp = (char *)realloc(tmp, (alloc + 1) * sizeof(char));
  tmp[index] = '\0';
  
  return tmp;
}

Soluzione Esercizio 2

Considerate le seguenti funzioni:
char* doubleVocals(char str[]) {
  int i = 0, index = 0,alloc = 0;
  char *tmp = NULL;

  while(str[i] != '\0') {
    if (isVocal(str[i])) {
      tmp = (char *)realloc(tmp, (alloc + 2) * sizeof(char));
      tmp[index] = tmp[index + 1] = str[i];
      index += 2;
      alloc += 2 * sizeof(char);
    } else {
      tmp = (char *)realloc(tmp, (alloc + 1) * sizeof(char));
      tmp[index++] = str[i];
      alloc += sizeof(char);
    }
    i++;
  }
  
  tmp = (char *)realloc(tmp, (alloc + 1) * sizeof(char));
  tmp[index] = '\0';
    
  return tmp;
}

short int isVocal(char c) {
  // è necessario includere l'header <ctype.h>
  c = tolower(c);
  if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') return 1; 
  return 0;
}

Soluzione Esercizio 3

Considerate la seguente funzione:
char* concat(char str1[], char str2[]) {
  int i = 0, alloc = 0;
  char *tmp = NULL;

  while(str1[i] != '\0') {
    tmp = (char *)realloc(tmp, (i + 1) * sizeof(char));
    tmp[i] = str1[i];
    i++;
  }

  alloc = i;
  i = 0;
  while(str2[i] != '\0') {
    tmp = (char *)realloc(tmp, (alloc + i + 1) * sizeof(char));
    tmp[i + alloc] = str2[i];
    i++;
  }

  tmp = (char *)realloc(tmp, (alloc + i +1) * sizeof(char));
  tmp[alloc + i] = '\0';

  return tmp;
}

Soluzione Esercizio 4

#include <stdio.h>
#include <stdlib.h>

void print(int [], int);
int* init(int);
int* somma(int [], int []);

int main (void) {
  int *vect1, *vect2, n1 ,n2;

  printf ("Inserisci un intero positivo: ");
  scanf("%d", &n1);
  vect1 = init(n1);

  printf ("Inserisci un intero positivo: ");
  scanf("%d", &n2);
  vect2 = init(n2);

  int *tmp = somma(vect1, vect2);
  printf ("Somma: ");
  print(tmp, 0);
  printf ("\n");

  return 0;
}

int* somma(int v1[], int v2[]) {
  int *tmp = (int *)malloc(sizeof(int)), alloc = 1, index = 0, d;

  /* 
     Questa funzione calcola la somma posizionale di due vettori di interi,
     con due vettori di lunghezza non conosciuta e possibilmente diversa.
     Il risultato viene inserito nel nuovo vettore di interi "tmp".
     L'algoritmo di calcolo di basa sullo spostamento in avanti del carattere
     (in questo caso un intero) di fine stringa: il "-1".
  */

  tmp[0] = -1;

  /* 
     Gestiamo qui la situazione in cui i due vettori hanno lo
     stesso numero di interi (es. 123 e 987, entrambi costituiti da 3 interi).
  */

  while(v1[index] >= 0 && v2[index] >= 0) {
    if (tmp[index] < 0) {
      tmp = (int *)realloc(tmp, (alloc + 1) * sizeof(int));
      alloc += sizeof(int);
      tmp[index + 1] = -1;
      tmp[index] = (v1[index] + v2[index]) % 10;

      d = (v1[index] + v2[index]) / 10;
      if (d > 0) {
	tmp[index + 1] = d;
	tmp = (int *)realloc(tmp, (alloc + 1) * sizeof(int));
	tmp[index + 2] = -1;
	alloc += sizeof(int);
      }
    } else {
       d = (v1[index] + v2[index] + tmp[index]) / 10;
       tmp[index] = (v1[index] + v2[index] + tmp[index]) % 10;
       
       if (d > 0) {
	 tmp[index + 1] = d;
	 tmp = (int *)realloc(tmp, (alloc + 1) * sizeof(int));
	 alloc += sizeof(int);
	 tmp[index + 2] = -1;
       }
    }
    index++;    
  }

  /*
    Gestiamo qui gli interi in eccedenza, quando i due vettori non hanno lo stesso
    numero di interi (es. 123 e 7)
  */

  int first = (v1[index] >= 0)?1:0;
  int second = (v2[index] >= 0)?1:0;

  /*
    La variabile "first" indica che il primo vettore è il più lungo, 
    mentre "second" indica che il secondo vettore è il più lungo;
    in base al cilco precedente, al massimo solo una delle due variabili viene 
    impostata ad 1 (ovvero a "true" nei controlli). Quando "first" e "second" sono
    entrambi a "0", allora i due vettori saranno stati completamente analizzati.
  */

  while (first || second) {
    if (tmp[index] < 0) {

      if (first) tmp[index] = v1[index];
      else tmp[index] = v2[index];

      tmp = (int *)realloc(tmp, (alloc + 1) * sizeof(int));
      alloc += sizeof(int);
      tmp[index + 1] = -1;
    } else {

      if (first) {
	d = (tmp[index] + v1[index]) / 10;
	tmp[index] = (tmp[index] + v1[index]) % 10;
      } else {
	d = (tmp[index] + v2[index]) / 10;
	tmp[index] = (tmp[index] + v2[index]) % 10;
      }

      tmp = (int *)realloc(tmp, (alloc + 1) * sizeof(int));
      alloc += sizeof(int);
      tmp[index + 1] = -1;

      if (d > 0) {
	tmp[index + 1] = d;
	tmp = (int *)realloc(tmp, (alloc + 1) * sizeof(int));
	tmp[index + 2] = -1;
	alloc += sizeof(int);
      }
    }
    index++;

    if (first) first = v1[index] >= 0?1:0;
    if (second) second = v2[index] >= 0?1:0;
  } 

  return tmp;
}

void print(int str[], int i) {
  /*
    Funzione ricorsiva di stampa, dall'intero più significativo
    (l'ultimo del vettore) al meno significativo (il primo del vettore).
  */

  if (str[i] == -1) return;

  print(str, i + 1);
  printf ("%d",str[i]);
}

int* init(int n) {
  int alloc = 0, index = 0, r, *tmp = NULL;

  while (n > 0) {
    tmp = (int *)realloc(tmp, (alloc + 1) * sizeof(int));
    r = n % 10;
    n /= 10;
    tmp[index] = r;
    index++;
    alloc += sizeof(int);
  }

  tmp = (int *)realloc(tmp, (alloc + 1) * sizeof(int));
  
  /*
    l'array termina con il numero intero "-1", non è infatti 
    possibile avere un "n" tale che (n % 10) = -1, e per questo 
    "-1" non potrà mai apparire nella stringa di interi.
  */
  
  tmp[index] = -1;

  return tmp;
}

-- RiccardoSilvestri - 07 Nov 2007

Edit | Attach | Watch | Print version | History: r5 < r4 < r3 < r2 < r1 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r5 - 2007-11-11 - RiccardoSilvestri






 
Questo sito usa cookies, usandolo ne accettate la presenza. (CookiePolicy)
Torna al Dipartimento di Informatica
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback