Sunteți pe pagina 1din 10

Valeriu Iorga Programare n C

Probleme rezolvate
1. Scriei o funcie care convertete un ntreg ntr-un ir de caractere n baza 10.
Algoritmul cuprinde urmtorii pai:
{ se extrage semnul numrului;
se extrag cifrele numrului, ncepnd cu cmps;
se transform n caractere i se depun ntr-un tablou;
se adaug semnul i terminatorul de ir;
se inverseaz irul;
}
void inversare(car!"#;
void itoa(int n, car s!"#{
int $, semn;
if((semn%n#&'#
n%-n;
$%';
do
s!$(("%n)*'(+'+;
,ile ((n-%*'#.'#;
if(semn&'#
s!$(("%+-/;
s!$"%+0'+;
inversare(s#;
}
void inversare(car s!"#
{ int i,$;
car c;
for(i%',$%strlen(s#-*;i&$;i((,$--#
c%s!i", s!i"%s!$", s!$"%c;
}
2. Scriei o funcie care convertete un ntreg fr semn ntr-un ir de caractere n baza 16.
Pentru a trece cu uurin de la valorile cifrelor hexazecimale ',*,1*2 la caracterele
corespunztoare /'+,+*+,1,+a+,1,+f+, vom utiliza un ta!lou iniializat de caractere"
static car exa!"%3'*4562789:abcdef3;
void ito(int n, car s!"#
{ $%';
do {
s!$(("%exa!n)*7";
,ile ((n-%*7#.'#;
s!$"%+0'+;
inversare(s#;
}
3. Scriei o funcie care convertete un ir de caractere reprezentnd un numr ntreg! ntr-o
va"oare ntreag. #umru" poate avea semn i poate fi precedat de spaii a"be.
;include &ct<pe=.
int atoi(car >s#
#
Valeriu Iorga Programare n C
{ int i, nr, semn;
for(i%'; isspace(s!i"#; i((# ->ignora spatii albe>-
;
semn%(s!i"%%+-/#?-*@*; ->stabilire semn>-
if(s!i"%%+(+AAs!i"%%+-/# ->se sare semnul>-
i((;
for(nr%';isdigit(s!i"#;i((# ->conversie in cifra>-
nr%*'>nr((s!i"-/'+#; ->si alipire la numar>-
return semn>nr;
}
6= Scriei o funcie avnd ca parametru un ir de caractere! care ntoarce "ungimea siru"ui
->varianta cu tablouri>-
int strlen(car >s#
{ int $;
for($%'; s!$"; $((#
;
return $;
}
->varianta cu pointeri>-
int strlen(car >s#
{ car >p%s;
,ile(>p#
p((;
return p-s;
}
$. Scriei o funcie care copiaz un ir de caractere s n d.
->varianta cu tablouri>-
void strcp<(car >d, car >s#
{ int $%';
,ile((d!$"%s!$"#B%+0'+#
$((;
}
->varianta cu pointeri>-
void strcp<(car >d, car >s#
{ ,ile((>d%>s#B%+0'+#{
d((;
s((;
}
Postincrementarea pointerilor poate fi fcut n operaia de atri!uire deci:
void strcp<(car >d, car >s#{
,ile((>d((%>s((#B%+0'+#
;
}
$
Valeriu Iorga Programare n C
%estul fa de /0'+ din ,ile este redundant& deci putem scrie:
void strcp<(car >d, car >s#{
,ile(>d((%>s((#
;
}
6. Scriei o funcie care compar "e%icografic dou iruri de caractere i ntoarce rezu"tatu" C*,
' sau * dup cum d&s, d%%s sau d.s.
->varianta cu tablouri>-
int strcmp(car >d, car >s#
{ int $;
for($%'; d!$"%%s!$"; $((#
if(d!$"%%+0'+#
return ';
return d!$"-s!$";
}
->varianta cu pointeri>-
int strcmp(car >d, car >s#
{ for(; >d%%>s; d((,s((#
if(>d%%+0'+#
return ';
return >d->s;
}
&. Scriei o funcie care determin poziia 'inde%u"( primei apariii a unui subir s ntr-un ir d.
)ac s nu apare n d! funcia ntoarce C*.
int strind(car d!", car s!"#{
int i,$,D;
for (i%'; d!i"; i((# {
for ($%i,D%'; s!D" EE d!$"%%s!D"; $((,D((#
;
if (D.' EE s!D"%%+0'+#
return i;
}
return C*;
}
*. Scriei o funcie care citete ce" mu"t n numere rea"e! pe care "e p"aseaz ntr-un tab"ou x.
+uncia ntoarce numru" de va"ori citite.
Vom citi numerele ntr'un ir de caractere s. (e aici vom extrage n mod repetat c)te un numr&
folosind funcia sscanf(# i l vom converti folosind un format corespunztor" Ciclul se va repeta
de n ori& sau se va opri c)nd se constat c s'au terminat numerele"
Vom scrie funcia n $ variante: folosind ta!louri sau folosind pointeri.
-> varianta cu tablouri >-
int citreal(int n, double x!"#
{ car s!422";
*
Valeriu Iorga Programare n C
int $;
double <;
for ($%'; $&n; $((# {
if(gets(s#%%FGHH#
return $;
if(sscanf(s,3)lf3,E<#B%*# ->conversie in real>-
breaD; ->s-au terminat numerele>-
x!$"%<;
}
return $;
}
-> varianta cu pointeri >-
int citreal(int n, double >px#
{ int $%';
double <;
double >p%px(n;
,ile(px&p# {
if(gets(s#%%FGHH#
return $;
if(sscanf(s,3)lf3,E<#B%*# ->conversie in real>-
breaD; ->s-au terminat numerele>-
>px((%<;
$((;
}
return $;
}
,. )efini i o func ie care sorteaz o "ist de nume.
Pentru sortare vom utiliza algoritmul !ulelor& care interschim! numele alturate& care nu respect
ordinea alfa!etic& Prin sortare nu se vor schim!a irurile de caractere& ci pointerii ctre acestea"
Fig.10.1. Sortarea irurilor de caractere
+ortarea o vom realiza cu algoritmul !ulelor: dac irul de nume ar fi ordonat& atunci dou nume
consecutive s'ar afla n relaia & sau %%" Vom cuta aadar relaiile .& schim!)nd de fiecare dat
ntre ei pointerii corespunztori ,schim!are mai eficient dec)t schim!area irurilor-" +e fac mai
multe parcurgeri ale listei de nume la fiecare trecere& o varia!il martor . sortat& iniializat la #
este pus pe /& atunci c)nd se interschim! doi pointeri" 0ista de nume va fi sortat n momentul n
care n urma unei parcurgeri a listei se constat c nu s'a mai fcut nici o schim!are de pointeri"
void sortare(car >tp!", int n# {
1
Vasile
Constantin
Ion
Vasile
Constantin
Ion
Valeriu Iorga Programare n C
int $, sortat;
car >temp;
for(sortat%'; Bsortat;#{
sortat%*;
for($%';$&n-*;$((#
if(strcmp(tp!$",tp!$(*"#.'#{
temp%tp!$",
tp!$"%tp!$(*",
tp!$(*"%temp,
sortat%';
}
}
}
10. Definii o funcie, avnd ca parametru un ntreg, reprezentnd o lun, care ntoarce (un pointer
la) numele acelei luni
car >numeIluna(int n#
{ static car >nume!"%{JHuna inexistenta3,3Kanuarie3, JLebruarie3,
3Martie3,3Nprilie3,JMai3,3Kunie3,3Kulie3,3Nugust3,
JOeptembrie3,3Pctombrie3, JFoiembrie3,3Qecembrie3};
return(n&*AAn.*4#?nume!'"@nume!n";
}
11. Scriei un program care extrage cuvintele ditincte dintr!un text, criind n dreptul fiecrui
cuvnt numrul de apariii ale acetuia n text.
Pentru separarea cuvintelor din text vom folosi funcia strtoD(#" 2n cuv)nt separat din text este
mai nt)i cutat n ta!loul de pointeri la cuvintele separate cuv& i este inserat acolo& n caz c nu este
gsit dac este gsit este crescut contorul de apariii al cuv)ntului"
;include &stdio=.
;include &string=.
;define FR *''
->cauta sirul p in tabloul de siruri cuv
intoarce pozitia in care se afla p in cuv sau -* >-
int exista(car> p, int nc, car> cuv!"#{
int $%';
for(int $%'; $&nc; $((#
if(strcmp(p,cuv!$"#%%'# return $;
return -*;
};
int main(#{
car sep!"%S =,@;-(#0t0nS; ->separatori intre cuvinte>-
car linie!9'"; ->tampon pentru citirea unei linii>-
car >cuv!FR", ap!FR", >p; ->tablou de cuvinte>-
int nc%', poz;
freopen(Stext=txtS, SrS, stdin#;
,ile(gets(linie##
3
Valeriu Iorga Programare n C
for(p%strtoD(linie,sep#; p; p%strtoD(',sep##
if((poz%exista(p, nc, cuv##%%-*#{
cuv!nc"%strdup(p#;
ap!nc(("%*;
}
else
ap!poz"((;
printf(Snumar cuvinte distincte )5d0nS, nc#;
for(int i%'; i&nc; i((#
printf(S)*'s )4d0nS, cuv!i", ap!i"#;
}
1". Se citec mai multe #iruri de caractere reprezentnd numere lungi n $aza 1%, ce pot avea pn
la 100 de cifre. S e calculeze uma acetora, ignornd numerele incorecte.
Indicaie: Pentru a aduna dou numere lungi pstrate n dou iruri de caractere& se inverseaz n
preala!il cifrele lor& astfel nc)t prima cifr s fie cea mai puin semnificativ i se transform apoi
caracterele cifre hexadecimale n numere ntregi de la / la #3" +e extinde apoi cu zerouri& numrul
lung cel mai scurt& aduc)ndu'l la lungimea celuilalt i se face adunarea rang cu rang& cu propagarea
transportului:
sum % s
i
( a
i
( t
s
i
% sum ) *7
t % sum - *7
(ac n final rm)ne transport& acesta devine cifra cea mai semnificativ a sumei""
4umerele din rangurile sumei se transform n cifre hexadecimale i se inverseaz aceste cifre"
#" iniializare numr lung sum
$" !ucl citire numere lungi
$"#" verificare corectitudine numr lung citit
$"$" conversie caractere cifre hexa n numere
$"*" inversare cifre numr lung
$"1 completare numr mai scurt cu zerouri
$"3" adunare pe ranguri cu propagare transport
$"5" completare suma cu ultimul transport
$"6" inversare cifre
$"7" conversie numere hexa n caractere
*" afiare numr lung sum
1&. ' fracie raional are numrtorul #i numitorul numere lungi n $aza 10, avnd pn la 100
cifre.
Se cere e implifice fracia cu divizori ntregi primi, pn la o limit dat n.
(umerele lungi e citec ca dou #iruri de caractere, din primele dou linii) a treia linie conine
valoarea lui n.
*rogramul va afi#a fracia neimplificat #i fracia implificat.
+ndicaie: +e va defini o funcie care mparte un numr lung a& cu un ntreg d i calculeaz c)tul c .
un numr lung i restul . un ntreg mai mic ca d"
d
r
c c c
d
a a a
n
n
+ =

# # /
# # /

5
Valeriu Iorga Programare n C
rest demprit mpritor c)t


int divlung(car >a, int d, car >c#;
8n preala!il& caracterele cifre ale dempritului se transform n ntregi"
9uncia simuleaz mprirea cifr cu cifr ntr'un pas al mpririi:
' se adaug la restul parial ,iniializat la /- cifra curent a dempritului: rp%*'>rp(a
i
' se calculeaz cifra curent a c)tului: c
i
% rp - d
' se actualizeaz restul parial: rp % rp ) d
2ltimul rest parial este restul mpririi"
C)tul c
'
c
*
1c
n-*
are aceeai lungime cu dempritul& dar cifrele sale cele mai semnificative pot fi /"
8n final& cifrele ntregi ale c)tului se transform n caractere cifre"
#" ncercare divizori primi
$" simplificare cu divizorul comun
*" afiare fracie simplificat
1" funcia divlung,-
1"#" conversie caractere n cifre
1"$" simulare mprire cifr cu cifr
1"*" conversie cifre n caractere
;include &stdio=.
;include &stdlib=.
;include &string=.
int divlung(car>, int, car>#;
int main(#{
car a!*''", b!*''", ca!*''", cb!*''";
int i, n;
gets(a#; puts(a#;
gets(b#; puts(b#;
scanf(S)dS, En#;
for(i%'; i&%n; i((#
if(divlung(a, i, ca#%%' EE divlung(b, i, cb#%%'#{
strcp<(a, ca#;
strcp<(b, cb#;
}
printf(S)s0nS, a#;
printf(S)s0nS, b#;
s<stem(STNGOUS#;
return ';
}
int divlung(car >a, int d, car >c#{
int i, lg, rp % ';
lg % strlen(a#;
for(i%'; i & l; i((#
a!i" -% V'V;
for(i%'; i&lg; i((#{
rp % *'>rp ( a!i";
6
Valeriu Iorga Programare n C
c!i" % rp - d;
rp )% d;
}
c!lg" % /0'+;
for(i%'; i & lg; i((#
c!i" (% V'V;
return rp;
}
1,. S e copieze la ie#ire fi#ierele date ca parametri ai comenzii. Dac nu avem parametri e
copiaz fi#ierul tandard de intrare (tdin).
;include &stdio=.
void cop<(LKHU >, LKHU >#;
int main(int argc, car >argv!"#{
LKHU >pf;
if(argc%%*#
cop<(stdin, stdout#;
else
,ile(--argc#
if((pf%%fopen(>((argv,3r3##%%FGHH# {
fprintf(stderr, JFu putem descide )s0n3, >argv#;
return *;
}

else {
cop<(pf, stdout#;
fclose(pf#;
}
return ';
}
void cop<(LKHU >s, LKHU >d#{
int c;
,ile((c%fgetc(s##B%UPL#
putc(c, d#;
}
Probleme propuse (iruri de caractere).
#" +criei o funcie C care sta!ilete dac un ir de caractere dat ca parametru reprezint un
palindrom" Pentru aceasta este necesar ca primul i ultimul caracter din irul de caractere s fie egale&
al doilea i penultimul& "a"m"d"
9uncia ntoarce # dac irul de caractere este un palindrom i / n caz contrar"
$" 2n text citit de pe mediul de intrare reprezint un program C" + se copieze pe mediul de ieire&
pstr)nd structura liniilor& dar suprim)nd toate comentariile"
7
Valeriu Iorga Programare n C
*" (intr'un text& citit de pe mediul de intrare& s se separe toate cuvintele& plas)ndu'le ntr'un vector
cu elemente iruri de caractere de lungime #/ ,cuvintele mai scurte se vor completa cu spaii li!ere&
iar cele mai lungi se vor trunchia la primele #/ caractere"
+e vor afia elemenetele acestui ta!lou& c)te 3 elemente pe o linie& separate ntre ele prin $
asteriscuri"
1" (intr'un text citit de pe mediul de intrare s se afieze toate cuvintele care conin cel puin *
vocale distincte"
3" +criei un program care citete i afieaz un text i determin numrul de propoziii i de cuvinte
din text" 9iecare propoziie se termin prin punct& iar n interiorul propoziiei cuvintele sunt separate
prin spaii& virgul sau liniu"
5" (e pe mediul de intrare se citete un text format din cuvinte separate prin spaii li!ere" + se
afieze acest text la ieire& pstr)nd structura liniilor i scriind n dreptul liniei cel mai lung cuv)nt
din linie" (ac mai multe cuvinte au aceeai lungime maxim& va fi afiat numai primul dintre ele"
6" +criei un program care citete de la intrarea standard cuvinte& p)n la nt)lnirea caracterului punct
i afieaz c)te un cuv)nt pe o linie& urmat de desprirea acestuia n sila!e" +e utilizeaz urmtoarele
reguli de desprire n sila!e:
o consoan aflat ntre dou vocale trece n sila!a a doua
n cazul a dou sau mai multe consoane aflate ntre dou vocale& prima rm)ne n sila!a nt)ia&
iar celelalte trec n sila!a urmtoare"
4u se iau n considerare excepiile de la aceste reguli"
7" + se transcrie la ieire un text citit de la intrarea standard& suprim)nd toate cuvintele de lungime
mai mare ca #/" Cuvintele pot fi separate prin punct& virgul sau spaii li!ere i nu se pot continua de
pe o linie pe alta"
:" +criei un program care citete de la intrarea standard un text terminat prin punct i l transcrie la
ieirea standard& nlocuind fiecare caracter />+ printr'un numr corespunztor de spaii li!ere care
ne poziioneaz la urmtoarea coloan multiplu de 3" +e va pastra structura de linii a textului"
#/" +criei un program pentru punerea n pagin a unui text citit de la intrarea standard" +e fac
urmtoarele precizri:
cuvintele sunt separate ntre ele prin cel puin un spaiu
un cuv)nt nu se poate continua de pe o linie pe alta
lungimea liniei la ieire este N
lungimea maxim a unui cuv)nt este mai mic dec)t F - 4
In textul rezultat se cere ca la nceput de linie s fie un nceput de cuv)nt& iar sf)ritul de linie s
coincid cu sf)ritul de cuv)nt" 8n acest scop& spaiile se distri!uie uniform i simetric ntre
cuvinte" 9ace excepie doar ultima linie" Caracterul punct apare doar la sf)rit de text"
##" ;odificai funcia strind(# astfel nc)t s ntoarc n locul indexului un pointer i FGHH n
caz c c su!irul s nu apare n irul destinaie d ,adic scriei funcia strstr(# -"
:
Valeriu Iorga Programare n C
#$. +criei un program care calculeaz i afieaz cmmdc a mai multor numere naturale"
4umerele sunt date:
n fiierul standard de intrare& caz n care programul este lansat n execuie fr parametri:
cmmdc
n linia de comand& ca argumente:
cmmdc 57 69 *9 84 26
ntr'un fiier de intrare& a crui nume apare ca argument al liniei de comand su! forma:
cmmdc Cnume=dat
#/