Documente Academic
Documente Profesional
Documente Cultură
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Probleme generale (aritmetica, vectori, matrici):
------------------------------------------------1.1 (puncte: 1.5)
Scrieti un program care citeste de la tastatura un numar natural si
scrie pe ecran toti divizorii sai primi.
Pentru a testa daca un numar este prim se va folosi o functie:
int prim(int n);
(returneaza: 1 daca n e prim, 0 daca nu e prim).
1.2 (puncte: 2.5)
Scrieti un program care citeste de la tastatura un numar natural si
scrie pe ecran descompunerea sa in factori primi
(de exemplu:
daca citeste 60, va afisa: 60 = 2^2 * 3 * 5
daca citeste 8, va afisa: 8 = 2^3
daca citeste 5, va afisa: 5 = 5
daca citeste 1, va afisa: 1 = 1
daca citeste 0, va afisa: 0 = 0)
1.3 (puncte: 1)
Scrieti un program care citeste de la tastatura 2 numere naturale si
verifica daca sunt prietene (i.e. fiecare este suma divizorilor
celuilalt, printre divizorii unui numar considerand si pe 1, dar
excluzand numarul insusi).
Exemple de numere prietene: k si k (cu k perfect), 220 si 284,
17296 si 18416.
Suma divizorilor se va calcula cu o functie:
int sumadiv(int n);
(returneaza suma divizorilor lui n).
1.4 (puncte: 1)
Scrieti un program care citeste de la tastatura un numar natural si
calculeaza suma cifrelor sale, folosind o functie:
int sumacif(int n);
(returneaza suma cifrelor lui n).
1.5 (puncte: 1.5)
Scrieti un program care citeste de la tastatura un numar natural si
calculeaza suma cifrelor sale de pe pozitii pare (pozitiile se vor
numara incepand de la cifra unitatilor).
Pentru a se putea lucra si cu numere mai mari, se va folosi pentru
numere intregi tipul "long int" (ale carui valori in Turbo C++ sunt de
la -2147483648 la 2147483647).
Exemple: pentru n = 12345, suma este 6 (= 4 + 2);
pentru n = 123456, suma este 9 (= 5 + 3 + 1).
Suma cifrelor de pe pozitii pare se va calcula cu o functie:
int sumacifpp(int n);
(returneaza suma cifrelor de pe pozitii pare ale lui n daca exista, sau
-1 daca nu exista).
1.6 (puncte: 1.5)
Scrieti un program care citeste de la tastatura un numar natural si
calculeaza suma cifrelor sale pare.
Suma cifrelor pare se va calcula cu o functie:
int sumacifp(int n);
(returneaza suma cifrelor pare ale lui n daca exista, sau -1 daca nu
exista).
1.7 (puncte: 1.5)
Scrieti un program care citeste de la tastatura un numar natural si
verifica daca este palindrom (i.e. daca citit si normal si invers
este la fel).
Se poate folosi tipul "unsigned long int" (ale carui valori in Turbo C++
sunt de la 0 la 4294967295), pentru a se putea lucra si cu numere mai
mari.
Exemple: 1 este palindrom;
12 nu este palindrom;
11 este palindrom;
123 nu este palindrom;
212 este palindrom;
42324 este palindrom;
42354 nu este palindrom;
Se poate folosi o functie:
unsigned long int rev(unsigned long int n);
care returneaza reversul unui numar natural dat ca parametru.
1.8 (puncte: 1)
Scrieti un program care citeste de la tastatura un numar natural n si
afisaza pe ecran toate tripletele de numere pitagoreice mai mici sau
egale cu n (adica triplete de numere naturale i j k astfel incat
i*i + j*j = k*k si i,j,k<=n), fara repetitii modulo ordinea (de ex.,
daca s-a afisat 3 4 5, nu se va afisa si 4 3 5). Numarul de calcule
efectuate trebuie sa fie cat mai mic.
1.9 (puncte: 1.5)
Scrieti un program pentru calculul cmmdc al doua numere naturale citite
de la tastatura, folosind algoritmul lui Euclid prin impartiri.
Aceeasi cerinta, dar folosind algoritmul lui Euclid prin diferente.
Pentru a calcula cmmdc se vor folosi functii:
int cmmdcimp(int a, int b);
int cmmdcdif(int a, int b);
(returneaza cmmdc lui a si b sau -1 daca a=b=0).
1.10 (puncte: 1.5)
Scrieti un program pentru rezolvarea ecuatiei de grad <=2 cu coeficienti
reali.
1.11 (puncte: 1)
Scrieti un program care citeste de la tastatura un numar natural n si
sa afiseze al n-lea termen al sirului lui Fibonacci, calculat cu o
functie:
unsigned long int fib(int n);
1.12 (puncte: 1.5)
De la tastatura se citesc doua numere naturale a si b (b>=2) si se
scrie pe ecran reprezentarea lui a in baza b. Cifrele in baza b vor fi
numerele 0, ... , b-1, scrise in baza 10 si puse intre paranteze daca
b>=11.
De exemplu:
daca b=7 si a=25, se va afisa: 34
daca b=12 si a=25, se va afisa: (2)(1)
daca b=12 si a=135, se va afisa: (11)(3)
1.13 (puncte: 0.5)
Scrieti un program care citeste de la tastatura 2 vectori de numere si
)
1.23 (puncte: 1.5)
Scrieti un program care citeste de la tastatura o matrice de numere
si calculeaza suma elementelor de pe "conturul" ei.
De exemplu, daca matricea este:
/ 1 2 3 4 \
| 5 6 7 8 |
\ 9 10 11 12 /
programul va afisa:
65
1.24 (puncte: 2)
Scrieti un program care citeste de la tastatura o matrice de numere
si inlocuieste cel mai mare element de pe fiecare coloana cu suma
elementelor de pe coloana respectiva. Daca pe o coloana valoarea maxima
se atinge in mai multe locuri, se va inlocui doar una din aparitii.
Exemplu: daca matricea este:
/ 1 2 4 3 \
| 5 2 3 3 |
\ 3 10 4 3 /
si facem conventia ca pe fiecare coloana inlocuim doar prima aparitie
a maximului, vom obtine:
/ 1 2 11 9 \
| 9 2 3 3 |
\ 3 14 4 3 /
1.25 (puncte: 2.5)
Scrieti un program care citeste de la tastatura o matrice de numere si
ordoneaza liniile acesteia astfel incat pe ultima coloana elementele
sa apara in ordine crescatoare. Matricea rezultata se va afisa.
Operatiile se vor face in aceeasi structura array (nu se vor considera
in program mai multe matrici).
Observatie importanta:
~~~~~~~~~~~~~~~~~~~~~
In problemele de mai sus se vor trata toate cazurile "speciale".
De exemplu, daca se cere suma elementelor pare dintr-un vector dat de
numere naturale iar vectorul respectiv nu contine numere pare, se
va tipari un mesaj, de tipul 'n-ar sens suma componentelor pare', si
nu se va scrie pur si simplu ca suma este 0.
2. Tipuri de date:
--------------2.1 (puncte: 2.5)
Scrieti o functie:
void replong(long n);
care afisaza octetii din reprezentarea interna a lui n de la stanga
la dreapta in ordinea descresterii semnificatiei, fiecare octet
reprezentandu-se ca doua cifre hexa; de exemplu pentru n=197121
(= 1 + 2*256 + 3*256*256) se va obtine:
00 03 02 01
si o functie:
long vallong(unsigned char c3, unsigned char c2,
unsigned char c1, unsigned char c0);
care returneaza long-ul ai carui octeti din reprezentarea interna sunt
in ordinea descresterii semnificatiei: c3, c2, c1, c0; de exemplu
vallong(0x00,0x03,0x02,0x01) va returna 197121.
Pentru descompunerea/compunerea long-ului din octeti se vor folosi doar
operatii pe biti.
Program ilustrativ.
2.2 (puncte: 1)
Scrieti un program care afisaza valorile maxime si minime ale diverselor
tipuri, date de constantele simbolice din limits.h si float.h.
2.3 (puncte: 2)
Scrieti o functie:
int citint(int n1, int n2);
care citeste intregi de la stdin pana intalneste unul >= n1 si <= n2;
daca la intrare apare un caracter ilegal, il consuma (citeste un
caracter) apoi incearca iar citirea intregului.
Program ilustrativ.
2.4 (puncte: 1)
Scrieti un program care deseneaza un tabel cu codurile ASCII zecimal,
octal, hexa ale caracterelor cu coduri cuprinse intre 32 si 255. Tabelul
va arata astfel:
------------------------------------------------| Caracter | Cod zecimal | Cod octal | Cod hexa |
|----------|-------------|-----------|----------|
...
...
...
...
|----------|-------------|-----------|----------|
|
A
|
65
|
101
|
41
|
|----------|-------------|-----------|----------|
...
...
...
...
|
|
|
|
|
------------------------------------------------2.5 (puncte: a se vedea in text)
Scrieti functii care primesc ca parametri doi intregi si returneaza suma
(0.5 puncte), diferenta (4 puncte), inmultirea (6 puncte), catul intreg
(10 puncte), respectiv restul impartirii lor intregi (10 puncte).
Se vor folosi doar operatii pe biti.
Program ilustrativ.
2.6 (puncte: 3)
Scrieti un program care citeste un intreg short si determina toti intregii
obtinuti din el prin permutarea circulara a bitilor. Acestia se vor afisa
cu reprezentarile lor externe zecimale si interne binare. Se vor afisa
permutarile circulare obtinute in ambele sensuri.
Pentru a efectua un pas de permutare circulara se vor folosi functiile:
short int rotbitstg(short int n);
short int rotbitdr(short int n);
00001011
00010110
00101100
01011000
10110000
01100000
11000000
10000000
00000000
00000000
00000000
00000000
00000000
00000001
00000010
00000101
Rotire la dreapta:
11: 00000000 00001011
-32763: 10000000 00000101
-16382: 11000000 00000010
24577: 01100000 00000001
-20480: 10110000 00000000
22528: 01011000 00000000
11264: 00101100 00000000
5632: 00010110 00000000
2816: 00001011 00000000
1408: 00000101 10000000
704: 00000010 11000000
352: 00000001 01100000
176: 00000000 10110000
88: 00000000 01011000
44: 00000000 00101100
22: 00000000 00010110
2.7 (puncte: 3)
Scrieti un program care citeste un intreg short si calculeaza intregul
short obtinut din el prin inversarea ordinii bitilor; programul va afisa
atat valorile cat si reprezentarile pe biti ale celor doi intregi.
Se va folosi o functie:
short int revint(short int n);
care returneaza intregul short obtinut din n prin inversarea ordinii
bitilor; aceasta se va face doar cu operatii pe biti.
Reprezentarile pe biti se vor afisa de la stanga la dreapta in ordinea
descrescatoare a semnificatie bitilor, folosind o functie.
De exemplu pentru intregul -32757 programul va afisa:
03
02
01
00
02
01
00
03
01
00
03
02
Rotire la dreapta:
197121: 00 03
16777986: 01 00
33619971: 02 01
50462976: 03 02
02
03
00
01
01
02
03
00
2.9 (puncte: 3)
Scrieti un program care citeste un intreg long si calculeaza intregul
long obtinut din el prin inversarea ordinii octetilor; programul va afisa
atat valorile cat si reprezentarile interne pe octeti ale celor doi
intregi.
Se va folosi o functie:
long int revoctint(long int n);
care returneaza intregul long obtinut din n prin inversarea ordinii
octetilor; aceasta se va face doar cu operatii pe biti.
Reprezentarile pe octeti se vor afisa de la stanga la dreapta in ordinea
descrescatoare a semnificatie octetilor (fiecare octet se va reprezenta
ca o pereche de cifre hexa), folosind o functie.
De exemplu pentru intregul 197121 programul va afisa:
197121: 00 03 02 01
16909056: 01 02 03 00
2.10 (puncte: 1)
Scrieti o functie:
int bitparsum(short int n);
Scrieti o functie:
int bitctl(int op, void *p, int bit);
care efectueaza urmatoarele operatii:
- daca op=1: seteaza bitul aflat la distanta "bit" (numar intreg oarecare)
de "p" la valoarea 1, apoi returneaza bitul vechi (1 sau 0, privit ca
intreg); bitii se parcurg a.i. dupa bitul 7 al octetului i urmeaza bitul
0 al octetului i+1.
- daca op=0: seteaza bitul aflat la distanta "bit" de "p" la valoarea 0,
apoi returneaza bitul vechi;
- daca op=-1: returneaza bitul aflat la distanta "bit" de "p", fara sa-l
modifice.
Accesarea/modificarea bitilor se va face doar cu operatii pe biti.
Program ilustrativ, care pentru niste numere efectueaza diverse modificari,
afisand numerele inainte si dupa modificare, atat ca valoare cat si ca
reprezentare pe biti (obtinuta cu o functie care afisaza bitii de la
stanga la dreapta in ordinea descresterii semnificatiei).
Exemplu:
int n=16707; (deci n are in locatie: 01000001 01000011)
bitctl(&n,2,14); ===> returneaza: 1
(deci returneaza valoarea bitului 2+12=14 de la adresa lui n).
3.5 (puncte: 2 + punctajul indicat in text)
Implementati tipul intreg pe un numar specificat (printr-o constanta
simbolica) de biti, in felul urmator:
#define DIM 10
typedef struct{unsigned char n[DIM];} intreg;
Valorile acestui tip se reprezinta intern prin complement fata de 2 pe cei
8*DIM biti ai locatiei, la fel ca la tipul int; astfel, intervalul
valorilor tipului va fi: -2^(8*n-1), ..., 2^(8*n-1)-1 (unde "^" inseamna
"la puterea").
Scrieti functii care implementeaza diverse operatii aritmetice cu acesti
intregi (operanzii sunt primiti ca parametri, rezultatul este valoarea
returnata); functiile vor folosi doar operatii pe biti.
Se vor implementa (nu e obligatoriu toate): adunarea (5 pct), scaderea
(5 pct), inmultirea (6 pct), aflarea catului intreg (10 pct), aflarea
restului (10 pct), luarea opusului (2 pct), testarea < (4 pct), testarea
<= (4 pct), testarea > (4 pct), testarea >= (4 pct), testarea == (1 pct),
testarea != (1 pct), atribuirea (1 pct), citirea cu format de la consola
(6 pct), scrierea cu format la consola (6 pct), conversia spre int
obisnuit (1 pct), conversia de la un int obisnuit (3 pct).
Program ilustrativ.
4. Pointeri si vectori:
-------------------4.1 (puncte: 2)
Scrieti o functie:
void memctl(int op, void *p, unsigned char *v, unsigned dim);
care efectueaza urmatoarele operatii:
- daca op=1: seteaza "dim" octeti incepand de la adresa "p" cu valorile
din vectorul "v";
- daca op=0: copiaza in componentele vectorului "v" "dim" octeti incepand
de la adresa "p".
Aplicatie: program care citeste un real float, apoi afla cu functia de mai
sus octetii din reprezentarea sa interna si-i afisaza (ca perechi de cifre
hexa, de la stanga la dreapta in ordinea descresterii semnificatiei), apoi
citeste sizeof(float) valori de octeti, ii pune cu functia de mai sus in
locatia unui real float, apoi afisaza realul obtinut.
4.2 (puncte: 2)
Scrieti functii pentru citirea unui vector de intregi, scrierea unui vector
de intregi, sortarea unui vector de intregi, cautarea unei valori intr-un
vector de intregi (returneaza 0: negasit, != 0: gasit), calcularea
diferentei intre maximul componentelor si minimul componentelor unui
vector de intregi (returneaza diferenta respectiva).
Functiile se vor scrie atat in varianta in care primesc ca parametri
adresa de inceput a vectorului (de tip int *) si numarul de componente
(de tip int), cat si in varianta in care primesc ca parametri toate
elementele vectorului incapsulate intr-o singura structura (de tip
struct vector{int n,v[10];};).
Program ilustrativ.
4.3 (puncte: 2)
Scrieti o functie:
int vals(int *s, int ds, int *d, int *dd);
care pune valorile distincte ce apar in vectorul "s" de dimensiune "ds"
in vectorul "d", iar in "*dd" numarul acestor valori; returneaza "*dd".
Program ilustrativ.
Sfat: Incercati sa rescrieti problemele cu vectori din sectiunea 1 a.i.
~~~~ sa repartizati cat mai mult operatiile unor functii, iar comunicarea
intre acestea si restul programului sa se faca doar prin intermediul
parametrilor si a valorii returnate.
5. Pointeri si matrici:
-------------------5.1 (puncte: 2)
Scrieti functii pentru citirea unei matrici dreptunghiulare de numere
intregi, afisarea unei asemenea matrici si suma a 2 asemenea matrici;
primele doua functii returneaza void, a treia returneaza un intreg care
este 0: esec (de exemplu matricile nu au aceleasi dimensiuni), != 0:
succes. Functiile vor primi matricile asupra carora opereaza ca parametri.
Se va implementa atat varianta in care functiile primesc ca parametri
adresa de inceput a matricii, numarul de linii si numarul de coloane, cat
si varianta in care primesc ca parametru o structura ce incapsuleaza toate
aceste trei elemente.
Program ilustrativ.
5.2 (puncte: 3.5)
Scrieti o functie care sorteaza liniile unei matrici dreptunghiulare de
intregi a.i. ele sa apara in ordinea lexicografica a sirului componentelor
lor. Ea va folosi o functie care va compara lexicografic doi vectori de
intregi (primeste ca parametri adresele de inceput ale vectorilor si
dimensiunile acestora (nu neaparat egale) si returneaza <0, ==0 sau >0
dupa cum primul vector este <, ==, respectiv > lexicografic ca al doilea)
si o functie care interschimba doi vectori de intregi de aceeasi
dimensiune (primeste ca parametri adresele de inceput ale vectorilor si
dimensiunea comuna).
Program ilustrativ.
5.3 (puncte: 3)
Scrieti o functie care primeste ca parametri doua matrici dreptunghiulare
de intregi (anume adresa de inceput si dimensiunile fiecareia) si verifica
daca prima apare ca bloc in a doua (ca submatrice cu linii si coloane
adiacente); returneaza 0: nu este, != 0; este.
Sfat: Incercati sa rescrieti problemele cu matrici din sectiunea 1 a.i.
~~~~ sa repartizati cat mai mult operatiile unor functii, iar comunicarea
intre acestea si restul programului sa se faca doar prin intermediul
parametrilor si a valorii returnate.
6. Pointeri si functii:
-------------------6.1 (puncte: 2)
Scrieti o functie:
void rep(unsigned char v);
care afisaza bitii continuti in "v" si in inca "n-1" octeti aflati in
memorie in continuare (unde "n" este o variabila intreaga globala);
grupele de biti corespunzatoare octetilor se separa prin blankuri, iar
afisarea se face de la stanga spre dreapta in ordinea descrescatoare a
semnificatiei octetilor si bitilor dintr-un octet.
Scrieti un program care apeleaza functia sub forma:
long l=1000000;
n=sizeof(l);
(*(void (*)(long))&rep)(l);
pentru a afisa octetii din reprezentarea interna a unui long.
Atentie ca este posibil ca programul sa nu functioneze corect pe anumite
compilatoare.
6.2 (puncte: 6)
Scrieti o functie care sa primeasca ca parametri:
- o functie reala cu valori reale: double f(double x);
- capetele unui interval real inchis: double a, double b;
- o scare de reprezentare pe orizontala si verticala: dx, dy
(reprezinta lungimea unui segment de pe abscisa, respectiv ordonata,
care pe ecran s-ar reprezenta printr-un singur caracter);
- o matrice de caractere: m si dimensiunile acesteia: l,c;
si deseneaza graficul functiei f:[a,b]->R la scara data de dx, dy, in mod
text, in matrica m; se vor desena si axele abscisa si ordonata, sub forma
unor linii orizontale, respectiv verticale, a.i. originea sa fie
aproximativ la mijlocul matricii; punctele de pe grafic se vor desena cu
caractere * (daca acest punct se nimereste pe o axa, se va desena punctul,
nu axa); cresterea coordonatelor orizontala si verticala in sistemul de
axe matematic sa fie in concordanta cu cresterea coloanei, respectiv
scaderea liniei, in matrice.
Matricea construita se va afisa apoi pe stdout cu o alta functie.
De exemplu pentru f(x) = x*x + 2*x - 3, a = -4, b = 4, dx = 0.5, dy = 2,
l = 10, c = 20, sa obtinem in matricea m:
|
*
|
*
| *
*
| *
----*-----|-*------*
|*
*****
|
|
|
6.3 (puncte: 2)
Scrieti o functie care sa primeasca ca parametri:
- o functie reala cu valori reale: double f(double x);
- capetele unui interval real inchis: double a, double b;
- o abatere maxima: double eps
se presupune ca f:[a,b]->R este continua, f(a)*f(b) < 0, iar in
intervalul [a,b] ecuatia f(x) = 0 are o solutie unica (pentru asta este
suficient sa avem in plus f strict monotona); se presupune de asemenea ca
eps > 0; functia trebuie sa returneze valoarea aproximativa a solutiei
ecuatiei f(x) = 0 din intervalul [a,b], cu o eroare < eps; in acest scop
va folosi metoda injumatatirii intervalului: se ia jumatatea c a
intervalului [a,b], daca f(c) = 0 se returneaza c, altfel avem f(c) > 0
sau f(c) < 0 si se inlocuieste [a,b] cu acela dintre intervalele [a,c] sau
[c,b] unde f ia valori de semne contrare in capete (el va contine cu
siguranta solutia cautata); se continua pana cand se intalneste solutia c
sau lungimea intervalului curent este < eps, caz in care se returneaza
unul din capetele sale, deoarece el aproximeaza solutia cu eroare < eps.
Program ilustrativ.
6.4 (puncte: 3)
Scrieti o functie care sa primeasca ca parametri:
- o functie reala cu valori reale: double f(double x);
- capetele unui interval real inchis: double a, double b;
- un numar de diviziuni: int n
se presupune ca f este integrabila pe intervalul [a,b] iar n >= 1; functia
trebuie sa returneze valoarea aproximativa a integralei lui f pe intervalul
[a,b], calculata cu metoda trapezului secant sumata cu n subintervale:
I = h * [f(a)/2 + f(b)/2 + f(a+h) + f(a+2*h) + ... + f(a+(n-1)*h)],
unde h=(b-a)/n.
Aplicatie: program care pentru niste functii si intervale date in codul sau
calculeaza integrala cu n = 1, 2, 3, ... pana cand rezultatele succesive
obtinute difera prin valori prea mici ca sa poata fi reprezentate in
calculator iar sirul rezultatelor pare ca stationeaza - atunci se va afisa
rezultatul obtinut.
6.5 (puncte: 12)
Scrieti o functie care sa primeasca ca parametri elementele folosite la
rezolvarea unei probleme prin backtracking: vectorul generat si
dimensiunea sa, functiile pentru initializarea unei componente, atribuirea
valorii urmatoare, testarea conditiilor de continuare, prelucrarea
solutiei, si aplica metoda backtracking cu aceste elemente; nu se vor
folosi date globale.
Aplicatie: cel putin doua programe pentru rezolvarea unor probleme prin
backtracking folosind aceasta functie (exemple: generarea permutarilor
unei multimi si asezarea a n dame pe o tabla de sah n x n a.i. sa nu se
atace).
O formalizare a metodei backtracking care poate fi solosita se gaseste in
cartea "Tehnici de programare, manual pentru clasa a X-a", autor Tudor
Sorin, ed. L&S INFOMAT, 1996.
6.6 (puncte: 3) Scrieti o functie generica de sortare, avand ca parametri:
- adresa vectorului de sortat, de tip void *
- dimensiunea unei componente, de tip unsigned;
- numarul componentelor, de tip unsigned;
- adresa functiei care compara doua elemente, componente ale vectorului;
Program ilustrativ.
7.13 (puncte: 2)
Simulati functia itoa (din TC++ - converteste intreg in string), folosind
doar operatii de vectori si pointeri. Program ilustrativ.
7.14 (puncte: 0.5)
Scrieti o functie:
char *strconcat(const char *s1, const char *s2, char *d);
care pune in zona pointata de "d" concatenarea unor copii ale stringurilor
"s1" si "s2", apoi returneaza "d"; daca unul dintre "s1" sau "s2" e NULL,
efectul consta doar in copierea celuilalt string in zona pointata de "d",
apoi se returneaza "d"; daca "s1" si "s2" sunt NULL sau daca "d" e NULL,
nu face nimic si returneaza NULL. Se vor folosi doar operatii de vectori
si pointeri.
Program ilustrativ.
7.15 (puncte: 2)
Scrieti functiile:
char *sscanfi(const char *s, int *n);
char *sprintfi(char *s, int n, size_t dim);
a.i. prima citeste in "*n" un intreg a carui reprezentare externa
zecimala este data in stringul "s" (asemeni lui sscanf cu %d), iar a doua
scrie intregul "n" in format extern zecimal in stringul "s" (asemeni lui
sprintf cu %d) a.i. sa nu depaseasca "dim" caractere incepand de la
pozitia curenta; prima va returna adresa primului caracter din "s" de
dupa intregul citit sau NULL daca nu s-a putut citi; a doua va returna
adresa primului caracter din "s" de dupa intregul scris sau NULL daca nu
a incaput complet in cele "dim" pozitii; se vor folosi doar operatii de
vectori si pointeri.
Program ilustrativ.
7.16 (puncte: 1)
Simulati functia strrev (din TC++ - schimba ordinea caracterelor dintr-un
string), folosind doar operatii de vectori si pointeri.
Program ilustrativ.
7.17 (puncte: 1)
Simulati functiile strupr si strlwr (din TC++ - converteste toate literele
mici in mari, respectiv mari in mici, intr-un string, lasand restul
caracterelor neschimbate), folosind doar operatii de vectori si pointeri.
Program ilustrativ.
7.18 (puncte: 1.5)
Scrieti o functie:
char *strsort(char *s);
care sorteaza caracterele din stringul "s"; returneaza "s"; se vor folosi
doar operatii de vectori si pointeri.
Program ilustrativ.
7.18 (puncte: 2)
Scrieti o functie:
char *getnword(char *d, const char *s, int n);
/* S */
inits(lista *l);
initsc(listac *l);
initd(listad *l);
initdc(listadc *l);
golestes(lista *l);
golestesc(listac *l);
golested(listad *l);
golestedc(listadc *l);
vidas(lista *l);
vidasc(listac *l);
vidad(listad *l);
vidadc(listadc *l);
citestes(lista *l);
citestesc(listac *l);
citested(listad *l);
citestedc(listadc *l);
void
void
void
void
scries(lista *l);
scriesc(listac *l);
scried(listad *l);
scriedc(listadc *l);
"*d" este lista destinatie, "*s" este lista sursa; lista sursa ramane
nemodificata; returneaza: 1 = succes, 0 = esec (de exemplu nu s-a putut
aloca memorie);
- (2 puncte) concatenarea unei copii a unei liste la sfarsitul altei liste:
int concateneazas(lista *d, lista *s);
int concateneazad(listad *d, listad *s);
se concateneaza o copie a listei "*s" la sfarsitul listei "*d"; lista
"*s" ramane nemodificata; returneaza: 1 = succes, 0 = esec (de exemplu
nu s-a putut aloca memorie).
Program ilustrativ.
9.2 (puncte: 1 + punctajul indicat in comentariile din text)
Scrieti functii pentru copierea unei liste in alta lista, cu conversie
intre tipuri de lista diferite:
int
int
int
int
int
int
/*
/*
/*
/*
/*
/*
1.5 puncte */
0.5 puncte */
2 puncte */
1 punct */
1 punct */
1 punct */
"*d" este lista destinatie, "*s" este lista sursa; lista sursa ramane
nemodificata; returneaza: 1 = succes, 0 = esec (de exemplu nu s-a putut
aloca memorie); in cazul "sc2s" lista rezultata va incepe de la elementul
curent al listei sursa.
Program ilustrativ care citeste o lista, ii aplica toate conversiile
implementate, ajungand in final la o lista de aceelasi tip ca cel initial;
programul va afisa lista initiala si listele obtinute dupa fiecare
conversie.
9.3 (puncte: cele indicate in comentariile din text)
Scrieti functii pentru inversarea legaturilor dintr-o lista:
void
void
void
void
inverseaza(lista *l);
inverseazac(listac *l);
inverseazad(listad *l);
inverseazadc(listadc *l);
/*
/*
/*
/*
2 puncte */
2.5 puncte */
2.5 puncte */
3 puncte */
lungimes(lista *l);
lungimec(listac *l);
lungimed(listad *l);
lungimedc(listadc *l);
sorteaza(lista *l);
sorteazac(listac *l);
sorteazad(listad *l);
sorteazadc(listadc *l);
"*l" este lista; daca "*min" nu este NULL, in "*min" se va pune valoarea
minima; daca "*max" nu este NULL, in "*max" se va pune valoarea maxima;
functia returneaza 1 = succes, 0 = esec (de exemplu "*min" si "*max" nu
sunt NULL iar lista e vida); se va lucra direct pe structura listelor,
fara functii intermediare;
Program ilustrativ care citeste cate o lista de fiecare tip, determina
valorile minima si maxima din ele, apoi le afisaza.
9.7 (puncte: cate 0.5 pentru fiecare functie)
Scrieti functiile urmatoare, care determina numarul aparitiilor unei valori
intr-o lista:
int
int
int
int
"*l" este lista; "val" este valoarea cautata; functiile returneaza numarul
aparitiilor; se va lucra direct pe structura listelor, fara functii
intermediare.
Program ilustrativ care citeste cate o lista de fiecare tip, apoi un intreg
si determina de cate ori apare intregul respectiv in fiecare lista.
9.8 (puncte: cate 3 pentru fiecare pereche functie / program)
Scrieti functiile urmatoare, care parcurg o lista data ca parametru si
aplica fiecarui element o functie data de asemenea ca parametru:
int
int
int
int
"*l" este lista; "*f" este functia care se aplica fiecarui nod (ea
primeste ca parametru adresa campului "inf" al nodului respectiv);
functia de aplicare returneaza 1 daca fiecare apel al lui "*f" a returnat
ceva diferit de 0 si 0 altfel; se va lucra direct pe structura listelor,
fara functii intermediare.
Program ilustrativ care citeste doua liste, apoi parcurge pe prima si
numara de cate ori apare valoarea elementului curent in a doua;
parcurgerea se va realiza cu functia de aplicare de mai sus, iar
functia transmisa ca parametru va numara de cate ori apare elementul
curent in a doua lista (data globala) si va afisa elementul si numarul
sau de aparitii; se va scrie cate o varianta a programului pentru fiecare
tip de lista S, SC, D, DC.
9.9 (puncte: cate 1 pentru fiecare functie)
Scrieti functiile urmatoare:
int
int
int
int
a.i. daca "*nou" nu este NULL inlocuiesc in lista "*l" toate aparitiile
valorii "vechi" cu valoarea "*nou"; daca "*nou" este NULL, se elimina
toate aparitiile valorii "vechi"; functia returneaza numarul inlocuirilor,
respectiv eliminarilor efectuate sau -1 in caz de eroare (de exemplu nu
s-a putut aloca memorie); se va lucra direct pe structura listelor, fara
functii intermediare, si se vor elimina/insera noduri cu totul, fara a
modifica informatia din nodurile existente.
Program ilustrativ, care citeste niste liste, le modifica cu functiile de
mai sus, apoi afisaza listele rezultate.
9.10 (puncte: cele indicate in comentariile din text)
Scrieti functiile urmatoare:
int cauta(lista *l, int op, int val);
int cautad(listad *l, int op, int val);
/* 1.5 puncte */
/* 0.5 puncte */
care daca "op" > 0 returneaza pozitia celei de-a "op"-a aparitii a valorii
"val" in lista numarand de la inceput, iar daca "op" < 0 returneaza
pozitia celei de-a "op"-a aparitii a valorii "val" in lista numarand de la
sfarsit; valorile valide ale lui "op" sunt 1, 2, ..., -1, -2, ..., iar
pozitiile in lista sunt numere de la 0 la lungimea listei - 1; in caz de
eroare (de exemplu nu se gasesc cel putin "op" aparitii ale valorii "val"
in lista sau "op" este egal cu 0) se va returna -1; se va lucra direct pe
structura listelor, fara functii intermediare.
Program ilustrativ care citeste o lista si un intreg, apoi pentru un "i" de
la 1 la lungimea listei se va afisa pozitia a "i"-a a intregului in lista,
numarand atat de la inceput cat si de la sfarsit.
9.11 (puncte: cele indicate in comentariile din text)
Scrieti functiile urmatoare:
int
int
int
int
/*
/*
/*
/*
1.5 puncte */
2 puncte */
1.5 puncte */
2 puncte */
care insereaza valoarea "nou" inaintea valorii "vechi" daca "op" > 0 si
dupa valoarea "vechi" daca "op" < 0, in lista "*l"; se vor face cel mult
modul de "op" inserari (daca "vechi" nu apare de suficiente ori in lista,
vor fi mai putine inserari); in cazul listelor circulare se va cauta
"vechi" incepand de la pozitia curenta si nu se va face mai mult de un tur
complet al listei; functia va returna numarul inserarilor facute sau -1 in
caz de eroare (de exemplu nu s-a putut aloca memorie); se va lucra direct
pe structura listelor, fara functii intermediare.
Program ilustrativ (va trata fiecare tip de lista si vor afisa listele
rezultate).
9.12 (puncte: cate 1.5 pentru fiecare functie)
Scrieti functiile urmatoare:
int
int
int
int
a.i. daca "*n" nu este NULL inlocuiesc in lista "*l" toate aparitiile
listei "*v" ca sublista cu o copie a listei "*n"; daca "*n" este NULL, se
elimina din "*l" toate aparitiile listei "*v" ca sublista; functia
returneaza numarul inlocuirilor, respectiv eliminarilor efectuate, sau -1
in caz de eroare (de exemplu nu s-a putut aloca memorie); sublista
inseamna ca valorile din "*v" apar incepand de la o anumita pozitie si in
"*l", adiacent, in aceeasi ordine; desi in toate cazurile "*v" si "*n"
sunt S, in urma inlocuirii lista "*l" rezultata trebuie sa fie de acelasi
tip (S, SC, D, DC) ca inainte; "*v" si "*n" nu se vor modifica; se va
lucra direct pe structura listelor, fara functii intermediare si se vor
elimina/insera noduri cu totul, fara a modifica informatia din nodurile
existente; nodurile portiunilor eliminate din "*l" se vor dezaloca.
Program ilustrativ, care citeste niste liste, le modifica cu functiile de
mai sus, apoi afisaza listele rezultate.
9.14 (puncte: cele indicate in comentariile din text)
Scrieti functiile urmatoare:
int lcauta(lista *l, int op, lista *s);
int lcautad(listad *l, int op, lista *s);
/* 4 puncte */
/* 1.5 puncte */
care daca "op" > 0 returneaza pozitia celei de-a "op"-a aparitii a listei
"*s" ca sublista in "*l" numarand de la inceput, iar daca "op" < 0
returneaza pozitia celei de-a "op"-a aparitii a listei "*s" ca sublista
in "*l" numarand de la sfarsit; sublista inseamna ca valorile din "*s"
apar incepand de la o anumita pozitie si in "*l", adiacent, in aceeasi
ordine; valorile valide ale lui "op" sunt 1, 2, ..., -1, -2, ..., iar
pozitiile in lista sunt numere de la 0 la lungimea listei - 1; in caz de
eroare (de exemplu nu se gasesc cel putin "op" aparitii sau "op" este egal
cu 0) se va returna -1; atentie ca in toate cazurile "*s" este S; "*l" si
"*s" nu se vor modifica; se va lucra direct pe structura listelor, fara
functii intermediare.
Program ilustrativ care citeste cate o lista S si D, apoi o lista S si
pentru un "i" de la 1 la lungimea primelor liste se va afisa pozitia a
"i"-a a ultimei liste in ele ca sublista, numarand atat de la inceput cat
si de la sfarsit.
9.15 (puncte: cele indicate in comentariile din text)
Scrieti functiile urmatoare:
int lid(lista *l, int nr, int vechi, lista *n);
int lidc(listac *l, int nr, int vechi, lista *n);
int lidd(listad *l, int nr, int vechi, lista *n);
/* 2.5 puncte */
/* 3 puncte */
/* 2.5 puncte */
/* 3 puncte */
care insereaza cate o copie a listei "*n" inaintea valorii "vechi" daca
"op" > 0 si dupa valoarea "vechi" daca "op" < 0, in lista "*l"; se vor
face cel mult modul de "op" inserari (daca "vechi" nu apare de suficiente
ori in lista, vor fi mai putine inserari); in cazul listelor circulare se
va cauta "vechi" incepand de la pozitia curenta si nu se va face mai mult
de un tur complet al listei; functia va returna numarul inserarilor
facute sau -1 in caz de eroare (de exemplu nu s-a putut aloca memorie);
"*n" nu se modifica; atentie ca in toate cazurile "*n" este S, iar
in urma inlocuirii lista "*l" rezultata trebuie sa fie de acelasi tip (S,
SC, D, DC) ca inainte; se va lucra direct pe structura listelor, fara
functii intermediare.
Program ilustrativ (va trata fiecare tip de lista si vor afisa listele
rezultate).
9.16 (puncte: 1 + punctajul indicat in text)
Scrieti functiile urmatoare:
- (2 puncte) functii ce returneaza o sublista de lungime data care incepe
de la o pozitie data:
int sublista(lista *l, int i, int lungime, lista *s);
int sublistad(listad *l, int i, int lungime, lista *s);
"*l" este lista, "i" este pozitia (de la 0 la lungimea listei - 1),
"lungime" este lungimea sublistei, in "*s" se va pune o copie a sublistei
lui "*l" de lungime cel mult "lungime" care incepe de la pozitia "i";
daca "*l" nu contine suficiente elemente, se va copia o sublista mai
scurta; sublista inseamna lista de elemente care apar adiacent in "*l";
in caz de succes functia returneaza lungimea sublistei copiate, iar in
caz de esec (de exemplu "i" este o pozitie in afara listei, "*s" e NULL
sau "*l" sau nu s-a putut aloca memorie) returneaza -1 si elibereaza
elementele deja alocate pentru "*s"; "*l" nu se modifica; atentie in
toate cazurile "*s" este S; se va lucra direct pe structura listelor,
fara functii intermediare;
- (3 puncte) functii ce insereaza o lista in alta lista ca sublista,
incepand de la o pozitie data:
int linsereaza(lista *l, int i, lista *s);
int linsereazad(listad *l, int i, lista *s);
"*l" este lista, "i" este pozitia (de la 0 la lungimea listei - 1), iar
functia va insera o copie a lui "*s" in "*l" de la pozitia "i"; copia
inserata este implementata S sau D ca "*l", desi in toate cazurile "*s"
este S; functia returneaza 1 = succes, 0 = esec (de exemplu "i" este o
pozitie in afara listei sau nu s-a putut aloca memorie) - in acest caz
se elibereaza elementele deja alocate pentru copia inserata, iar "*l" nu
se modifica; "*s" nu se modifica; se va lucra direct pe structura
listelor, fara functii intermediare;
- (3 puncte) functii ce elimina sublista ce incepe de la o pozitie data si
are o lungime data:
int lelimina(lista *l, int i, int lungime, lista *s);
int leliminad(listad *l, int i, int lungime, lista *s);
"*l" este lista, "i" este pozitia (de la 0 la lungimea listei - 1),
"lungime" este lungimea sublistei; daca "*s" nu este NULL, in "*s" se va
recupera sublista eliminata; daca de la pozitia indicata pana la
sfarsitul lui "*l" nu sunt suficiente elemente, se va elimina/recupera o
sublista mai scurta; in caz de succes functia returneaza lungimea
/* 3 puncte */
/* 1.5 puncte */
/* AB */
/* A */
* 10
/ \
/ \
20 *
* 30
/
/
40 *
se va afisa: 10
|-- 20
| |-- .
| \-- .
\-- 30
|-|
|
\--
40
|-- .
\-- .
.
se va afisa: 1
|-|-|
|
\--
* 1
/|\
/ | \
/ | \
2 * * 3 * 4
/ \
\
/ \
\
* 5 * 6 * 7
2
3
|-- 5
\-- 6
4
\-- 7
* 10
/ \
20 *
* 30
/
/
40 *
secventele sunt: preordine: 10 20 30 40
inordine: 20 10 40 30
postordine: 20 40 30 10
pentru un A nevid, secventa nodurilor in A-pre/A-post ordine este
respectiv RF, FR (unde R este nodul radacina iar F este secventa (eventual
vida a) secventelor nodurilor subarborilor fiu, parcuresi in acceeasi
A-pre/A-post ordine); aici nu mai avem inordine deoarece nu stim intre
care fii sa inseram radacina;
de exemplu pentru arborele oarecare:
* 1
/|\
/ | \
/ | \
2 * * 3 * 4
|
|
* 5
1 *
/
/
/
2 * --|
|
.
---- .
3
4
===>
* --- * --- . <===
|
|
|
|
| 7 * --- .
|
|
|
|
|
.
|
|
5 * --- * --- .
| 6 |
|
|
.
.
1 *
/
/
2 *
\
\
* 3
/ \
/ \
5 *
\
\
\
\
6 *
* 4
/
/
7 *
10.8 (puncte: 8)
Scrieti functia:
int insabs(arboreb *a, int x);
care insereaza un nod nou avand informatia "x" in arborele "*a" privit ca
arbore de sortare; intr-un arbore (binar) de sortare, pentru fiecare nod
informatia asociata este mai mare sau egala decat informatiile asociate
nodurilor din subarborele sau stang si mai mica sau egala decat
informatiile asociate nodurilor din subarborele sau drept - astfel o
parcurgere in inordine a sa genereaza secventa informatiilor asociate
nodurilor in ordine crescatoare; inserarea unui nod nou intr-un asemenea
arbore presupune cautarea (eventual recursiva) de la radacina spre frunze
a unui loc unde poate fi inserat nodul a.i. sa se pastreze regula
referitoare la inegalitatea informatiilor; functia va returna:
1 = succes, 0 = esec (de exemplu nu s-a putut aloca memorie la stive) - in
acest caz "*a" ramane nemodificat.
Scrieti functie:
int abssort(int *v, int n);
care sorteaza vectorul ce incepe de la adresa "v" (presupus deja existent)
si avand "n" componente folosind un arbore de sortare construit in
interior - acesta este initial vid, apoi incarcat succesiv cu elementele
din vector folosind functia dinainte, apoi in vector se pune secventa
informatiilor din arbore in inordine iar arborele se dezaloca; functia
returneaza: 1 = succes, 0 = esec (de exemplu nu s-a putut aloca memorie
pentru arbore) - in acest caz vectorul ramane nemodificat.
Program ilustrativ care citeste un vector si afisaza vectorul sortat.
10.9 (puncte: 2)
Scrieti functiile urmatoare, care determina numarul aparitiilor unei valori
intr-un arbore:
int numaraparitiiab(arboreb *a, int val);
int numaraparitiia(arbore *a, int val);
"*a" este lista; "val" este valoarea cautata; functiile returneaza numarul
aparitiilor; "*a" ramane nemodificat.
Program ilustrativ care citeste cate un arbore de fiecare tip, apoi un
intreg si determina de cate ori apare intregul respectiv in fiecare
arbore.
10.10 (puncte: 6)
Scrieti functia urmatoare care plecand de la secventele informatiilor
asociate nodurilor unui AB in preordine si inordine reconstituie arborele:
int pi2ab(const int *p, const int *i, int n, arboreb *a);
"p" si "i" sunt adresele vectorilor ce contin secventele in preordine,
respectiv postordine (parametri de intrare, vectorii raman in final
nemodificati), "n" este numarul de componente ale fiecaruia, "*a" este
un parametru de iesire in care se va pune adresa radacinii arborelui
construit; functia returneaza: 1 = succes, 0 = esec (de exemplu nu s-a
putut aloca memorie pentru arbore).
Program ilustrativ care citeste secventa informatiilor in preordine si
inordine si afisaza AB corespunzator (de exemplu prin expresii cu
paranteze complete).
Varianta: incercati ca plecand de la cele doua secvente sa obtineti