Tema 1 - Introducere în C++

Responsabili

Deadline soft: 2 aprilie, ora 23:55

Depunctare întârziere după depășirea deadline-ului soft: -10p/zi

Deadline hard: 5 aprilie, ora 23:55

Modificări și actualizări

  • 20 martie modificare check_pc.sh din arhivă
  • 22 martie pus fișierele de referință în arhiva de testare, specificat format de output
  • 23 martie detalii pentru operatorul de concatenare

Obiective

În urma realizării acestei teme:

  • veți învǎţa să definiți și să folosiți tipuri de date proprii
  • veți fi capabili să implementați o clasă generică Vector, similară cu cea din STL
  • veți fi capabili să implementați un iterator pentru această clasă, similar cu cel din STL
  • vă veți acomoda cu sintaxa de C++ (genericizare, management de memorie, operatori)

Ne propunem să simulăm funcționalitatea unei structuri de date omogenă, care se redimensionează, de tip std::vector din STL. De atlfel, ne propunem implementarea unui iterator care să poate funcționa pe aceasta structură de date, similiar cu std::vector::iterator din STL.

Cum funcționează

MyVector

Reprezintă o clasă care implementează funcționalitatea unui vector cu elemente generice. Se dorește implementarea următoarelor funcționalități:

  • adăugare element, metoda se va numi add
  • ștergere element de pe o anumită poziție și pentru o anumită valoare, metodele (două) se vor numi remove, respectiv removeElement; removeElement va șterge prima apariție a valorii primite ca parametru
    • ne dorim ca spațiul “liber” din MyVector să se ocupe prin deplasarea restului elementelor astfel încât structura de date să fie contiguă
    • exemplu: un MyVector conține elementele 1,2,3; dacă vrem să “ștergem” elementul 2 din structura de date, vom deplasa elementul 3 la stânga cu o unitate astfel încât MyVector-ul nostru conține acum elementele 1,3; aveți grijă la cazuri limită
  • vectorul are dimensiunea, by default, de 10 elemente
  • poate fi specificat ca dimensiunea de început să fie alta
  • dacă dimensiunea actuală este depășită prin adăugarea de noi elemente, atunci dimensiunea se dublează
  • dacă, prin ștergere de elemente se ajunge ca numărul de elemente actual să fie jumătate - 1 din dimensiunea actuală, aceasta se reduce la jumătate
  • să existe posibilitatea de a folosi semantica de index a vectorilor din C (să putem scrie v[index], cu v de tip MyVector și index de tip întreg, care să aibă sensul din C - se aleagă elementul de la index). Atenție, se dorește ca v[index] să se poată și scrie și citi, adică să putem scrie v[index] = ceva
  • să existe posibilitatea de a putea scrie new_list = list1 + list2, cu new_list, list1 și list2 de tip MyVector. new_list va reprezenta concatenarea dintre list1 și list2; se va considera că rezultatul este list1 la care se adaugă fiecare element din list2; operanzii nu vor fi modificați
  • să implementeze 2 metode, begin și end, care să întoarcă un iterator de tip MyIterator care pointează spre primul element (begin), respectiv după ultimul element (end) al vectorului. Practic, end pointează după ultimul element din vector, deci nu ar trebui dereferențiat
  • să poată fi afișată de către un stream de output (e.g. std::cout); formatul de ieșire este simplu: toate elementele structurii, separate prin spațiu

MyIterator

Reprezintă o clasă care va fi folosită pentru a itera asupra structurii de date de mai sus. Astfel, ea va avea nevoie de următoarele funcționalități:

  • să aiba un membru de tipul container-ului pe care vrea să itereze
  • să rețină index-ul actual din container până unde a iterat
  • să implementeze posibilitatea de a folosi semantica de dereferențiere din C (să putem scrie *it, cu it de tip MyIterator, care să reprezinte elementul curent din container unde s-a ajuns cu iterarea)
  • să implementeze posibilitatea de a scrie it++, ++it, it - -, - - it, cu it de tip MyIterator, care să incrementeze/decrementeze locul unde s-a ajuns cu iterarea asupra container-ului
  • să implementeze posibilitatea de a scrie it » x și it « y, cu it de tip MyIterator și x, y de tip întreg, care să incrementeze (»), cu x, respectiv să decrementeze («), cu y, locul unde s-a ajuns cu iterarea asupra container-ului
  • să implementeze posibilitatea de a scrie ~it, cu it de tip MyIterator, care să șteargă elementul din container spre care pointează iteratorul it

Exemplu simplu de folosire (evident, clasele voastre vor fi template-uite):

MyVector a; /* a are o dimensiune default de 10 elemente */
MyIterator it;
for (int i = 0; i < 20; ++i)
    a[i] = i;
 
/* se iterează asupra vectorului cu ajutorul iteratorului */
for (it = a.begin(); it != a.end(); ++it)
    std::cout << *it << ' ' << std::endl; /* se printează elementele */

Cerințe

Se cere să se implementeze funcționalitățile descrise mai sus, în 2 fișiere, MyVector.h și MyIterator.h, care vor fi incluse în fișierele noastre de teste.

Cum vom testa

Tema voastră va fi testată folosind niște fișiere sursă .cpp, care vor include cele 2 header-e și vor instanția cele 2 clase pe care le aveți de implementat, verificând funcționalitățile cerute.

Folosiți MyVector și MyIterator pt numele claselor, respectiv MyVector.h și MyIterator.h pentru numele fișierelor, altfel testele nu vor trece, chiar dacă voi implementați cum trebuie totul.

Având în vedere modul de testare, dacă veți avea funcționalități neimplementate, cel puțin unele dintre teste nu vor compila.

Cum vom implementa

Veți implementa cele două clase template-uite în câte un fișier header separat, MyVector.h și MyIterator.h.

observație: Față de funcționalitățile descrise mai sus, clasele vor trebui, evident, să respecte rule of three.

Teste publice

Aveți la dispoziție o arhivă ce conține o suită de teste publice, reprezentate prin niște fișiere .cpp, și un Makefile care va încerca compilarea fiecărui fișier din teste.

Arhiva de testare

Reguli pentru trimitere

Temele vor trebui trimise pe vmchecker. Atenție! Temele trebuie trimise în secțiunea Structuri de Date (CA).

Arhiva trebuie să conțină:

  • fișierele MyVector.h și MyIterator.h
  • fisier README care să conțină detalii despre implementarea temei

Punctaj

  • 80 puncte obținute pe testele de pe vmchecker
  • 10 puncte: coding style
  • 10 puncte: README
  • Bonus 10 puncte pentru soluțiile ce nu au memory leak-uri.
  • TOTAL: 110 puncte

Codul vostru va fi verificat să nu genereze comportament nedefinit (undefined behaviour) cu valgrind. Dacă se va observa că există cod care ar putea genera astfel de comportament din partea compilatorului, se poate scădea tot punctajul de pe temă (o tema cu undefined behaviour poate merge sau nu, în funcție de mașina pe care a fost compilată, memoria RAM disponibilă la acel moment, starea vremii în ziua compilării sau orice alt motiv super concludent :-p). Exemple de lucruri care ar putea genera undefined behaviour:

  • dereferențiere de pointer NULL
  • screiere sau citire peste zona care a fost alocată
  • double free etc

Mai multe exemple găsiți aici, la răspunsul acceptat (cel cu checked). De altfel, mai multe despre undefined behaviour găsiți aici, aici și aici. Ar fi de preferat să citiți aceste articole înainte de implementarea temei.

Coding style-ul trebuie sa fie consistent și ușor de citit. Ca ghid vă recomandăm:

sau

Atenție! Tema valorează 0.75 punct din nota finală. Cele 100 de puncte acordate de noi se vor regăsi proporțional în punctajul de 0.75. Citiți cu atenție Regulamentul General de Trimitere a Temelor.

Nu copiați! Toate soluțiile vor fi verificate folosind o unealtă de detectare a plagiatului. În cazul detectării unui astfel de caz, atât plagiatorul cât și autorul original (nu contează cine care e) vor primi punctaj 0 pe toate temele!

De aceea, vă sfătuim să nu vă lăsați rezolvări ale temelor pe calculatoare partajate (la laborator etc), pe Drive/Dropbox/mail/liste de discuții/grupuri/facebook/reddit/9gag etc.

În cazul detectării plagiatului, argumentele de tipul “mi-am lăsat calculatorul logat pe Drive” vor avea aceeași valoare cu “mi-a mâncat câinele codul”. You have been warned :)

FAQ

Q: Se poate folosi STL?

A: Nu puteți folosi structurile gata implementate în STL. Obiectivul principal al cursului de structuri de date este acela ca voi să implementați structurile respective.

Q: Avem vreun schelet de cod? Practic ce clase, metode, operatori trebuie să implementăm?

A: Nu există schelet de cod pentru tema aceasta. Trebuie să vă dați seama din specificația temei (dacă nu e suficient de clară, întrebați) ce anume trebuie să implementați (metode, operatori etc).

Q: De ce trebuie să mă chinui atât ca doar să mi se compileze codul?

A: După cum observați, structura de date în sine este foarte simplă. Pentru că abia învățați baza C++, ne așteptăm ca operațiile pe care trebuie să le suporte MyVector și MyIterator să vă dea (foarte probabil) bătăi de cap la compilare. Este intenționat. Deducerea semnăturilor corecte pentru metode, operatori etc și utilizarea lor corectă fac parte din dificultatea temei.

Resurse

sd-ca/teme/teme-01.txt · Last modified: 2015/04/01 18:34 by andrei.vasiliu2211
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