Laboratorul 13. Tipuri generice. Funcţiile qsort şi bsearch

În acest laborator veţi învăţa să folosiţi:

  • funcţiile qsort şi bsearch.
  • tipuri, funcţii şi pointeri generici.

Problema 1 - Problemă rezolvată


Scrieţi un program care citeşte un n de la tastatură şi creează un vector (cu dimensiunea n) de numere întregi generate aleator şi îl sortează ulterior folosind funcţia de bibliotecă void qsort din stdlib.h:

 void qsort ( void * base, size_t num, size_t size, int ( * comparator ) ( const void *, const void * ) ); 
  • base este adresa primului element din vector
  • num este numărul de elemente din vector
  • size este dimensiunea unui element
  • comparator este funcţia ce compară 2 elemente din vector

Implementaţi o funcţie de comparare în care să apelaţi qsort cu parametrii corespunzători. Rezolvare:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
#define MAX_VALUE 200
 
int cmp(const void * a, const void *b)
{
   return (*(int*)a - *(int*)b);
}
 
int main(void)
{
   int N, i;
   int *v;
   printf("Introduceti dimensiunea vectorului:\n");
   scanf("%d", &N);
 
   v = calloc(N, sizeof(int));
   if (!v) printf("Nu am putut aloca memorie pentru v!\n");
 
   srand(time(NULL));
   for (i = 0; i < N; ++i)
      v[i] = (rand() % MAX_VALUE)+1;
 
   for (i = 0; i < N; ++i)
      printf("%d ", *(v+i));
   printf("\n");
 
   qsort(v, N, sizeof(int), cmp);
 
   for (i = 0; i < N; ++i)
      printf("%d ", *(v+i));
   printf("\n");
 
   free(v);
   return 0;
}

Problema 2


Completaţi programul de la problema 1 astfel încât să se afişeze poziţia pe care apare un întreg x citit de la tastatură în vectorul sortat. Veţi folosi funcţia void *bsearch din stdlib.h:

 void *bsearch ( const void * key, void * base, size_t num, size_t size, int ( * comparator ) ( const void *, const void * ) ) 
  • key este adresa cheii căutate
  • base este adresa primului element din vector
  • num este numărul de elemente din vector
  • size este dimensiunea unui element
  • comparator este funcţia ce compară 2 elemente din vector

Funcţia întoarce un pointer către elementul din vector corespunzător cheii căutate sau NULL dacă nu a fost găsit un astfel de element.

Problema 3

Atentie! aveti atasata o arhiva cu o rezolvare partiala a problemei, va rugam sa o completati! arhiva_lab_13.rar


Se consideră următoarele definiţii:

typedef struct entry {
   void * key;
   void * value;
} entry;
 
typedef struct map {
   entry ** elem; // vectorul de elemente; este alocat si realocat dinamic
   int n_elem; // numarul de elemente din vector
   int cap; // capacitatea vectorului
} map;

Definiţi următoarele funcţii:

// aloca initial memorie pentru cap elemente de tip entry*
void init(map *m, int cap);
 
// adauga la vectorul de elemente din m noua intrare (pointerul primit) si eventual realoca pe m->elem OBS: se considera ca nu se adauga chei duplicate!
void add(map *m, entry *e);
 
// afiseaza pe m folosind functia pentru afisarea unui entry primita ca parametru
void print(map *m, void ( *printEntry) ( const entry * ) );
 
// sorteaza elementele din m folosind functia primita ca parametru si functia de biblioteca qsort. Observatie: fc va trebui sa compare între ele 2 structuri entry* (se va face conversie la entry ** in functia de comparatie!! DE CE?)
void sort(map *m, int ( * fc ) ( const void *, const void * ) ); 
 
// sterge intrarea corespunzatoare cheii k din m. Atentie! Nu veti compara pointerii pentru a testa daca 2 elemente sunt egale, ci veti folosi functia primita ca parametru, ce se considera ca întoarce 0 pentru elemente egale. Observatie: fc2 va trebui sa compare între ele 2 chei (void *).
void del(map *m, void *k, int ( * fc2 ) ( const void *, const void * )); 
 
// functie ce întoarce valoarea asociata unei chei. Se va folosi functia bsearch! Observatie: fc va trebui sa compare între ele 2 structuri entry* (se va face conversie la entry ** in functia de comparatie!! DE CE?). Vectorul tb sortat in prealabil! Dar, atentie el nu tb sa iasa modificat, se va lucra pe o copie a lui!
void *find(map *m, void *k, int ( * fc ) ( const void *, const void * )); 

Pentru a testa funcţiile definite vom face următoarea particularizare: vrem să reţinem definiţiile asociate unor cuvinte. Va trebui să implementaţi:

//  Funcţia ce compară între ele 2 structuri entry* ţinând cont de faptul că în acest caz particular cheia va fi char *. Funcţia de comparare nu trebuie să ţină cont şi de valorile asociate.
int compareEntry( const void *, const void *); 
 
// Funcţie ce compară 2 chei (în cazul de faţă, 2 şiruri de caractere). Funcţia va apela _strcmp_.
int compareKey( const void *, const void *); 
 
// Funcţie ce afişează cheia şi valoarea asociată pe cazul particular când sunt şiruri de caractere.
void printEntry( const entry *); 

În programul principal, afişaţi un meniu ce va permite următoarele operaţii la apăsarea respectivelor taste:

  1. - Afisare dictionar.
  2. - Cauta cuvant in dictionar. // se va afisa cuvantul + definitia sau un mesaj corespunzator daca nu a fost gasit
  3. - Adauga cuvant in dictionar. // se va citi de la tastatura cuvantul si definitia
  4. - Sterge cuvant din dictionar. // se va citi de la tastatura cuvantul ce se doreste sters
  5. - Sortare dictionar
  6. - Iesire din program
  

BONUS: 1.Impartiti sursa in 3 fisiere: un fisier header, unul care contine implementarea dictionarului generic si un al treilea in acre avem utilizarea dictionarului (main+functiile de comparare si printare intrare).

2.Sa se redefineasca metoda add astfel incat daca se incearca adaugarea unei intrari a carei cheie exista deja in dictionar sa se modifice doar valoarea veche asociata cheii la valoarea noua!

Aveţi grijă să alocaţi memorie pentru fiecare cuvânt şi pentru fiecare definiţie şi să o eliberaţi atunci când nu mai este nevoie (de ex. la ştergerea unui cuvânt). Puteţi să le citiţi iniţial într-un sir de dimensiune fixa şi să folosiţi funcţia strdup.

programare-cc/laboratoare/13.txt · Last modified: 2023/01/12 21:47 by carmen.odubasteanu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0