Differences

This shows you the differences between two versions of the page.

Link to this comparison view

programare:laboratoare:lab07 [2018/11/03 16:38]
darius.neatu [Motivație]
programare:laboratoare:lab07 [2022/04/01 11:35] (current)
cristian.olaru1612
Line 3: Line 3:
  
 **Responsabili:​** **Responsabili:​**
-  * [[neatudarius@gmail.com|Darius Neațu (2018, 2017)]]+  * [[neatudarius@gmail.com|Darius Neațu (CA 2019-2021)]] 
 +  * [[ion_dorinel.filip@cti.pub.ro|Dorinel Filip (CA 2019-2021)]]
   * [[rares96cheseli@gmail.com|Rareș Cheșeli (2018, 2017)]] ​   * [[rares96cheseli@gmail.com|Rareș Cheșeli (2018, 2017)]] ​
  
Line 35: Line 36:
 ==== Dimensiunea tipurilor implicite în C. Calculul memoriei unui program ==== ==== Dimensiunea tipurilor implicite în C. Calculul memoriei unui program ====
  
-În [[https://​ocw.cs.pub.ro/​courses/​programare/​laboratoare/​lab02|laboratorul 2]] au prezentate tipurile de date implicite din C și dimensiunea acestora.+În [[https://​ocw.cs.pub.ro/​courses/​programare/​laboratoare/​lab02|laboratorul 2]] au fost prezentate tipurile de date implicite din C și dimensiunea acestora.
  
 Pentru a afla ** dimensiunea în bytes ** a unei variabile se poate folosi operatorul **sizeof**. Pentru a afla ** dimensiunea în bytes ** a unei variabile se poate folosi operatorul **sizeof**.
Line 76: Line 77:
 </​code>​ </​code>​
  
-În urma executării acestui program pe o arhitectură de 32 biți vom vedea următorul rezultat.+În urma executării acestui program pe o arhitectură de **32 biți** (ceea ce folosim la PC) vom vedea următorul rezultat.
  
 <​code>​ <​code>​
Line 100: Line 101:
  
 <​note>​ <​note>​
-Putem afla dimensiunea unui tip de date / variabila ​de un anumit tip la ** compile time ** folosind operatorul sizeof care returnează dimensiunea în bytes a parametrului dat.+Putem afla dimensiunea unui tip de date / unei variabile ​de un anumit tip la ** compile time ** folosind operatorul sizeof care returnează dimensiunea în bytes a parametrului dat.
  
-**sizeof** poate fi folosit și pentru măsurarea dimesiunii unui vector / matrice alocat(a) static.+**sizeof** poate fi folosit ​**și** pentru măsurarea dimesiunii unui vector / matrice alocat(a) static.
  
-Memoria totală folosită de un program poate fi calculată ca suma tuturor dimensiunilor ocupate de variabilele din program.+Memoria totală folosită de un program poate fi calculată ca **suma** tuturor dimensiunilor ocupate de variabilele din program.
  
 De obicei, ne interesează să știm ** ordinul de mărime ** al spațiului de memorie alocat, astfel, de cele mai multe ori, putem contoriza doar tablourile. De obicei, ne interesează să știm ** ordinul de mărime ** al spațiului de memorie alocat, astfel, de cele mai multe ori, putem contoriza doar tablourile.
  
 +
 +<note warning>
 Un caz special îl poate reprezenta recursivitatea! Punerea parametrilor pe stivă de un număr foarte mare de ori, este echivalent cu declararea unui tablou de valori pe stivă. Aceste variabile nu pot fi neglijate în calculul memoriei! Un caz special îl poate reprezenta recursivitatea! Punerea parametrilor pe stivă de un număr foarte mare de ori, este echivalent cu declararea unui tablou de valori pe stivă. Aceste variabile nu pot fi neglijate în calculul memoriei!
 +</​note>​
  
-Vom descoperi mai multe în următoare laboratoare. ​:p+Vom descoperi mai multe în următoare laboratoare. ​8-)
 </​note>​ </​note>​
  
Line 137: Line 141:
 == Bitwise NOT == == Bitwise NOT ==
 <spoiler Semnificație>​ <spoiler Semnificație>​
-** Bitwise NOT ** (** complement față de 1 **) este operația la nivel de bit care următorul tabel de adevăr.+** Bitwise NOT ** (**complement față de 1**) este operația la nivel de bit care următorul tabel de adevăr.
 ^ x ^ ~x ^ ^ x ^ ~x ^
 ^ 0 ^ 1 ^ ^ 0 ^ 1 ^
Line 144: Line 148:
 Evident putem extinde această operație și la nivel de număr. Operația se aplică separat pentru fiecare rang binar. Evident putem extinde această operație și la nivel de număr. Operația se aplică separat pentru fiecare rang binar.
 ^  ^ $b_2$ ^  $b_1$ ^ $b_0$ ^ ^  ^ $b_2$ ^  $b_1$ ^ $b_0$ ^
-^ x = 3 ^ 0 ^ 1 ^ 1 ^+ x = 3 ^ 0 ^ 1 ^ 1 ^
 ^ ~x = 4 ^ 1 ^ 0 ^ 0 ^ ^ ~x = 4 ^ 1 ^ 0 ^ 0 ^
 </​spoiler>​ </​spoiler>​
Line 150: Line 154:
 == Bitwise AND == == Bitwise AND ==
 <spoiler Semnificație>​ <spoiler Semnificație>​
-** Bitwise AND ** (** ȘI pe biți **) este operația la nivel de bit care următorul tabel de adevăr.+** Bitwise AND ** (**ȘI pe biți**) este operația la nivel de bit care următorul tabel de adevăr.
 ^ x ^ y ^ x & y ^ ^ x ^ y ^ x & y ^
 ^ 0 ^ 0 ^ 0 ^ ^ 0 ^ 0 ^ 0 ^
Line 159: Line 163:
 Evident putem extinde această operație și la nivel de număr. Operația se aplică separat pentru fiecare rang binar. Evident putem extinde această operație și la nivel de număr. Operația se aplică separat pentru fiecare rang binar.
 ^  ^ $b_2$ ^  $b_1$ ^ $b_0$ ^ ^  ^ $b_2$ ^  $b_1$ ^ $b_0$ ^
-^ x = 3 ^ 0 ^ 1 ^ 1 ^ +    ​x = 3 ^ 0 ^ 1 ^ 1 ^ 
-^ y = 7 ^ 1 ^ 1 ^ 1 ^+    ​y = 7 ^ 1 ^ 1 ^ 1 ^
 ^ x & y = 3 ^ 0 ^ 1 ^ 1 ^ ^ x & y = 3 ^ 0 ^ 1 ^ 1 ^
 </​spoiler>​ </​spoiler>​
Line 166: Line 170:
 == Bitwise OR == == Bitwise OR ==
 <spoiler Semnificație>​ <spoiler Semnificație>​
-** Bitwise OR ** (** SAU pe biți **) este operația la nivel de bit care următorul tabel de adevăr.+** Bitwise OR ** (**SAU pe biți**) este operația la nivel de bit care următorul tabel de adevăr.
 ^ x ^ y ^ x %%|%% y ^ ^ x ^ y ^ x %%|%% y ^
 ^ 0 ^ 0 ^ 0 ^ ^ 0 ^ 0 ^ 0 ^
Line 182: Line 186:
 == Bitwise XOR == == Bitwise XOR ==
 <spoiler Semnificație>​ <spoiler Semnificație>​
-** Bitwise XOR ** (** SAU-EXCLUSIV pe biți **) este operația la nivel de bit care următorul tabel de adevăr.+** Bitwise XOR ** (**SAU-EXCLUSIV pe biți**) este operația la nivel de bit care următorul tabel de adevăr.
 ^ x ^ y ^ x %%^%% y ^ ^ x ^ y ^ x %%^%% y ^
 ^ 0 ^ 0 ^ 0 ^ ^ 0 ^ 0 ^ 0 ^
Line 246: Line 250:
  
 === Cum verificăm dacă  bitul i  dintr-un număr n este setat? === === Cum verificăm dacă  bitul i  dintr-un număr n este setat? ===
-<spoiler Explicație>​ 
- 
-Această întrebare ne oferă valoarea bitului i. 
- 
-Dacă "​valoarea este 1", atunci vom spune că "bitul este setat"​. ​ 
- 
-Dacă "​valoarea este 0", atunci vom spune că "bitul nu este "​setat"​. 
- 
- 
-Pentru a ** verifica ** valoarea bitului i din numărul n, practic noi ar trebui să privim numărul astfel: 
- 
-^    ^ $b_7$ ^ $b_6$ ^ ... ^ $b_i$ ^ ... ^ $b_1$ ^ $b_0$ ^ 
-^ n  ^ *  ^  * ^ ... ^  ? ^ ... ^ *  ^  * ^ 
- 
-unde ***** înseamnă ** don't care ** (de la PL), 
-iar **?** este valoarea pe care o cautăm. 
- 
-Deci am vrea sa facem, după cum am zis mai sus, o operație de tipul "​scoate"​ doar bitul i din număr, iar în rest lasă 0 (pentru a evidenția bitul nostru). 
-^            ^ $b_7$ ^ ... ^ $b_{i+1}$ ​ ^ $b_i$ ^ $b_{i-1}$ ^ ... ^ $b_0$ ^    ^ 
-^         ​n ​ ^ *     ^ ... ^  *         ​^ ​ ?    ^  *        ^ ... ^  *    ^    ^ 
-^      mask  ^ $m_7$ ^ ... ^ $m_{i+1}$ ​ ^ $m_i$ ^ $m_{i-1}$ ^ ... ^ $m_0$ ^ op ^ 
-^ n op mask  ^ 0     ^ ... ^  0         ​^ ​ ?    ^  0        ^ ... ^  0    ^    ^ 
- 
-Să analizăm cine pot fi **op** și **biții din mască** ($m_i$). 
- 
-Dorim ca: 
-  * $ ? \ \ op \ \ m_i = \ ? $ : operația op aplicată pe $?$ și $m_i$, va avea mereu ca rezultat pe $?$. 
-  * $ * \ \ op \ \ m_j = 0 $ (unde i != j) : operația op aplicată pe orice valoare și $m_j$, va da 0. 
- 
-Observăm că: 
-  * 1 este elementul neutru pentru **ȘI**, ceea ce verifică ** ? & 1 = ? **, oricare are fi ? un bit. 
-  * 0 este elementul care poate "​șterge"​ un bit prin **Și**, ceea ce verifică ** * & 0 = 0 **, oricare ar fi * un bit. 
- 
-</​spoiler>​ 
 <​note>​ <​note>​
 Detectarea bitului: Detectarea bitului:
Line 291: Line 261:
  
  
-  * pas 2: deoarece **?** poate avea două valori, x poate fi $0$ sau $2^i$.+  * pas 2: deoarece **?** poate avea două valori, x poate fi $0$ sau $2^i$
          * dacă ** x == 0 **, atunci ** bitul i este 0 **          * dacă ** x == 0 **, atunci ** bitul i este 0 **
          * dacă ** x > 0  **, atunci ** bitul i este 1 **           * dacă ** x > 0  **, atunci ** bitul i este 1 ** 
Line 321: Line 291:
 </​spoiler>​ </​spoiler>​
  
 +<spoiler Explicație pas cu pas>
  
 +Această întrebare ne oferă valoarea bitului i.
  
 +Dacă "​valoarea este 1", atunci vom spune că "bitul este setat"​. ​
  
-=== Cum setăm (valoarea ​devine 1)  bitul i  dintr-un număr n? === +Dacă "valoarea ​este 0", atunci vom spune că "bitul nu este "​setat"​.
-<spoiler Explicație>​ +
-Dorim să facem următoarea operație: schimba doar bitul i in 1, iar pe ceilalți lasă-i neschimbați. +
-^            ^ $b_7$ ^ ... ^ $b_{i+1}$ ^ $b_i$ ^ $b_{i-1}$ ^ ... ^ $b_0$ ^    ^ +
-^         ​n ​ ^ $n_7$ ^ ... ^ $n_{i+1}$ ^  *    ^ $n_{i-1}$ ^ ... ^ $n_0$ ^    ^ +
-^      mask  ^ $m_7$ ^ ... ^ $m_{i+1}$ ^ $m_i$ ^ $m_{i-1}$ ^ ... ^ $m_0$ ^ op ^ +
-^ n op mask  ^ $n_7$ ^ ... ^ $n_{i+1}$ ^  1    ^ $n_{i-1}$ ^ ..^ $n_0$ ^    ^+
  
-Să analizăm cine pot fi **op** și **biții din mască** ($m_i$).+ 
 +Pentru a ** verifica ** valoarea bitului i din numărul n, practic noi ar trebui să privim numărul astfel: 
 + 
 +^    ^ $b_7$ ^ $b_6$ ^ ... ^ $b_i$ ^ ... ^ $b_1$ ^ $b_0$ ^ 
 +^ n  ^ *  ^  * ^ ... ^  ? ^ ... ^ *  ^  * ^ 
 + 
 +unde ***** înseamnă ** don't care ** (de la PL), 
 +iar **?** este valoarea pe care o cautăm. 
 + 
 +Deci am vrea să facem, după cum am zis mai sus, o operație de tipul "​scoate"​ doar bitul i din număr, iar în rest lasă 0 (pentru a evidenția bitul nostru). 
 +^            ^ $b_7$ ^ ... ^ $b_{i+1}$ ​ ^ $b_i$ ^ $b_{i-1}$ ^ ... ^ $b_0$ ^    ^ 
 +^         ​n ​ ^ *     ^ ... ^  *         ​^ ​ ?    ^  *        ^ ... ^  *    ^    ^ 
 +^      mask  ^ $m_7$ ^ ... ^ $m_{i+1}$ ​ ^ $m_i$ ^ $m_{i-1}$ ^ ... ^ $m_0$ ^ op ^ 
 +^ n op mask  ^ 0     ^ ... ^  0         ​^ ​ ?    ^  0        ^ ... ^  0    ^    ^ 
 + 
 +**op** este o operație, iar **mask** un număr. ​Să analizăm cine pot fi **op** și **biții din mască** ($m_i$).
  
 Dorim ca: Dorim ca:
-  * $ \ \ op \ \ m_i = operația op aplicată pe $*(orice) ​și $m_i$, va avea mereu ca rezultat pe $1$. +  * $ \ \ op \ \ m_i = \ ? , adică ​operația op aplicată pe $?$ și $m_i$, va avea mereu ca rezultat pe $?
-  * $ n_j \ \ op \ \ m_j = n_j $ (unde i != j) operația ​$opaplicată pe orice valoare și $m_j$, va da $n_j$.+  * $ \ \ op \ \ m_j = $ (unde i != j), adică ​operația op aplicată pe orice valoare și $m_j$, va da 0
  
 Observăm că: Observăm că:
-  * 1 esteelementul care poate "​umple"​ un bit prin **SAU**, ceea ce verifică ​1 = 1 $, oricare ​ar fi un bit. +  * 1 este elementul neutru pentru ​**ȘI**, ceea ce verifică ** ? & 1 = ? **, oricare ​are fi un bit 
-  * 0 este elementul ​neutru pentru ​**SAU**, ceea ce verifică ​$ n_j | 0 = n_j $, oricare ​are fi $n_j$ un bit.+  * 0 este elementul ​care poate "​șterge"​ un bit prin **Și**, ceea ce verifică ​** * & 0 = 0 **, oricare ​ar fi un bit 
 </​spoiler>​ </​spoiler>​
  
 +
 +
 +
 +
 +=== Cum setăm (valoarea devine 1)  bitul i  dintr-un număr n? ===
 <​note>​ <​note>​
 Setarea bitului: Setarea bitului:
Line 378: Line 366:
 </​spoiler>​ </​spoiler>​
  
- +<spoiler Explicație ​pas cu pas
- +Dorim să facem următoarea operație: schimba doar bitul i in 1, iar pe ceilalți lasă-i neschimbați.
- +
- +
-=== Cum resetăm (valoarea devine 0)  bitul i  dintr-un număr n? === +
-<spoiler Explicație>​ +
-Dorim să facem următoarea operație: schimba doar bitul i in 0, iar pe ceilalți lasă-i neschimbați.+
 ^            ^ $b_7$ ^ ... ^ $b_{i+1}$ ^ $b_i$ ^ $b_{i-1}$ ^ ... ^ $b_0$ ^    ^ ^            ^ $b_7$ ^ ... ^ $b_{i+1}$ ^ $b_i$ ^ $b_{i-1}$ ^ ... ^ $b_0$ ^    ^
 ^         ​n ​ ^ $n_7$ ^ ... ^ $n_{i+1}$ ^  *    ^ $n_{i-1}$ ^ ... ^ $n_0$ ^    ^ ^         ​n ​ ^ $n_7$ ^ ... ^ $n_{i+1}$ ^  *    ^ $n_{i-1}$ ^ ... ^ $n_0$ ^    ^
 ^      mask  ^ $m_7$ ^ ... ^ $m_{i+1}$ ^ $m_i$ ^ $m_{i-1}$ ^ ... ^ $m_0$ ^ op ^ ^      mask  ^ $m_7$ ^ ... ^ $m_{i+1}$ ^ $m_i$ ^ $m_{i-1}$ ^ ... ^ $m_0$ ^ op ^
-^ n op mask  ^ $n_7$ ^ ... ^ $n_{i+1}$ ^  ​   ^ $n_{i-1}$ ^ ... ^ $n_0$ ^    ^+^ n op mask  ^ $n_7$ ^ ... ^ $n_{i+1}$ ^  ​   ^ $n_{i-1}$ ^ ... ^ $n_0$ ^    ^
  
-Să analizăm cine pot fi **op** și **biții din mască** ($m_i$).+**op** este o operație, iar **mask** un număr. ​Să analizăm cine pot fi **op** și **biții din mască** ($m_i$).
  
 Dorim ca: Dorim ca:
-  * $ * \ \ op \ \ m_i = operația op aplicată pe $*$ (orice) și $m_i$, va avea mereu ca rezultat pe $0$. +  * $ * \ \ op \ \ m_i = $, adică ​operația op aplicată pe $*$ (orice) și $m_i$, va avea mereu ca rezultat pe $1
-  * $ n_j \ \ op \ \ m_j = n_j $ (unde i != j) operația $op$ aplicată pe orice valoare ​și $m_j$, va da $n_j$.+  * $ n_j \ \ op \ \ m_j = n_j $ (unde i != j), adică ​operația $op$ aplicată pe $n_j$ și $m_j$, va da $n_j$
  
 Observăm că: Observăm că:
-  * este elementul care poate "șterge" un bit prin **ȘI**, ceea ce verifică $ * & 0 $, oricare ar fi * un bit. +  * este elementul care poate "umple" un bit prin **SAU**, ceea ce verifică $ * | 1 $, oricare ar fi * un bit 
-  * este elementul neutru pentru **ȘI**, ceea ce verifică $ n_j | = n_j $, oricare are fi $n_j$ un bit.+  * este elementul neutru pentru **SAU**, ceea ce verifică $ n_j | = n_j $, oricare are fi $n_j$ un bit
 </​spoiler>​ </​spoiler>​
  
 +
 +
 +
 +
 +
 +=== Cum resetăm (valoarea devine 0)  bitul i  dintr-un număr n? ===
 <​note>​ <​note>​
 Resetarea bitului: Resetarea bitului:
  
-  * pas 1: se aplică următoarea operația ** n = n & mask **, unde ** mask = ~(1 << i) **+  * pas 1 / 1: se aplică următoarea operația ** n = n & mask **, unde ** mask = ~(1 << i) **
  
 ^            ^ $b_7$ ^ ... ^ $b_{i+1}$ ^ $b_i$ ^ $b_{i-1}$ ^ ... ^ $b_0$ ^    ^ ^            ^ $b_7$ ^ ... ^ $b_{i+1}$ ^ $b_i$ ^ $b_{i-1}$ ^ ... ^ $b_0$ ^    ^
Line 436: Line 425:
     ​     ​
 </​code>​ </​code>​
 +</​spoiler>​
 +
 +
 +<spoiler Explicație pas cu pas>
 +Dorim să facem următoarea operație: schimba doar bitul i in 0, iar pe ceilalți lasă-i neschimbați.
 +^            ^ $b_7$ ^ ... ^ $b_{i+1}$ ^ $b_i$ ^ $b_{i-1}$ ^ ... ^ $b_0$ ^    ^
 +^         ​n ​ ^ $n_7$ ^ ... ^ $n_{i+1}$ ^  *    ^ $n_{i-1}$ ^ ... ^ $n_0$ ^    ^
 +^      mask  ^ $m_7$ ^ ... ^ $m_{i+1}$ ^ $m_i$ ^ $m_{i-1}$ ^ ... ^ $m_0$ ^ op ^
 +^ n op mask  ^ $n_7$ ^ ... ^ $n_{i+1}$ ^  0    ^ $n_{i-1}$ ^ ... ^ $n_0$ ^    ^
 +
 +**op** este o operație, iar **mask** un număr. Să analizăm cine pot fi **op** și **biții din mască** ($m_i$).
 +
 +Dorim ca:
 +  * $ * \ \ op \ \ m_i = 0 $, adică operația op aplicată pe $*$ (orice) și $m_i$, va avea mereu ca rezultat pe $0$
 +  * $ n_j \ \ op \ \ m_j = n_j $ (unde i != j), adică operația $op$ aplicată pe $n_j$ și $m_j$, va da $n_j$
 +
 +Observăm că:
 +  * 0 este elementul care poate "​șterge"​ un bit prin **ȘI**, ceea ce verifică $ * & 0 = 0 $, oricare ar fi * un bit
 +  * 1 este elementul neutru pentru **ȘI**, ceea ce verifică $ n_j | 1 = n_j $, oricare are fi $n_j$ un bit
 </​spoiler>​ </​spoiler>​
  
Line 448: Line 456:
 [[https://​drive.google.com/​open?​id=1QjYcHcDSApXZ1ZTloxqibOAU9GSckaxE | Teste Problema 6]] [[https://​drive.google.com/​open?​id=1QjYcHcDSApXZ1ZTloxqibOAU9GSckaxE | Teste Problema 6]]
  
-==Precizari:==+==Precizari ​CB\CD==
  
  
Line 461: Line 469:
  
  
-<note warning> 
-În rezolvarea acestui ** laborator ** nu aveți voie să folosiți operatorii ** /, *, % ** ! 
  
-Hint: Încercați să folosiți operații pe biți!  +==Precizari generale== 
-</​note>​ +Rezolvați împreună cu asistentul pe tablă, exercițiile 0-4, apoi rezolvați invidual exercițiul ​5.
- +
-Rezolvați împreună cu asistentul, eventual ​pe tablă, exercițiile 0-3, apoi rezolvați invidual exercițiul ​4.+
  
-== 0: Verificare ​ca un număr e par ==+== 0: Verificare ​că un număr e par ==
 Să se verifice folosind operații pe biți că un număr natural n e par. Să se verifice folosind operații pe biți că un număr natural n e par.
 <code C> <code C>
 int is_even(int n); int is_even(int n);
 </​code>​ </​code>​
 +
 == 1. Calcul putere a lui 2 (0p) == == 1. Calcul putere a lui 2 (0p) ==
 Să se scrie o funcție care să calculeze $2^n$, unde $ n <= 30 $. Să se scrie o funcție care să calculeze $2^n$, unde $ n <= 30 $.
Line 494: Line 499:
 </​code>​ </​code>​
  
-Implementați invidual următoarea problemă. 
-== 4. bitset (10p) == 
-O mulțime de numere întregi poate fi reprezentată astfel: spunem că un număr aparține unei mulțimi S dacă bit-ul al i-lea din vectorul S are valoarea 1.  
  
-Pentru e ficientă, vectorul ​va conține date de tipul **unsigned char**.+== 4. Verificare că un număr este putere al lui 2 (0p)== 
 +Să se scrie o funcție care verifică dacă un număr întreg n pe 32 biți este puterea a lui 2. Funcția va returna 1 dacă n este putere a lui 2, 0 altfel. 
 +<code C> 
 +int is_power2(int n); 
 +</​code>​
  
-<​spoiler ​Exemplu+<​spoiler ​Hint
-Presupunem că avem vectorul ** unsigned char S[3]; **, pentru care am initializat deja valorile cu 0, 3, 5. +Analizați reprezentarea în baza 2 a lui n (exn = 16 si n = 5). 
-S[0], S[1], S[2] fiecare reprezintă câte o variabilă pe 8 biți.+</​spoiler>​
  
-^  ^     ​^ ​    ​^ ​    ​^ ​  ​S[0] ​ ^     ​^ ​    ​^ ​    ​^ ​    ​^ ​ |   ​^ ​    ​^ ​    ​^ ​    ^ S[1]    ^     ​^ ​    ​^ ​    ​^ ​    ​^ ​  ​| ​ ^     ​^ ​    ​^ ​    ^ S[2]    ^     ​^ ​    ​^ ​    ​^ ​    ^ 
-^ ^$b_0$^$b_ 1$^$b_2$^$b_3$^$b_4$^$b_5$^$b_6$^$b_7$^ ​ |   ^ $b_0$^$b_1$^$b_2$^$b_3$^$b_4$^$b_5$^$b_6$^$b_7$^ ​ |   ^ $b_0$^$b_1$^$b_2$^$b_3$^$b_4$^$b_5$^$b_6$^$b_7$^ 
-^ biti din S ^0    ^0    ^0    ^0    ^0    ^0    ^0    ^0    ^  |  ^1    ^1    ^0    ^0    ^0    ^0    ^0    ^0    ^    |   ^ 1    ^0    ^1    ^0    ^0    ^0    ^0    ^0    ^ 
-^ numere asociate^0^1^2^3^4^5^6^7^ | ^8^9^10^11^12^13^14^15^ | ^16^17^18^19^20^21^22^23^ ​ 
  
-<​note>​ 
-Atentie! Bitii au fost desenati invers (stanga-dreapta 0-7) pentru a obtine in desen sirul sortat de numere asociate. 
-In realitate un byte arata asa in memorie: $b_7b_6b_5b_4b_3b_2b_1b_0$ 
-</​note>​ 
-Observați notarea biților! Vom folosi această schema pentru a obține șirul numerelor asociate ca fiind sortat. 
  
-Interpretare:​ 
  
-- numărul **3** nu face partea din mulțimea S, pentru că bitul asociat (**cel cu numărul / etichete 3** din vector) este **0**+\\ 
 +Implementați invidual următoarea problemă.
  
-- numărul **16** face partea din mulțimea S, pentru că bitul asociat (**cel cu numărul / etichepa 16 ** din vector) este **1** 
  
-Analog pentru toate numerele de la 0 la 23 (avem doar 24 de biți în acest exemplu), putem verifica dacă numărul i este în vector. +== 5. bitset ​(10p )== 
-Astfel vectorul S de mai sus reprezintă ​mulțimea **{8, 9, 16, 18}**.+mulțime de numere întregi poate fi reprezentată astfel: spunem că un număr ​**** aparține unei mulțimi S dacă bit-ul al i-lea din vectorul S are valoarea 1
  
-Dacă programul nostru ​va seta bitul cu numărul 15 pe 1, atunci operația este echivalentă cu **S = S U {15}**. Programul va trebui să își dea seama ca **bitul cu numărul 15** este defapt ​** bitul cu numărul 7 ** din **byteul cu numărul 1** (adica din S[1]).  +Pentru e ficientă, vectorul S va conține date de tipul **unsigned char** (reamintim ​ca **sizeof(unsigned char) == 1 byte** adică **8 biți**).
-</​spoiler>​+
  
 <​note>​ <​note>​
Line 539: Line 534:
 </​note>​ </​note>​
  
 +
 +
 +=== 5.1 ===
        
-Implementați funcții ​pentru+Implementați ​următoarele ​funcții. Realizați un program în C prin care să demonstrați că funcțiile implementate funcționează. 
-      * **adăugarea** unui element în mulțime ​(**1p**)+ 
 +<​note>​ 
 +Există un [[https://​ocw.cs.pub.ro/​courses/​programare/​laboratoare/​lab07-bitset-example | exemplu]] detaliat care vă explică cum functionează aceastea. 
 + 
 +Treceți la subpunctul următor abia după ce v-ați asigurat că acestea funcționează. 
 +</​note>​ 
 + 
 +      * **adăugarea** unui element în mulțime
       <code C>        <code C> 
-      // insert_in_set(s,​ n) - adauga numarul n in multimea ​S+      // insert_in_set(s,​ n) - adauga numarul n in multimea ​s
       void insert_in_set(SET s, unsigned int n);       void insert_in_set(SET s, unsigned int n);
       </​code>​       </​code>​
  
-      * **ștergerea** unui element din mulțime ​(**1p**)+      * **ștergerea** unui element din mulțime
       <code C>       <code C>
-      // delete_from_set(s,​ n) - scoate numarul n din multime ​S+      // delete_from_set(s,​ n) - scoate numarul n din multime ​s
       void delete_from_set(SET s, unsigned int n);       void delete_from_set(SET s, unsigned int n);
       </​code>​       </​code>​
  
-      * a verifica dacă un element n **aparține** unei mulțimi ​(**1p**)+      * **verificarea** faptului că un element n **aparține** unei mulțimi
       <code C>       <code C>
-      // is_in_set(s,​ n) - returneaza 1 daca n este in S, 0 altfel+      // is_in_set(s,​ n) - returneaza 1 daca n este in s, 0 altfel
       int is_in_set(SET s, unsigned int n);       int is_in_set(SET s, unsigned int n);
       </​code>​       </​code>​
  
-      * **ștergerea** tuturor elementelor din mulțime ​(**1p**)+      * **ștergerea** tuturor elementelor din mulțime
       <code C>       <code C>
       // delete_all_from_set(s) - elimina toate elementele din multime       // delete_all_from_set(s) - elimina toate elementele din multime
Line 565: Line 570:
       </​code>​       </​code>​
  
-      * a calcula ​**cardinalul** unei mulțimi ​(**1p**)+      * calcularea ​**cardinalul** unei mulțimi
       <code C>       <code C>
-      // card_set(s) - returneaza cardinalul multimii ​S+      // card_set(s) - returneaza cardinalul multimii ​s
       int card_set(SET s);       int card_set(SET s);
       </​code>​       </​code>​
  
-      * a verifica dacă mulțimea este **vidă** ​(**0.5p**)+      * verificarea faptului că mulțimea este **vidă**
       <code C>       <code C>
       // is_empty_set(s) - verifica daca multimea este sau nu goala       // is_empty_set(s) - verifica daca multimea este sau nu goala
Line 578: Line 583:
       </​code>​       </​code>​
  
-      * o funcție care **să citească de la tastatură** ​ o mulțime ​(**0.5p**)+      * o funcție care **să citească de la tastatură** ​ o mulțime
       <code C>       <code C>
-      // read_set(a) - functia citeste numarul n de elemente care se afla in A +      // read_set(s) - functia citeste numarul n de elemente care se afla in a 
-      // apoi citeste cele n numere si le insereaza in A+      // apoi citeste cele n numere si le insereaza in a
       // va returna numarul n citit (numarul de elemente)       // va returna numarul n citit (numarul de elemente)
-      int read_set(SET ​a);+      int read_set(SET ​s);
       </​code>​       </​code>​
  
-      * o funcție care **să afișeze** pe ecran elementele care se află într-o mulțime ​(**0.5p**)+      * o funcție care **să afișeze** pe ecran elementele care se află într-o mulțime
       <code C>       <code C>
-      // print_set(a) - functia printeaza elementele multimii ​A +      // print_set(s) - functia printeaza elementele multimii ​s 
-      void print_set(SET ​a);+      void print_set(SET ​s);
       </​code>​       </​code>​
 +      ​
 +Urmăriți acest [[https://​ocw.cs.pub.ro/​courses/​programare/​laboratoare/​lab07-bitset-example | exemplu cu bitset]] ​ pentru a înțele cum funcționeazăaceste operații. ​     ​
  
 +=== 5.2 ===
 Realizati un program care, utilizând metodele de fite anterior, citește 2 mulțimi A (n și B și a fișează:​ $ A U B, A ∩ B, A - B, B - A $. Realizati un program care, utilizând metodele de fite anterior, citește 2 mulțimi A (n și B și a fișează:​ $ A U B, A ∩ B, A - B, B - A $.
  
Line 597: Line 605:
       * **reuniunea** a două mulțimi (**1p**)       * **reuniunea** a două mulțimi (**1p**)
       <code C>       <code C>
-      // B+      // b
       void merge_set(SET a, SET b, SET c);       void merge_set(SET a, SET b, SET c);
       </​code>​       </​code>​
Line 603: Line 611:
       * **intersecția** a două mulțimi (**1p**)       * **intersecția** a două mulțimi (**1p**)
       <code C>       <code C>
-      // B+      // b
       void intersect_set(SET a, SET b, SET c);       void intersect_set(SET a, SET b, SET c);
       </​code>​       </​code>​
Line 609: Line 617:
       * **diferența** a două mulțimi (**1p**)       * **diferența** a două mulțimi (**1p**)
       <code C>       <code C>
-      // A - B+      // a \ b
       void diff_set(SET a, SET b, SET c);       void diff_set(SET a, SET b, SET c);
       </​code>​       </​code>​
  
-În final va trebui sa creați o funcție ** main ** și să faceți un program care rezolvă cerința folosind funcțiile implementate. (**1p**)+În final va trebui sa creați o funcție ** main ** și să faceți un program care rezolvă cerința folosind funcțiile implementate. 
 + 
 +==== B1. Optimizations ==== 
 +O să învățați pe viitor că nu toate înstrucțiunile sunt la fel din punct de vedere al timpului de execuției. Ca un punct de start, gândiți-vă că dacă ați face pe foaie o adunare sau o înmultire, durează mai mult să înmulțiți decât să adunați. Această dificulate o are și procesorul din laptopul vostru! 
 + 
 +Pentru a-l ajuta și a face programul mai rapid, putem înlocui operații costisitoare ​(** * **, ** / **) cu altele mai puțin costistoare (** + **, ** - **). Cele mai rapide instrucțiuni sunt cele care lucrează direct pe biți (deoarece numerele sunt stocate în memorie în binar, deci este modul natural de lucru pentru calculator)
 + 
 +Acest exercițiu vă propune să aplicați aceste optimizări pe codul vostru! ​
  
 <spoiler Hint> <spoiler Hint>
-Folosiți funcțiile **setresetis_set ​** definite în ** prima ** parte a laboratorului. +Pentru a completa acest bonus, **NU** aveți voie să folosiți operatorii ​** /*** ! Încercați să folosiți operații pe biți! ​
- +
-Implementați funcțiile din enunț în ordinea sugerată.+
 </​spoiler>​ </​spoiler>​
  
-=== BONUS === +==== B2. MSB/​LSB ​====
-== B1. MSB/LSB ==+
 Să se scrie o câte o funcție pentru aflarea MSB(Most significant bit), respectiv LSB(Least significant bit), pentru un număr n pe 32 biți. Să se scrie o câte o funcție pentru aflarea MSB(Most significant bit), respectiv LSB(Least significant bit), pentru un număr n pe 32 biți.
 <code C> <code C>
Line 628: Line 640:
 int get_msb(int n); int get_msb(int n);
 </​code>​ </​code>​
 +
 <spoiler Hint> <spoiler Hint>
 Analizați reprezentarea în baza 2 a lui n. Analizați reprezentarea în baza 2 a lui n.
 </​spoiler>​ </​spoiler>​
- 
-== B2. Verificare că un număr este putere al lui 2 == 
-Să se scrie o funcție care verifică dacă un număr întreg n pe 32 biți este puterea a lui 2. Funcția va returna 1 dacă n este putere a lui 2, 0 altfel. 
-<code C> 
-int is_power2(int n); 
-</​code>​ 
-<spoiler Hint> 
-Analizați reprezentarea în baza 2 a lui n (ex. n = 16 si n = 5). 
-</​spoiler>​ 
- 
  
  
Line 664: Line 667:
  
 <spoiler Element unic din șir> ​ <spoiler Element unic din șir> ​
-Fie un șir cu ** 2n + 1 ** numere întregi, dintre care n numere apar de câte 2 ore, iar unul singur este unic.+Fie un șir cu ** 2n + 1 ** numere întregi, dintre care n numere apar de câte 2 ori, iar unul singur este unic.
 Să se gasească elementul unic.  Să se gasească elementul unic. 
  
Line 701: Line 704:
 </​spoiler>​ </​spoiler>​
  
-<spoiler Împărat, bețiv și nervos> 
-Împăratul Gigel a primit cadou ** 100 ** de sticle de vin de la un admirator secret. Acesta i-a lăsat și o scrisoare în care îi spune despre faptul că este vin nobil, însă a otrăvit o sticlă. Cine va bea din sticla otrăvită ** va muri în fix 24h **.  
  
-Gigel dispune de un număr imens de sclavi (precum număr imens de restanțe in Poli), așa că el își va pune sclavii să guste din vin. Se gândește totuși că nu se mai găsesc sclavi pe toate drumurile, așa ca dorește ** să folosească un număr minim de sclavi ** (cei care gustă riscă să moară). 
- 
-Ajutați-l pe Gigel să găsească numărul minim de sclavi pe care trebuie să îi foloseacă astfel: 
-   * pune pe cei **n sclavi** aleși la masă cu câte un pahar în mână, inițial gol 
-   * poruncește bucătarului să toarne vin în pahare, alegând cui și ce să toarne 
-   * unui sclav i poate turna în pahat vin din oricâte sticle (chiar și simultan) 
-   * după ce s-a turnat în **toate** cele n pahare, ei **vor bea toți simultan** 
-   * la finalul celor **24h** Gigel trebuie să își dea seama care este sticla otrăvită, altfel se va oftica și va pune 100 de sclavi să guste fiecare din câte o sticlă, iar pe cei care rămân în viață îi va împușca oricum pentru că e nervos 
- 
-P.S. Apreciați faptul că Gigel încearcă să nu omoare foarte mulți oameni degeaba. Ajutați-l să găsească $numărul minim n de sclavi$ care trebuie să guste din vin.  
- 
-Follow-up: Aceeași problemă, dar pentru n sticle. 
- 
-TODO: sursă ​       ​ 
- 
-<​note>​ 
-Hint: Reprezentarea numerelor în baza 2. 
-</​note>​ 
- 
-</​spoiler>​ 
  
 <spoiler Jocul NIM> ​ <spoiler Jocul NIM> ​
Line 742: Line 723:
 Enunt: [[http://​www.infoarena.ro/​problema/​sushi | sushi ]] Enunt: [[http://​www.infoarena.ro/​problema/​sushi | sushi ]]
 </​spoiler>​ </​spoiler>​
 +
programare/laboratoare/lab07.1541255922.txt.gz · Last modified: 2018/11/03 16:38 by darius.neatu
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