Probleme pentru examenul de licenţă - INFORMATICĂ
Introducere în programarea calculatoarelor / Tehnici de programare (1)
1. Daţi o soluţie recursivă, în limbajul de programare C, pentru Algoritmul lui Euclid de aflare a
celui mai mare divizor comun a două numere întregi.
Formularea în cuvinte a algoritmului este următoarea:
Dacă unul dintre numere este zero, c.m.m.d.c. al lor este celălalt număr.
Dacă nici unul dintre numere nu este zero, atunci c.m.m.d.c. nu se modifică dacă se înlocuieşte
unul dintre numere cu restul împărţirii sale cu celălalt.
2. Să se scrie o funcţie care inversează conţinutul unui şir de caractere; şirul iniţial va fi returnat ca
rezultat al apelului funcţiei. Se vor folosi operaţii cu pointeri.
3. Scrieţi, în C, un program care să creeze un fişier copie a unui fişier dat.
SOLUŢII
1. unsigned cmmdc (unsigned m, unsigned n)
{
if (n==0)
return m;
else
return cmmdc(n, m%n);
}
2. char *strrev (char *sir)
{
char *initial = sir;
char *urmator = sir;
char temp;
while (*sir) sir++;
while (urmator < sir)
{
temp = *(--sir);
*sir = *urmator;
*urmator++ = temp;
}
return (initial);
}
3.
#include <stdio.h>
#include <stdlib.h>
void main()
{
int c;
char nume_sursa[80], nume_dest[80];
FILE *fs,*fd;
printf("Introduceti numele fisierului sursa \n");
fgets(nume_sursa, 80, stdin);
printf("Introduceti numele fisierului copie \n");
fgets(nume_dest, 80, stdin);
if ((fs=fopen(nume_sursa, "r"))==NULL)
{
printf("Nu se poate deschide fisierul %s\n",
nume_sursa);
exit(1);
}
if ((fd=fopen(nume_dest, "w"))==NULL)
{
printf("Nu se poate deschide fisierul %s\n",
nume_dest);
exit(1);
}
while ((c=getc(fs))!=EOF)
putc(c, fd);
fclose(fs);
fclose(fd);
}
Fundamentele calculatoarelor (2)
1. Se considera numerele zecimale X=38 si Y=79. Se cere adunarea acestora in toate combinatiile de
semne corespunzatoare reprezentarilor binare de virgula fixa, precum si adunarea fara semn
corepunzatoare formatelor zecimale pe 4 biti.
2. Se consideră un format ipotetic de reprezentare a numerelor binare de virgulă flotantă pe 10 biţi
partiţionaţi astfel: de la stânga la dreapta: 1 bit de semn, 3 biţi de exponent şi 6 biţi de mantisă.
Admiţând că sunt adoptate convenţiile standardului IEEE 754 la formatul dat, să se determine câmpurile
de reprezentare tolerate.
3. Admiţând că sunt date două numere binare pe 2 biţi, A=a1a0 si B=b1b0. Se cere sinteza unui dispozitiv
de înmulţire combinaţional uzitând de circuitele ŞI-NU cu 2 şi 3 intrări şi circuite inversoare.
R:
1. Semn Marime Identic C1 si C2
+38 = 0. 0 1 0 0 1 1 0 +
+79 = 0. 1 0 0 1 1 1 1
0. 1 1 1 0 1 0 1 = +117
Semn Marime Complement de 1 (C1)
+38 = 0. 0 1 0 0 1 1 0 + 0. 0 1 0 0 1 1 0 +
-79 = 1. 1 0 0 1 1 1 1 1. 0 1 1 0 0 0 0
1. 1 1 1 0 1 0 1 = -117 1. 1 0 1 0 1 1 0
Raspuns Gresit (se impune verificare de semn) =-41 in C1 (corect)
Complement de 2 (C2)
+38 = 0. 0 1 0 0 1 1 0 +
-79 = 1. 0 1 1 0 0 0 1
1. 1 0 1 0 1 1 1
=-41 in C2 (corect)
Semn Marime Complement de 1 (C1)
-38 = 1. 0 1 0 0 1 1 0 + 1. 1 0 1 1 0 0 1 +
+79 = 0. 1 0 0 1 1 1 1 0. 1 0 0 1 1 1 1
1. 1 1 1 0 1 0 1 = -117 1 0. 0 1 0 1 0 0 0 +
Raspuns Gresit (se impune verificare de semn) End around carry 1
0. 0 1 0 1 0 0 1 = 41
Complement de 2 (C2)
-38 = 1. 1 0 1 1 0 1 0 +
+79 = 0. 1 0 0 1 1 1 1
1 0. 0 1 0 1 0 0 1
=-41 in C2 (corect)
Semn Marime Complement de 1 (C1)
-38 = 1. 0 1 0 0 1 1 0 + 1. 1 0 1 1 0 0 1 +
-79 = 1 1 0 0 1 1 1 1 1. 0 1 1 0 0 0 0
1 0. 1 1 1 0 1 0 1 = +117 1 1. 1 0 0 1 0 0 1 +
Fals End around carry 1
1. 1 0 0 1 0 1 0 = -117
Complement de 2 (C2)
-38 = 1. 1 0 1 1 0 1 0 +
-79 = 1. 0 1 1 0 0 0 0
1 1. 1 0 0 1 0 1 1
=-117 in C2 (corect)
1 1
38 = 0011 1000 + 0110 1011
79 = 0111 1001 1010 1100
1011 1 0001 + 1 0001 1 0111 +
0110 0110 0011 0011
1 0001 0111 1 0100 1010
=117 (zecimal) =117 (zecimal)
2. Translatarea convenţiilor standardului IEEE 754 la cazul dat conduce la:
Es x 3N 1 2 1.M
, unde E0 x 7
7 31 2 3 6
7
41
1 2
1 1 1 1x 2 1
2 2 2 2
11
2x 2
11
2
127 1x 32
42
0 32
2
x 2 1 0 0
1x
8
3
4
1x
8
127x
4
3. Tabel de adevar
intrări ieşiri
a1 a0 b1 b0 c3 c2 c1 c0
0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 1 0 0 0 0 0
0 0 1 1 0 0 0 0
0 1 0 0 0 0 0 0
0 1 0 1 0 0 0 1
0 1 1 0 0 0 1 0
0 1 1 1 0 0 1 1
1 0 0 0 0 0 0 0
1 0 0 1 0 0 1 0
1 0 1 0 0 1 0 0
1 0 1 1 0 0 1 1
1 1 0 0 0 0 0 0
1 1 0 1 0 0 1 1
1 1 1 0 0 1 1 0
1 1 1 1 1 0 0 1
0
1
2
3
c 5,7,11,13,15
c 6,7,9,11,13,14
c 10,14
c 15
În urma minimizării rezultă:
0 1 0 1 0 1 0 1 0 0 1 0 1 0 0
1 1 1 0 1 0 0 1 0 1 0 1 0
2 1 1 0
3 1 0 1 0
c a a b b a a b b a b b a a b
c a b b a a b a a b a b b
c a b b
c a a b b
0 1 0 1 0 1 0 1 0 0 1 0 1 0 0
1 1 1 0 1 0 0 1 0 1 0 1 0
2 1 1 0
3 1 0 1 0
c a a b b a a b b a b b a a b
c a b b a a b a a b a b b
c a b b
c a a b b
Structuri de date şi algoritmi (3)
1. Să se definească următoarele TDA-uri:
A1-articol : strada(max 19 caractere), nr(int), localitate(max 19 caractere);
A2-articol : nume(19 caractere), adresa(A1);
Sa se implementeze funcţia care ordonează alfbetic după nume, folosind sortarea prin
selectie, un tablou de articole de tip A2 (de dimensiune 10) .Prototipul funcţiei este:
void ordonare_selectie(A2 tablou[]); Obs: Se va folosi limbajul de programare C.
(15 minute)
Rezolvare: #include <string.h> …. #define N 10 typedef struct{ char strada[20]; int numar; char localitate[20]; }A1; typedef struct{ char nume[20]; A1 adresa; }A2; void ordonare_selectie(A2 tablou[]){ A2 aux; int i,j,k; char nume_k[20]; for (i=0;i<N;i++){ k=i; aux=tablou[i]; for(j=i+1;j<N;j++) if(strcmp(aux.nume, tablou[j].nume)>0){ k=j; aux=tablou[j]; } aux=tablou[k]; tablou[k]=tablou[i]; tablou[i]=aux; } }
2. Se consideră tipul de dată abstract listă simplu înlănţuită ordonată, implementată cu ajutorul
pointerilor.
typedef struct nod{
char nume[10]; struct nod* urm; }nod; Să se implementeze operatorii de:
inserarea unui nod în lista simplu înlănţuită
nod* adaugare(nod*, nod*);
Obs: Se va folosi limbajul de programare C. (15minute) Rezolvare: #include<stdio.h> #include<string.h> …. typedef struct nod{ char nume[10]; struct nod*urm; } nod; nod* adaugare(nod*lista, nod*q){ nod*q1,*q2; for(q1=q2=lista;q1!=NULL&&strcmp(q1->nume,q->nume)<0;q2=q1,q1=q1->urm); if(strcmp(q1->nume,q->nume)==0){ printf("\nNodul a fost introdus in lista"); free(q); return lista; } if(q1==q2){ q->urm=lista; lista=q; } else{ q2->urm=q; q->urm=q1; } return lista; }
3.Fişierul evidenta.txt conţine:
NumeProdus Producator Defect NrPieseInlocuite PieseInlocuite NumeProdus-sir de 9caractere Producator-sir de 9 caractere Defect-sir de 9 caractere NrPieseInlocuite -int PieseInlocuite -tablou siruri de caractere, maxim 10 siruri de 9 caractere
Să se definească următoarele TDA-uri:
A1-articol cu câmpurile : Prod,TipDefect, NrPieseInloc, PieseInloc; A2- articol cu câmpurile : NumeProd, inf(A1); Să se implementeze funcţia ce caută un produs într-un tablou de articole de tip A2 (de
dimensiune 10) folosind tehnica fanionului. .Prototipul funcţiei este:
void Tehnica_Fanion(A2 tablou[], char*nume); Obs: Se va folosi limbajul de programare C.
(15minute)
Rezolvare: #include <string.h> …… #define N 11 typedef struct{ char Prod[10]; char TipDefect[10]; int NrPieseInloc; char PieseInloc[10][10]; }A1; typedef struct{ char NumeProd[10]; A1 Inf; }A2; void Tehnica_Fanion(A2 tablou[], char*nume){ int i=0; int n=strlen(nume); if (n<=9){ strcpy(tablou[N-1].NumeProd, nume); while(strcmp(tablou[i].NumeProd, nume)!=0) i++; if(i<N-1)printf("Produsul cautat se afla pe pozitia %d",i); else printf("Elementul nu a fost gasit"); } else{ printf(“\n Sirul are mai mult de 9 caractere”); exit (1); } }
Arhitectura calculatoarelor (4)
1. Să se reprezinte valoarea -53,125 conform standardului IEEE 754, simplă precizie (32 de biți).
Rezolvare
Expresia reprezentării IEEE 754
S (1
bit)
E (8 biți) M (23 biți)
Convertim numărul 53,125 în binar.
Normalizăm mantisa.
M reprezintă biți aflați după virgulă. Bitul 1 din fața virgulei fiind bitul ascuns.
M = 10101001
Exponentul reprezintă valoare puterii lui 2 după normalizare, plus bias-ul (în acest caz 127).
E = 5 + 127 = 132
Convertim valoarea 132 în binar.
Bitul de semn este 1 deoarece semnul este minus.
Rezultatul este:
S (1
bit)
E (8 biți) M (23 biți)
1 1000 0100 1010 1001 0000 0000 0000 000
2. Să se calculeze valoarea zecimală pentru următorul șablon de biți exprimați conform standardului
IEEE 754:
1 1000 0011 1010 1100 0000 0000 0000 000
Rezolvare
Expresia reprezentării IEEE 754
S (1
bit)
E (8 biți) M (23 biți)
1 1000 0011 1010 1100 0000 0000 0000 000
Transformăm exponentul din binar în zecimal
Înlocuim valorile în expresia reprezentării standardului IEEE 754
3. Să se scrie o secvență de cod, în limbaj de asamblare, care preia numere de la tastatură și face
suma acestora până la introducere valorii 0. Rezultatul se va afișa pe poziția a 7-a a ecranului. Pentru
preluare numerelor de la tastatură se va folosi întreruperii INT 08H. Pentru afișarea numerelor se va
folosi întreruperea INT 09H.
Rezolvare
MOV BL, 00H : se inițializează BL cu valoarea 0
LOOP:INT 08H ; se stochează valoarea introdusă de la
;tastatură în registrul AL
ADD BL, AL ; se adună valoarea din AL la valoarea din BL
CMP AL, 00H ; se compară conținutul registrului AL cu 0
JNZ LOOP ; dacă flag-ul zero nu este activ atunci se
;sare la LOOP
MOV AL, BL ; se mută rezultatul în registrul AL
MOV CL, 07H ; se încarcă conținutul lui CL cu valoarea 7
INT 09H ; se va afișa valoarea din registrul AL pe
;poziția 7 (care este stocată în registrul CL)
Sisteme de operare (5)
1: Realizaţi un program în C ce funcţionează pe baza următorului scenariu: Un proces P
afişeaza cifre de la 0 la 9. Va începe afişarea cu cifra 0 (cifra va fi afişată în buclă de câte ori e
posibil într-o secundă) iar la fiecare secundă va incrementa cifra afişată. Procesul de afişare se
va încheia când se ajunge la 10 şi va afişa numărul total de cifre tipărite.
Rezolvare:
#include<unistd.h> #include<signal.h> #include<sys/wait.h> #include<sys/types.h> void handler(int sig); int number, counter; int main(int argc, char** argv){ number = 0; counter = 0; signal(SIGALRM, &handler); alarm(1); while(number < 10) { printf("%d", number); counter++; } printf("Total:%d", counter); return 0; } void handler(int sig){ number++; alarm(1); }
2: Realizaţi un program C ce funcţionează pe baza următorului scenariu: Un proces părinte P şi
un proces fiu F. Procesul P va citi un fişier primit ca şi argument şi îl va trimite printr-un pipe
procesului F. F va număra caracterele primite într-un contor pe care îl va afisa în terminal.
Rezolvare:
#include<stdio.h> #include<string.h> #include<unistd.h> #include<fcntl.h>
int main(int argc, char**argv){ int ppf[2];//pipes int fd;//file descriptor char buffer[2]; pipe(ppf); if(fork()){ //close unused pipe ends close(ppf[0]); //open file fd = open(argv[1], O_RDONLY); if(fd == -1){ perror("File read error"); _exit(1); } int n; while((n = read(fd,buffer, strlen(buffer)+1)) != 0){ write(ppf[1], buffer, n); } close(ppf[1]); int rc; wait(&rc); }else{ //close pipe ends close(ppf[1]); int contor = 0,n; while((n = read(ppf[0],buffer, strlen(buffer)+1)) != 0){ contor += n; } printf("\nContor:%d\n",contor); } return 0; }
3: Realizaţi un program shell script ce va primi ca şi argument un nume de director D şi un
cuvânt C. Programul va căuta cuvântul C parcurgând recursiv directorul D iar pentru fiecare
fişier întâlnit care conţine cuvântul C va afişa calea relativă a acestuia.
Rezolvare:
#!/bin/sh word=$2 lst(){ for i in $1/* do if [ -d $i ] then lst $i elif [ -f $i ] then count=`grep $word $i | wc -l` if [ $count -gt 0 ] then echo $i fi fi done } lst $1
Programare orientată pe obiecte (6)
1. Într-o aplicaţie de conducere de proces se utilizează senzori de tip analogic şi optic. Toţi
senzorii trebuie resetaţi şi calibraţi, respectiv periodic citiţi. Citirea presupune şi filtrare folosind
valoarea anterioară citită, dar metodele de filtrare sunt diferite pentru senzori de tip diferit. Toate
valorile citite sunt întregi. Fiecare operaţie de citire este specifică senzorului respectiv,
resetarea este comună tuturor tipurilor de senzori iar calibarea este diferită pentru senzorii
analogici şi optici. Senzorii permit şi o operaţie identică de interogare a stării. Senzorii optici mai
necesită o operaţie specifică de aducere la zero, alta decât reset, iar senzorii analogici necesită
o operaţie specifică de selectare a canalului.
Proiectaţi o ierarhie de clase (se cer doar declaraţiile, nu şi implementările) care să modeleze fragmentul corespunzător de realitate, în cadrul aplicaţiei software de conducere de proces. Sugeraţi care vor fi metodele publice şi unde vor fi folosite acele funcţii care nu sunt publice. Comentati fiecare variabilă şi fiecare funcţie membră.
R. class senzor{ int status; // starea protected: int val_citita; // valoarea citita (va fi setata de citire) int val_anterioara; // valoarea anterioara va fi transferata din val_citita // in timpul apelului metodei de citire int val_filtrata; // valoarea prelucrata prin filtrare (va fi returnata de get) virtual int filtru()=0; public: virtual void calibrare()=0; // calibrarea este o functie virtuala pura virtual void citire()=0; // citirea este si ea o functie virtuala pura void reset(); // operatia de reset int status(); // returneaza starea int get(); // returneaza valoarea filtrata }; class senzor_analog public: senzor { // clasa specializata pentru senzori analogici int filtru(); // functia de filtrare nu va fi accesata de afara public: void calibrare(); // calibrarea specifica senzorului analogic void citire(); // aici se va apela si filtrul specific void select_canal(int ); // extensie pentru selectia canalului analogic }; class senzor_optic public: senzor { int filtru(); public: void calibrare(); // calibrarea specifica senzorului optic void citire(); // aici se va apela si filtrul specific void zero(); // extensie pentru operatia specifica de aducere la zero };
2. Valorile citite într-un sistem de monitorizare trebuie stocate într-o stivă. Creaţi pentru aceasta
o stivă cu alocare dinamică care să funcționeze (incremental) astfel: dacă se atinge
dimensiunea curentă a stivei, se alocă memorie pentru ca să poată stoca stiva existentă și încă
câteva valori și se copiază stiva în noua zonă de memorie, eliberând apoi vechea zonă.
R: class CStack { int *m_p; // stiva propriu-zisa va fi aici int m_nStored; // indicator varf stiva int m_nDepth; // dimensiunea temporara a stivei enum {GROW_BY=5}; // pasul de crestere a stivei public: CStack( ); // constructor virtual ~CStack(); // destructor int IsEmpty() const; // test stiva goala void Push(const int &item); // introducere in stiva int Pop(); // extragere din stiva }; // Constructori CStack::CStack() { m_p=0; m_nStored=0; m_nDepth=0; } CStack::~ CStack() { delete []m_p; } // Operatii int CStack::IsEmpty() const { return m_nStored==0; } void CStack::Push(const int &item) { if(m_nStored==m_nDepth) // stiva alocata s-a terminat {
Int *p=new int[m_nDepth+GROW_BY]; // trebuie una mai mare for (int i = 0; i<m_nDepth; i++) // stiva se replica in cea noua { p[i]=m_p[i]; } m_nDepth+=GROW_BY; // dimensiunea temporara creste delete [ ]m_p; // stiva anterioara este eliberata m_p=p;
} m_p[m_nStored]=item; // introducerea in stiva m_nStored ++; // si avansul indicatorului de varf stiva } int CStack::Pop( ) { m_nStored--; // indicatorul de varf al stivei merge inapoi
return m_p[m_nStored]; // scoaterea din stiva } …
CStack stivaMea; // utilizare
3. Prezentaţi declararea clasei/claselor care permit implementarea unei liste înlănţuite, pentru
stocarea unor informaţii despre variabile citite de senzori. Acestea cuprind: denumirea variabilei
de proces, valoarea sa întreagă şi valoarea sa prelucrată. Valoarea întreagă se setează la
citirea de către senzor. Valoarea prelucrată este de tip double, se obţine prin apelarea unei
metode de procesare şi trebuie furnizată în exterior prin apelul unei metode.
R: (una din solutiile simple) class var_proc{ // un nod stocheaza date specifice unei citiri si valoarea procesata // pentru lista inlantuita static var_proc *cap; // capul listei var_proc *urm; // pointer catre urmatorul element din lista // mai departe, valorile stocate in nod char *denumire; // denumirea int val; // valoarea citita double val_proc; // valoarea prelucrata // metode private double procesare(); // metoda nu trebuie apelata de afara public: var_proc(char* ); // constructor care va apela si functia de citire a senzorului virtual int citire(); // citirea va trebui redefinita la implementarea concreta (in // cadrul unei clase derivate var_proc_concreta double getval(); // aici va fi apelata si procesarea, se va seta val_proc si // valoarea este furnizata apelantului }; var_proc *var_proc::cap=NULL;
Analiza algoritmilor (7)
1. Se cere să se implementeze tipul de date abstract Arbore Binar Ordonat. În acest scop se cere:
1. Să se definească o structură de date care defineşte în manieră recursivă structura Arbore Binar Ordonat;
2. Să se implementeze pe această structurră, în forma unor funcţii C operatorii Caută, Inserează şi Suprimă definiţi peste TDA Arbore Binar Ordonat;
3. Să se dezvolte operatorul Inordine, care să afişeze cheile unui Arbore Binar Ordonat în inordine.
R1: typedef int T_cheie; typedef void (*T_prelucrare)(T_cheie); void Initializare(T_arbore *A); int ArboreVid(T_arbore A); int Cauta(T_arbore A, T_cheie k); T_arbore Insereaza(T_arbore A, T_cheie k); T_arbore Suprima(T_arbore A, T_cheie k); void Preordine(T_arbore A, T_prelucrare f); void Inordine(T_arbore A, T_prelucrare f); void Postordine(T_arbore A, T_prelucrare f); [1] typedef struct nod T_nod; /* tipul nodurilor */ typedef T_nod *T_arbore; /* tipul arbore binar ordonat */ struct nod { T_cheie ch; /* cheia unica per nod */ T_nod *st; /* pointer subarbore stang */ T_nod *dr; /* pointer subarbore drept */ }; [2] int Cauta(T_arbore p, T_cheie k) { int gasit = 0; while (p) { if (k < p->ch) p = p->st; else if (p->ch < k) p = p->dr; else { gasit = 1; break; } } return gasit; } T_nod* alocaNod(T_cheie k)
{ T_nod *p = malloc(sizeof(T_nod)); p->st = p->dr = NULL; p->ch = k; return p; } T_arbore Insereaza(T_arbore p, T_cheie k) { if (!p) p = alocaNod(k); else if (k < p->ch) p->st = Insereaza(p->st, k); else if (p->ch < k) p->dr = Insereaza(p->dr, k); return p; } T_nod *supred(T_nod **p) { T_nod *q; while (q = *p, q->dr) p = &q->dr; *p = q->st; return q; } T_arbore Suprima(T_arbore p, T_cheie k) { if (!p) return NULL; if (k < p->ch) p->st = Suprima(p->st, k); else if (p->ch < k) p->dr = Suprima(p->dr, k); else { T_nod *q = p; if (!p->st) p = p->dr; else if (!p->dr) p = p->st; else { q = supred(&p->st); p->ch = q->ch; } free(q); } return p; } [3] void Inordine(T_arbore p, T_prelucrare f) { if (!p) return; inordine(p->st);
(*f)(p->ch); inordine(p->dr); } static void afisNod(int k) { printf(“%-8d”, *k); /* maxim de ordinul sutelor de mii */ } int main() { T_arbore rad; Initializare(&rad); /* . . . */ Inordine(rad, &afisNod); return 0; }
2. Se cere să se redacteze o aplicaţie care realizează următoarele activităţi:
1. Defineşte structura de date aferentă unui graf; 2. Implementează operatorii CautăNod, InserNod, SuprimaNod, InserArc,
SuprimArc, Crează, Afişează, TraversareInAdancime; 3. Acceptă la intrare un graf precizat prin mulţimea nodurilor şi arcelor sale; 4. Crează graful; 5. Listează nodurile în ordinea parcurgerii lor pe baza căutării în adâncime.
R2: #include <stdio.h> #include <stdlib.h> #define VAR * #define REF & #define BUF while(fgetc(file) != „\n‟) typedef void (*T_traversare)(char); [1] #define MAX 100 typedef int MatrAdj[MAX][MAX]; typedef struct graf T_graf; struct graf { int contor; /* contorul nodurilor */ char nume[MAX]; /* numele nodurilor (litera) */ MatrAdj madj; /* matricea de adiacenta */ int marc[MAX]; /* tabloul vizitat */ }; [2] void Initializare(T_graf VAR graf) { graf->contor = 0; }
int CautaNod(T_graf *graf, char nume) { int i, n = graf->contor; for (i = 0; i < n; ++i) if (graf->nume[i] == nume) break; return i; } void InserNod(T_graf VAR graf, char nume) { int i = CautaNod(graf, nume), n = graf->contor; if ((i < n || n >= MAX)) return; graf->nume[n] = nume; for (i = 0; i <= n; ++i) { graf->madj[i][n] = 0; graf->madj[n][i] = 0; } ++graf->contor; } void SuprimNod(T_graf VAR graf, char nume) { int i = CautaNod(graf, nume), j, n = graf->contor; if (i == n) return; n = --graf->contor; for (j = 0; j < n; ++j) { graf->madj[i][j] = graf->madj[n][j]; graf->madj[j][i] = graf->madj[j][n]; } } void InserArc(T_graf VAR graf, char nod1, char nod2) { int i = CautaNod(graf, nod1), j = CautaNod(graf, nod2), n = graf->contor; if (i == n || j == n) return; graf->madj[i][j] = 1; } void SuprimArc(T_graf VAR graf, char nod1, char nod2) { int i = CautaNod(graf, nod1), j = CautaNod(graf, nod2), n = graf->contor; if (i == n || j == n) return; graf->madj[i][j] = 0; } void adancime(T_graf g, T_traversare f, int i) { int j, n = g.contor; g.marc[i] = 1; (*f)(g.nume[i]); for (j = 0; j < n; ++j)
if (!g.marc[j] && g.madj[i][j]) adancime(g, f, j); } void TraversareInAdancime(T_graf graf, T_traversare func) { int i, n = graf.contor; for (i = 0; i < n; ++i) graf.marc[i] = 0; for (i = 0; i < n; ++i) if (!graf.marc[i]) adancime(graf, func, i); } void Creaza(FILE* file, T_graf VAR graf) { int i, n; if (file == NULL) return; fscanf(file, “%d”, &n); BUF; for (i = 0; i < n; ++i) { InserNod(graf, fgetc(file)); BUF; } while (!feof(file)) { char nod1, nod2; nod1 = fgetc(file); BUF; nod2 = fgetc(file); BUF; InserArc(graf, nod1, nod2); } } static void afisareNod(char nume) { printf(“%c\n”, nume); } void Afiseaza(T_graf graf) { TraversareInAdancime(graf, &afisareNod); } int main() { T_graf g; char f[] = “?.txt”; Initializare(graf); puts(“Nume fisier text: ”); f[0] = getchar(); Creaza((f[0] == „\n‟) ? stdin : fopen(f, “rt”), REF g); Afiseaza(g); return 0; }
3. Se consideră o structură graf orientat ponderat. Se cere:
1. Să se descrie o structură de graf orientat ponderat. 2. Să se implementeze procedura care determină lungimile drumurilor minime între toate
perechile de noduri ale grafului. 3. Să se implementeze procedura care determină traseul drumului de lungime minimă între
două noduri precizate ala grafului. Indicaţie: În implementare se va utiliza algoritmul FLOYD.
R3: [1] #define INF 1000 #define MAX 100 struct graf { int contor; /* numarul de noduri */ float COST[MAX][MAX]; /* matrice costuri arce (lipsa=INF) */ }; [2] float A[MAX][MAX]; /* mattrice lungim drumuri minime */ int Drum[MAX][MAX]; /* reconstituire traseu */ void FLOYD(struct graf *Graf) { int i, j, k, n = Graf->contor; for (i = 0; i < n; ++i) for (j = 0; j < n; ++j) { A[i][j] = Graf->COST[i][j]; Drum[i][j] = 0; } for (i = 0; i < n; ++i) A[i][i] = 0; for (k = 0; k < n; ++k) for (i = 0; i < n; ++i) for (j = 0; j < n; ++j) if (A[i][k] + A[k][j] < A[i][j]) { A[i][j] = A[i][k] + A[k][j]; Drum[i][j] = k; } } [3] void Traseu(int i, int j) { int k = Drum[i][j]; if (k != 0) { Traseu(i, k); printf(“%d\n”, k) Traseu(k, j); } }
Proiectarea microsistemelor digitale (8)
1. Prezentaţi schema pentru o interfaţă serială de tip RS 232 . 2. Prezentaţi schema pentru o interfaţă paralelă de tip CENTRONIX. 3. Prezentaţi schema pentru conectarea a 64 led-uri la o unitate centrală cu microprocesorul
8086. R:
1. Schema este alcătuită din un decodificator de porturi, un circuit specializat 8251 şi un circuit
MAX 232 pentru translatarea nivelelor de tensiune din TTL în EIA şi invers. Oricare din ieşirile
decodificatorului poate fi folosită pentru selectarea circuitului 8251.
2. Schema este alcătuită din un decodificator de porturi, un circuit specializat 8255 şi porţi
pentru amplificarea/separarea liniilor între circuitul specializat şi periferic. Oricare din ieşirile
decodificatorului poate fi folosită pentru selectarea circuitului 8251.
3. Schema este alcătuită din un decodificator de porturi, 8 circuite registru, fiecare cu câte 8
ieşiri. La fiecare ieşire de registru se conecteză catodul unui led iar anodul acestuia se leagă prin
o rezistenţă la alimentare. Aprinderea/stingerea led-urilor se va comanda prin intermediul
informaţiilor înscrise în registre prin intermediul magistralei de date. Pentru ca un led să
lumineze ieşirea la care este conectat va trebui să aibă 0 logic iar pentru ca un led să fie stins,
ieşirea la care este conectat va trebui să aibă 1 logic.
Fundamente de inginerie software(9)
1. Să se reprezinte o diagramă „use case” ce implementează un sistem web on-line de achiziţii
publice care acţionează în următorul fel:
- pe site-ul web există conturi de contractori, de prestatori şi un cont special de administrare;
- contractorii şi prestatorii se pot înregistra şi pot să-şi modifice doar datele proprii. Contul de
administrator este predefinit şi poate administra şi conturile de contractori şi prestatori;
- pentru acces utilizatorii se vor autentifica (prin logare);
- beneficiarul poate posta un anunţ pentru o lucrare;
- contractorii care doresc acea lucrare, îşi postează oferta, care cuprinde preţul propus, termen
de timp şi descrierea soluţiei. Ulterior ei pot să îşi modifice oferta;
- beneficiarul poate să renunţe la o lucrare (să o şteargă);
- în caz că o oferta este acceptată ea intră în execuţie. Prestatorul o va executa iar contractorul
o va recepţiona.
R:
Sistem on-line
Creare
cont
Logare
Administrare
conturi
Administrare
cont propriu
Lucrare
Ofertă
Execuţie
înregistrare
autentificare
administrare
administrare
administrare
postare/
ştergere acceptare
recepţionare
postare/modificare/ştergere
executare
Vizitator
Administrator
Contractor
Prestator
autentificare
2. Considerând următorul formular de introducere date, cu validările specificate, specificaţi un
set de date eronate pentru a se verifica funcţionarea corecta a sistemului de validare:
cod utilizator - intre 6 si 20 caractere, format doar din litere si cifre, trebuie sa fie unic in baza de
date
parola - intre 4 si 15 caractere, doar litere si cifre
e-mail - trebuie sa fie un e-mail scris corect (daca notam cu S setul de caractere permise,
trebuie sa avem: S @ S(.S)+, adică după @ trebuie sa fie minim 2 grupe de caractere
S, despărţite prin .)
nume - trebuie sa conţină doar litere, cu minim 2 caractere pentru un cuvânt si minim 2 cuvinte
telefon intern - trebuie sa fie un număr valid de 5 până la 10 cifre, fără prefix internaţional (00),
putând cuprinde opţional pentru lizibilitate liniuţe şi puncte.
R: a) 1. Codul sa fie format din mai puţin de 6 caractere 2. Codul sa fie format din mai mult de 20 caractere 4. Codul sa conţină şi alte caractere pe lângă litere si cifre 3. Codul sa fie duplicat b) 1. Parola să fie formată din mai puţin de 4 caractere 2. Parola să fie formată din mai mult de 15 caractere 4. Parola să conţină şi alte caractere pe lângă litere si cifre c) 1. Să conţină si alte caractere pe lângă cele permise 2. Sa nu existe @ 3. După @ urmează un singur S 4. Sa fie @ la început sau la sfârşit 5. După @S sau @S. nu mai urmează nimic d) 1. Numele să conţină şi alte caractere în afara de litere 2. Numele are mai puţin de două caractere 3. Numele este format dintr-un singur cuvânt e) 1. Număr incorect de telefon cu mai puţin de 5 sau mai mult de 10 cifre 2. Să conţină 00 in fata 3. Să conţină alte caractere decât cifre, liniuţe şi puncte
3. Se cere diagrama de clase UML care implementează un sistem de gestiune al angajaţilor
dintr-o companie considerând următoarele precizări:
- fiecare angajat are un cod personal, nume, adresa, telefon, data angajării si observaţii;
- un angajat poate ocupa unul din trei posturi posibile: salariat, şef de echipă sau director de
departament;
- fiecare angajat are un salariu rezultat printr-o procedură de calcul;
- există trei departamente (tipuri de angajaţi): producţie, vânzare şi achiziţii;
- angajaţii din producţie mai au în plus şi o calificare specifică;
- la vânzare si achiziţii, angajaţii mai trebuie să cunoască o limbă străină şi pot să muncească în
alte locaţii, decât la sediul firmei;
- la achiziţii, unii angajaţi pot avea şi calificarea de testor pentru a testa lotul achiziţionat.
La proiectare se va utiliza conceptul de moştenire şi se va respecta principiul open-close.
R:
În plus fiecare clasă va mai conţine câte o metodă set, respectiv get pentru fiecare atribut.
Productie
- calificare : String
Angajat
- codPersonal : int
- nume : String
- adresa : String
- dataAngajare : Date
- observatii : String
- post
+ salariu()
AngajatAV
- limbaStraina : String
- locatie : String
Vanzare Achizitie
- calificareTestor : boolean
enum{Salariat, Sef_Echipa, Director}
Securitatea Informației(10)
1. Precizati succesiunea operatiilor pentru obtinerea cheilor publice utilizand o „autoritate pentru
distribuţia cheilor publice” (fig.1)
Fig.1 . Distribuţia cheilor folosind o autoritate pentru chei publice
R: Fiecare participant cunoaşte cheia publică a autorităţii, care va fi folosită pentru autentificarea părţilor participante. Pentru a primi o cheie se urmează paşii descrişi în continuare: A trimite un mesaj datat (mesajul include Time1) autorităţii conţinând o cerere (Request) pentru cheia publică curentă a lui B. [mesajul (1)] Autoritatea răspunde cu un mesaj [mesajul (2)] criptat cu cheia sa privată, mesaj pe care A îl poate decripta fiind în posesia cheii publice a autorităţii. Astfel A poate fi sigur că mesajul primit este autentic, mesajul fiind criptat cu cheia privată a autorităţii KRauth. Mesajul include următoarele: Cheia publică a lui B, KUb. Cererea originală pentru ca A să determine dacă aceasta nu a fost modificată. Datarea mesajului, astfel A poate determina dacă mesajul primit nu este un mesaj vechi de la autoritate, conţinând o cheie diferită de cheia curentă a lui B. A salvează cheia publică a lui B şi îi transmite acestuia un mesaj care conţine un identificator IDA şi un anunţ N1, care este folosit pentru identificarea tranzacţiei. [mesajul (3)] B recepţionează cheia publică a lui A de la autoritate în aceeaşi manieră cum A a recepţionat cheia lui B. [mesajele (4) si (5)]
B transmite un mesaj lui A criptat cu cheia publica a lui A si care contine un raspuns N2 la anuntul N1 [mesajul (6)] In final A ii retransmite mesajul N2 inapoi lui B, criptat cu cheia publica a lui B. Astfel A si B au ajuns in posesia cheilor publice ale celuilalt si s-au anuntat unul pe altul despre acest lucru. [mesajul (7)]
2. Aplicati transformarea ShiftRows( ) – Fig.2. – din algoritmul de criptare AES urmatorului
tablou de stare:
AB90F1A7
1523A57B
1225E377
1B3F32A2
S
Fig. 2. Transformarea ShiftRows( )
R: În această transformare, octeţii din liniile tabloului de stare sunt rotiţi spre stânga astfel: cu 0 octeţi pentru linia 1, cu 1 octet pentru linia 2, cu 2 octeţi pentru linia 3 şi respectiv cu 3 octeţi pentru linia 4, rezultand tabloul de stare S’.
90F1A7AB
A57B1523
771225E3
1B3F32A2
'S
3. Aplicati transformarea InvSubBytes( ) din algoritmul de decriptare AES, bazat pe substitutia S
inversa din Fig.3, a urmatorului tablou de stare:
AB90F1A7
1523A57B
1225E377
1B3F32A2
S
Figura 3. Descrierea substituţiei octetului xy (in hexazecimal) utilizând cutia
inversă S
R: Pentru fiecare byte se obtine x (prima cifra hexa) si y (a doua cifra hexa) si se utilizeaza Fig.3 pentru a
obtine valoarea noua a octetului respectiv. De ex. Pentru S0,0=2A, x=2, y=A, rezultand S‟0,0=95. Astfel
rezulta:
Rețele de calculatoare(11)
1. Se considera adresa ip v4 172.16.0.150 având masca 255.255.255.192. Se cere:
a) Adresa rețelei respectiv adresa de broadcast a rețelei din care face parte adresa ip; b) Adresa subrețelei respectiv adresa de broadcast a subrețelei din care face parte adresa ip; c) Numărul de hosturi din subrețeaua din care face parte adresa ip; d) Numărul de subrețele definite de masca adresei ip dată.
R: a) Adresa IP definește o rețea de clasa B rezultă că masca rețelei este 255.255.0.0 . Făcând operațiile pe biți vom avea: 10101100.00010000.00000000.10010110 Adresa IP 11111111 .11111111 .00000000.00000000 Mască rețea -------------------------------------------------- 10101100.00010000.00000000.00000000 Adresa rețelei -------------------------------------------------- 10101100.00010000.11111111 .11111111 Adresa de broadcast a rețelei Adresa rețelei este 172.16.0.0 Adresa de broadcast a rețelei este 172.16.255.255 b) Făcând operațiile pe biți vom avea: 10101100.00010000.00000000.10010110 Adresa IP 11111111 .11111111 .11111111 .11000000 Masca subrețea -------------------------------------------------- 10101100.00010000.00000000.10000000 Adresa subrețelei -------------------------------------------------- 10101100.00010000.00000000.10111111 Adresa de broadcast a subrețelei Adresa subrețelei este 172.16.0.128 Adresa de broadcast a subrețelei este 172.16.0.191 c) Numărul de hosturi din subrețea: NH = 26-2 = 62 hosturi d) Numărul de subrețele: NSR = 210-2 = 1022 subrețele
2. Se considera adresa ip v4 192.168.10.125/28. Se cere:
a) Adresa rețelei respectiv adresa de broadcast a rețelei definite de perechea adresă ip / mască rețea. b) Numărul de hosturi din rețeaua determinată la punctul a).
R: a) Făcând operațiile pe biți vom avea:
11000000.10101000.00001010.01111101 Adresa IP 11111111 .11111111 .11111111 .11110000 Masca rețea -------------------------------------------------- 11000000.10101000.00001010.01110000 Adresa de rețea -------------------------------------------------- 11000000.10101000.00001010.01111111 Adresa de broadcast a rețelei Adresa rețelei este 192.168.10.112 Adresa de broadcast a rețelei este 192.168.10.127 b) Numărul de hosturi din subrețea: NH = 24-2 = 14
Baze de date(12)
Nota: Pentru rezolvarea problemelor propuse se poate folosi şi limbajul SQL sau PL/SQL, dar cu definirea
cheilor primare şi externe.
1. Se consideră două fişiere dintr-o bază de date existentă pentru rezervare locuri la avion. Fişierul Curse
conţine datele pentru fiecare cursă din orarul de zbor.
Fişierul Pasageri conţine datele pentru toţi pasagerii din toate cursele. Toţi pasagerii unei curse vor avea
acelaşi cod cursă CodC.
Curse
CodC Pilot Copilot Avion Oras1 Ora1 Oras2 Ora2 PretR NrLoc
Pasageri
CodC CNP NumeP Adresa DataN Tel Pret
Să se afişeze informaţiile despre o cursă de avion şi lista pasagerilor din acea cursă folosind comenzi
simpe din limbajul XBase. Se recomandă forma de afişare:
CodC Oras1 Ora1 Oras2 Ora2 Pilot Copilot TipAv
Ro234-
0609
Timisoara
TSR
8:30 Bucuresti 9:30 Popescu Adam B747
Lista Pasageri
CNP Nume Pas Adresa Telefon DataN Pret
R.
SET TALK OFF
CLEAR
USE Curse INDEX Icodc IN 1 ALIAS CS
USE Pasageri INDEX Icodc, Inume IN 2 ALIAS PS
SET RELATION TO Codc INTO PS
ACCEPT ’Cod cursa: ’ TO Vcodc
SEEK VCodc
? ’CodC Pilot Copilot Avion Oras1 Ora1 Oras2 Ora2 ‘
? REPL(‘=’,120)
? Codc, Pilot, Copilot, Avion, Oras1, Ora1, Oras2, Ora2
?
? ‘ LISTA PASAGERI ‘
?
SELECT PS
? ‘CNP Nume Pasager Adresa Tel DataN Pret ‘
? ‘ REPL(‘-’,120)
DO WHILE Codc=Vcodc
? CNP, NumeP, Adresa, Tel, DataN, Pret
SKIP
ENDDO
2. Considerăm o bază de date normalizată pentru evidenţă studenţi care cuprinde tabelele:
STUD
CodS Nume Adresa DataN Bursa Telefon CNP ......
NOTE
CodS CodC NOTA Data
CURS
CodC Titlu NumeProf
Folosind comenzi simple Xbase se cere afişarea notelor unui student dat prin nume sub forma:
CODS: AC321 Nume: Popescu Bogdan Adresa: Bogdanesi 3 Bursa:150
Situatia notelor
Curs Nota Data Nume prof
Sisteme de operare 9 23-01-2011 Popovici
.....................................
R.
USE Stud INDEX Inume, Icods IN 1 ALIAS ST
USE Note INDEX Icodsn IN 2 ALIAS NT
USE CURS INDEX Icodc IN 3 ALIAS CS
SET RELATION Cods INTO Note
Select 2
SET RELATION Codc INTO Curs
Select 1
ACCEPT ‘ Nume Student: ‘ TO Vnume
SEEK Vnume
IF EOF()
? ‘Studentul ‘ + Vnume + ‘ Nu exista’
ELSE
? ‘Cods: ‘ + Cods, ‘ Nume: ‘+ Nume, ‘ Adresa: ‘+ Adresa, ‘ Bursa: ‘,Bursa
?
? ‘ Situatia notelor ‘
?
? ‘ Curs Nota Data Nume Prof ‘
? ‘ ------------------------------------------------------------------------------------ ‘
Select 2
DO WHILE Cods=Vcods
? CS-->Titlu, Nota, Data, CS-->NumeProf
SKIP
ENDDO
ENDIF
3. Considerăm o bază de date normalizată pentru evidenţă studenţi care cuprinde tabelele:
STUD
CodS Nume Adresa DataN Bursa Telefon CNP ......
NOTE
CodS CodC NOTA Data
CURS
CodC Titlu NumeProf
Folosind comenzile XBase elementare pentru dialog şi SQL pentru căutarea informaţiilor, să se scrie
secvenţe de program care realizează funcţiile:
Afişare Cods, Nume student, Bursa, pentru toţi studenţii care au medii mai mari decât o valoare N
Afişare pentru un student dat prin Cods toate notele, Titlul cursului pentru fiecare notă şi Nume profesor.
Se va ţine cont că rezultatul unei comenzi SQL se obţine într-o zona de lucru din care se poate afişa
direct folosind comanda BROWSE, iar variabilele citite sunt externe precedate de “:”.
R.
ACCEPT ‘ Media minima: ‘ TO N
SELECT ST.Cods,ST.Nume, AVG(NT.Nota) Media FROM Stud ST, Note NT
WHERE ST.Cods=NT.Cods GROUP BY ST.Cods,ST.Nume,ST.Bursa,
HAVING AVG(NT.Nota)>:N
Browse && - afisare rezultat
Wait
ACCEPT ‘ Dati Cod student’ TO Vcods
SELECT ST.Cods, ST.Nume,NT.Nota,CS.Titlu,CS.NumeP Profesor
FROM Stud ST, Note NT, Curs CS
WHERE ST.Cods=:Vcods AND ST.Cods=NT.Cods AND NT.Codc=CS.CODC
BROWSE
Wait
Proiectarea interfeţelor utilizator şi grafică(13)
1. Analizati din punctul de vedere al uzabilității mesajul de eroare de mai jos: Mesaj de “help” al unui site al unei companii (Midwest Microwave) care apare atunci când utilizatorii doresc să parcurgă catalogul de produse de pe site. Mesajul apare înainte de prezentarea catalogului. Are scopul de a completa câteva lucruri care nu au fost precizate anterior în catalog.
R:
Supraîncărcarea utilizatorului cu detalii; nu reiese ce este important şi ce este mai puţin important (-minus la design minimalist).
Aspect dezastruos: fără paragrafe, fără titlu, fără spaţii care să ghideze privirea (- la design estetic)
Materialul nu este organizat pe module, astfel încât să fie parcurs ușor şi utilizatorul să aleagă din ceea ce este prezentat ceea ce ştie şi nu ştie deja (- la flexibilitate şi eficienţă).
Informaţia prezentată este inutilă şi în afara contextului atât timp cât utilizatorul nu a văzut încă despre ce este vorba (- la suport şi documentare)
Fiind o casetă de dialog modală, aceasta va dispărea îndată ce utilizatorul va continua şi va ajunge la catalog, atunci când de fapt va avea nevoie de a-şi aduce aminte de cele scrise în casetă (- la minimizarea încărcării memoriei).
Utilizarea termenilor precum modem V.90 (nu vorbeşte în limbajul utilizatorului general).
2. Analizați interfața de mai jos și propuneți o variantă mai bună, conform regulilor de design
cunoscute.
R.:
Prea multe culori, fără reguli asociate;
Prea multe fonturi, prea mult bold;
Nu e nevoie de umbrire în titlu;
Bara orizontală nu este necesară în prima zonă de text;
butonul Close – care apare ca secundar aici – este mai mare decât butonul Send – cel mai des folosit.
3. Indicați elementele din proiectarea interfețelor utilizator de tip web care caracterizează o proiectare reuşită. R: Text Fondul nu creează discontinuităţi ale textului Textul este suficient de mare pentru a fi bine citit, dar nu prea mare Ierarhizarea informaţiei este clară Coloane textului sunt mai înguste decât într-o carte pentru a facilita citirea mai uşoară de pe ecran. Navigarea Butoanele de navigare sunt uşor de înţeles şi folosit Navigarea este consistentă în tot web-site-ul Butoanele de navigare conţin o indicaţie pentru a informa utilizatorul unde se găseşte, în ce pagină Daca se folosesc frame-uri, acestea nu sunt obtruzive (stridente, deranjante) Un site mare are un index sau o hartă a site-ului. Links Culorile link-urilor sunt corelate cu culorile paginilor Link-urile sunt subliniate şi astfel sunt imediat vizibile utilizatorului. Grafica Butoanele nu sunt prea mari şi greoaie Fiecare element grafic are asociat un “alt label” (descriere prin text atunci când trecem peste acesta) Fiecare link grafic are un corespondent link text Elementele grafice şi fondurile folosesc culori care nu sunt denaturate de browser Elementele de grafica animată se opresc automat Proiectarea generală Paginile se încarcă rapid Prima pagină şi pagina ‟Acasă‟ (Home) intră într-un spaţiu de 800x600 pixeli Restul paginilor au un impact vizual imediat în legătură cu relaţia 800x600 Utilizarea corectă a elementelor grafice pentru a “sparge” zone mari de text Fiecare pagină din site arată ca o parte a unui întreg; există elemente repetitive care sunt menţinute în toate paginile.
Medii şi tehnologii de programare(14)
1. Scrieți în C# sau Visual Basic .NET două funcții care să calculeze, pe baza CNP-ului unei
persoane, data de naștere și vârsta acesteia.
' Visual Basic Private Function DataNasterii(ByVal sCNP As String) As Date Private Function Varsta(ByVal sCNP As String) As Integer // C# private DateTime DataNasterii(string cnp); private int Varsta(string cnp);
Exemplu: DataNasterii(”1900228350001”) va returna 28.02.1990, iar Varsta(”1900228350001”) va returna 24 (dacă anul curent este 2014).
SOLUŢIE: ' Visual Basic Private Function DataNasterii(ByVal sCNP As String) As Date Dim an, luna, zi As Integer an = 1900 + Convert.ToInt32(sCNP.Substring(1, 2)) luna = Convert.ToInt32(sCNP.Substring(3, 2)) zi = Convert.ToInt32(sCNP.Substring(5, 2)) Return New Date(an, luna, zi) End Function Private Function Varsta(ByVal sCNP As String) As Integer Return DateDiff(DateInterval.Year, DataNasterii(sCNP), Today) End Function //C# private DateTime DataNasterii(string cnp) { DateTime dn; int an = Convert.ToInt32("19" + cnp.Substring(1, 2)); int luna = Convert.ToInt32(cnp.Substring(3, 2)); int zi = Convert.ToInt32(cnp.Substring(5, 2)); if (DateTime.TryParse(zi + "/" + luna + "/" + an, out dn)) return (dn); return DateTime.MinValue; } private int Varsta(string cnp) { long ticks; long ticks0 = DataNasterii(cnp).Ticks; if (ticks0 > 0) { TimeSpan ts = new TimeSpan(ticks0); ticks = DateTime.Now.Ticks - ticks0; DateTime v = new DateTime(ticks); return v.Year - 1; } return 0; }
2. Secvența de cod de mai jos (Visual Basic sau C#) are ca efect trasarea într-un control
PictureBox1 a unei linii între coordonatele (x1,y1) și (x2,y2). Modificați secvența pentru a se desena, în interiorul aceluiași control, un trapez isoscel având baza mare latura inferioară a dreptunghiului format de cele două perechi de coordonate, iar baza mică o treime din latura
superioară a aceluiași dreptunghi. Se presupune că x1<x2 și y1<y2.
' Visual Basic Dim myGraph As System.Drawing.Graphics myGraph = PictureBox1.CreateGraphics() myGraph.DrawLine(Pens.Black, x1, y1, x2, y2) // C# System.Drawing.Graphics myGraph; myGraph = pictureBox1.CreateGraphics(); myGraph.DrawLine(Pens.Black, x1, y1, x2, y2);
SOLUŢIE: ' Visual Basic Dim myGraph As System.Drawing.Graphics myGraph = PictureBox1.CreateGraphics() myGraph.DrawLine(Pens.Black, x1, y2, x2, y2) myGraph.DrawLine(Pens.Black, x2, y2, (CInt(x2-(x2- x1)/3)), y1) myGraph.DrawLine(Pens.Black, (CInt(x2-(x2-x1)/3)), y1, (CInt(x1+(x2-x1)/3)), y1) myGraph.DrawLine(Pens.Black, (CInt(x1+(x2-x1)/3)), y1, x1, y2) // C# System.Drawing.Graphics myGraph; myGraph = pictureBox1.CreateGraphics(); myGraph.DrawLine(Pens.Black, x1, y2, x2, y2); myGraph.DrawLine(Pens.Black, x2, y2, (Convert.ToInt32(x2 - (x2 - x1) / 3)), y1); myGraph.DrawLine(Pens.Black, (Convert.ToInt32(x2 - (x2 - x1) / 3)), y1, (Convert.ToInt32(x1 + (x2 - x1) / 3)), y1); myGraph.DrawLine(Pens.Black, (Convert.ToInt32(x1 + (x2 - x1) / 3)), y1, x1, y2);
3. Ce va afișa la ieșire secvența de cod (Visual Basic sau C#) de mai jos? ' Visual Basic Dim i, j As Integer For i = 1 To 5 For j = 5 To 1 Step -1 If (j - i) < 0 Then Continue For Console.Write(j + i) Next Next // C# int i = 0; int j = 0; for (i = 1; i <= 5; i++) { for (j = 5; j >= 1; j += -1) { if ((j - i) < 0) break; Console.Write(j + i); } }
SOLUŢIE: ' Visual Basic 6543276548769810 // C# 6543276548769810
Limbaje formale şi tehnici de compilare(15)
1. Se dă gramatica:
G1:E → E+ E | E * E | (E) | i Să se arate că această gramatică este ambiguă. 2. Se consideră definiţia regulată pentru identificatori:
identif → litera(litera|cifra)* Să se deseneze diagrama de tranzitii (automatul finit) corespunzătoare, incluzând şi cuvintele cheie şi menţionând procedurile semantice necesare. 3. Se dă gramatica:
E → T | E+T T → F | T*F F → (E) | id
Să se elimine recursivitatea de stânga din această gramatică.
Răspunsuri
1. Se consideră şirul de intrare: i + i * i
Pentru acest şir există 2 arbori de derivare:
În concluzie, gramatica este ambiguă.
2. Tratarea identificatorilor:
0start literă
1ad, carurm
ad, carurm
literă, cifră
altceva
cautăid 2
id este
cuv.
cheie ?
NU
DA
gen
gen
3
4
<ident, id>
<clcheie[id]>
3. Pentru relaţiile recursive, se foloseşte formula:
AA AA’
A’A’ În acest fel, mulţimea de şiruri derivate din A nu se schimbă. Se obţine următoarea gramatică transformată:
EE+TT ETE’ E’TE’
TTFF TFT’ T’FT’
F(E)id F(E)id
E
E + E
i E E *
i i
E
E * E
i E E +
i i
Programare WEB (16)
1. În cadrul unei baze de date cu numele RESURSE_UMANE, stocată pe un server MySQL
(localhost, user “root”, fără parolă), se consideră tabela PERSONAL, creată cu comanda SQL
următoare:
CREATE TABLE personal ( cnp CHAR(13) PRIMARY KEY, nume VARCHAR(20), prenume VARCHAR(20); salar INTEGER); Să se scrie o aplicaţie Web (structurată sub forma a două fişiere script, unul HTML, celălalt
PHP) care permite interogarea parametrizată a tabelei după o informaţie din coloana CNP (cod
numeric personal) introdusă de la tastatura (prin intermediul unui formular HTML). Parametrul
de interogare va fi transmis spre scriptul PHP, acesta realizând interogarea efectivă a tabelei şi
afişarea pe o coloană a datelor returnate. Dacă nu se găseşte nici o înregistrare, se va semnala
acest lucru printr-un mesaj. Se vor trata eventualele erori/excepţii prin afişarea unor mesaje.
Alegerea numelor fişierelor este la latitudinea programatorului.
R. (o soluţie posibilă, aceasta nefiind unică): fisier.html <html> <form action="fisier.php" method="POST"> CNP:<input type="text" name="cnp" size="13"><br> <input type="SUBMIT" value="Cauta"> </form> </html> fisier.php <?php $link=mysql_connect("localhost","root","") or die ("Eroare: Conectare esuata la server MySQL"); mysql_select_db("resurse_umane") or die ("Eroare: Nu se poate deschide baza de date"); $cnp=$_POST['cnp']; $query=mysql_query("select * from personal where cnp='$cnp'"); $contor_linii=0; while($row=mysql_fetch_row($query)) { $contor_linii++; //gasit o linie foreach ($row as $value) echo $value." <br>"; } if ($contor_linii==0)
echo "Nu s-a gasit nici o linie!"; mysql_close($link); ?> 2. În cadrul unei baze de date cu numele BAZA, stocată pe un server MySQL (localhost, user
“root”, fără parolă), se consideră tabela EVIDENTA, creată cu comanda SQL următoare:
CREATE TABLE evidenta(nume CHAR(20), varsta INTEGER, localitate CHAR(20));
Să se scrie un script PHP care permite interogarea tabelei, respectiv afişarea în format tabelat
al întregului ei conţinut. Se vor trata eventualele erori/excepţii prin afişarea unor mesaje.
Secvenţa de cod PHP se va comenta succint.
R. (o soluţie posibilă, aceasta nefiind unică): <?php //conectare la server si selectie baza de date $link=mysql_connect("localhost","root","") or die ("Eroare: Conectare esuata la server MySQL"); mysql_select_db("baza") or die ("Eroare: Nu se poate deschide baza de date"); //interogare tabela $query=mysql_query("select * from evidenta"); //creare antet tabel echo "<table border='1'>"; echo "<tr>"; echo "<th>Nume</th>"; echo "<th>Varsta</th>"; echo "<th>Localitate</th>"; echo "</tr>"; //ciclare dupa numarul de inregistrari/linii gasite si afisarea lor, element cu element while ($row=mysql_fetch_row($query)) { echo "<tr>"; foreach ($row as $value) { echo "<td>$value</td>"; } echo "</tr>"; } echo "</table>"; //inchidere conexiune la baza de date mysql_close($link); ?>
3. În cadrul unei baze de date cu numele MAGAZIN, stocată pe un server MySQL (localhost,
user “root”, fără parolă), se consideră tabela PRODUSE, creată cu comanda SQL următoare:
CREATE TABLE produse (id INTEGER PRIMARY KEY, nume_produs VARCHAR(20), stoc
INTEGER);
Să se scrie o aplicaţie Web (structurată sub forma a două fişiere script, unul HTML, celălalt
PHP) care permite introducere de la tastatură (prin intermediul unui formular HTML) a datelor
privitoare la un produs din tabela bazei de date (id, nume_produs, stoc). Aceşti parametrii se
vor transmite către un script PHP, realizând adăugarea efectivă a noului articolului în tabela
bazei de date. Reuşita sau nereuşita operaţiei se va semnala prin afişarea unui mesaj
corespunzător. Alegerea numele fişierelor este la latitudinea programatorului.
R. (o soluţie posibilă, aceasta nefiind unică): fisier.html <html> <form action="fisier.php" method="POST"> Id:<input type="text" name="id" size="5"></p> Nume Produs:<input type="text" name="nume_produs" size="20"><br> Stoc:<input type="text" name="stoc" size="5"><br> <input type="SUBMIT" value="Trimite"> </form> </html> fisier.php <?php $link=mysql_connect("localhost","root","") or die ("Eroare: Conectare esuata la server MySQL"); mysql_select_db("magazin") or die ("Eroare: Nu se poate deschide baza de date"); $id=$_POST['id']; $nume_produs=$_POST['nume_produs']; $stoc=$_POST['stoc']; mysql_query("insert into produse values ($id, '$nume_produs', $stoc)") or die ("Eroare: Nu se poate finaliza operatia"); echo "Informatiile au fost introduse in baza de date"; mysql_close($link); ?>