main()
{
enum {F,T}; /*false,true;0,1*/
int znak,prvi=T; /* znak sa ulaza, indikator pojavepocetka recenice */
/* ucitavanje ulaza do markera kraja (EOF) i pretvaranje pocetnih slova recenice u velika i pretvaranje velikih slova iz sredine recenice u mala slova. */
while ( (znak=getchar() ) != EOF)
{
if (isupper(znak) )
{ if ( !prvi) /* if (prvi==0) */
znak=tolower(znak); /*u sredini recenice veliko slovo->malo slovo */
else prvi=F; /*napusta se pocetak recenice */
}
else if (islower(znak) )
{ if(prvi) /*recenica pocinje */
{ znak=toupper(znak); /* velikim slovom */
prvi=F; /*napusta se pocetak recenice */
}
}
else /*nije slovo */
if (znak =='.' || znak=='!' || znak =='?')
prvi=T; /*novi pocetak */
putchar(znak); /*slanje rezultata obrade naizlaz */
}
return 0;
}
42.
/* Sa standardnog ulaza se unose linije teksta limitirane dužine. Ispisati na standardni izlaz linije koje sadrže dati obrazac- nisku HTML. */
/* Za one koji preferiraju MS "hungariannotation" */
#include <stdio.h>
#include <ctype.h>
/* limit duzine ulazne linije */
#define cMAXLINE 1000
/* ucitava liniju limitirane duzine sa ulaza i vracanjenu duzinu */
int getline( char szLine[], int iLimit);
/* vraca ili
-1 ako se druga niska ne nalazi u prvoj
ili poziciju prve pojave druge niske u prvoj */
int strindex( char szSource[], char szSearchFor[]);
char gszPattern[]="HTML"; /* obrazac za kojim se traga*/
/* glavni program */
main()
{
char szLine[cMAXLINE]; /* linija sa ulaza limitiraneduzine*/
int iFound=0; /* signal pojave pattern-a:ako je iFound==0 =>
niti jedna linija se ne ispisuje, jer niti jedna linijane sadrzi obrazac*/
/*ucitavanje linija sa ulaza do markera kraja (EOF)uz pretragu obrasca u svakoj ucitanoj liniji */
while( getline(szLine, cMAXLINE)>0 )
/*ako je indeks(pozicija) nadjenog obrasca(pattern-a)u liniji veci ili jednak nuli, onda odstampati tu liniju */
if( strindex(szLine, gszPattern)>=0 )
{
printf("%s", szLine);
iFound++;
}
else printf("\n");
/* ako pozicija obrasca nije veca ili jednaka nuli,preci u novi red */
return iFound;
}
/* getline: ucitava liniju i vraca njenu duzinu */
int getline( char szLine[], int iLimit)
{
int CharCurr, iCur;
iCur=0;
while( --iLimit>0 && (CharCurr=getchar())!=EOF&& CharCurr!='\n')
szLine[iCur++]=CharCurr;
if( CharCurr=='\n' )
{
szLine[iCur]=CharCurr;
++iCur;
}
szLine[iCur]='\0';
return iCur;
}
/* strindex: vraca indeks druge niske u prvoj, odnosno-1 ako se ne sadrzi*/
int strindex( char szSource[], char szSearchFor[])
{
int iSub, iFirst, iSecond; /* pozicija karakterau nisci u kojoj se vrsi pretraga,
pozicija pocetka pretrage u svakom prolazu,
pozicija karaktera u niski obrasca */
/*pretraga pocinje od pocetka prve niske
i ako je odatle neuspesna, onda se povecava iSub svedo kraja prve niske */
for( iSub=0; szSource[iSub]!='\0'; iSub++ )
{
/* pocev od tekuce pozicije prve niske (iSub) poredi se znak prve idruge niske i to sve do kraja druge niske ili do pojave prvog znaka u komse niske razlikuju */
for( iFirst=iSub, iSecond=0;
szSearchFor[iSecond]!='\0' && szSource[iFirst]==szSearchFor[iSecond];
iFirst++, iSecond++) ;
/* u slucaju uspesne pretrage vraca se pozicija prve niske od koje pocinjeprva pojava druge niske */
if( iSecond>0 && szSearchFor[iSecond]=='\0')
return iSub;
}
return -1;
}
43.
/* Izracunati sumu brojeva u pokretnom zarezu. Nije unapred poznato koliko
ima brojeva, sem da je svaki sadrzan u po jednoj liniji, a sve linije ulaza su limitirane duzine.
Smatracemo na dalje da se ovakav ulaz podrazumeva,cak i ako ga ne opisemo detaljno*/
#include <stdio.h>
#include <ctype.h>
#define LINELIMIT 1000
int getline( char linija[], int lim);
/* na osnovu sadrazaja niske vraca broj u pokretnomzarezu */
double atofd (char [] );
/* glavni program */
main()
{double dSum; /* suma brojeva */
char linija[LINELIMIT]; /*tekucibroj kao niska cifara */
dSum=0;
while( getline(linija, LINELIMIT)>0 ) dSum+= atofd(linija);
printf("Suma: %f \n", dSum);
return 0;
}
/* getline: ucitava liniju i vraca njenu duzinu */
int getline( char linija[], int lim)
{
int znakk, indeks;
indeks=0;
while( --lim>0 && (znakk=getchar())!=EOF&& znakk!='\n') linija[indeks++]=znakk;
if( znakk=='\n' )
{ linija[indeks]=znakk;
++indeks;
}
linija[indeks]='\0';
return indeks;
}
/* atof: na osnovu sadrzaja niske vraca broj u pokretnomzarezu */
double atofd( char sBroj[])
{
double dVal, dPower;
int indeks, iSign;
/*preskok escapespace */
for( indeks=0; isspace(sBroj[indeks]); indeks++) ;
/*odrediti predznak */
iSign = ( sBroj[indeks]=='-' ) ? -1 : 1;
if( sBroj[indeks]=='+' || sBroj[indeks]=='-' ) indeks++;
/*vrednost celobrojnog dela */
for( dVal=0.0; isdigit(sBroj[indeks]); indeks++) dVal=10.0*dVal+(sBroj[indeks]-'0');
if( sBroj[indeks]=='.' ) indeks++;
/* razlomljenog dela */
for( dPower=1.0; isdigit(sBroj[indeks]); indeks++)
{dVal=10.0*dVal+(sBroj[indeks]-'0');
dPower *= 10;
}
return iSign*dVal/dPower;
}
/* varijanta sa konverzijom koja podrzava format sa mantisom i eksponentom:npr: -2.85e-4 ili 5.146E18 */ /*double atofd( char szNumber[]){ double dVal, dPower; int iCur, iSign; for(iCur=0;isspace(szNumber[iCur]);iCur++); iSign = ( szNumber[iCur]=='-' ) ? -1 : 1; if( szNumber[iCur]=='+' || szNumber[iCur]=='-') iCur++; for( dVal=0.0; isdigit(szNumber[iCur]); iCur++) dVal=10.0*dVal+(szNumber[iCur]-'0'); if( szNumber[iCur]=='.' ) { iCur++; for( dPower=1.0; isdigit(szNumber[iCur]); iCur++) { dVal=10.0*dVal+(szNumber[iCur]-'0'); dPower *= 10; } dVal = iSign*dVal/dPower; } else dVal = iSign*dVal; if( szNumber[iCur]=='e' || szNumber[iCur]=='E' ) { int iExp; iCur++; iSign = ( szNumber[iCur]=='-' ) ? -1 : 1; if( szNumber[iCur]=='+' || szNumber[iCur]=='-') iCur++; for( iExp=0.0; isdigit(szNumber[iCur]); iCur++) iExp=10.0*iExp+(szNumber[iCur]-'0'); if( iSign==-1) for(iCur=1; iCur<=iExp;iCur++) dVal /= 10.0; else for(iCur=1; iCur<=iExp;iCur++) dVal *= 10.0; } return dVal; }*/
O REKURZIJI
Stekovi se koriste za praćenje niza poziva funkcija tokom izvršavanja programa (stek aktivacijskih slogova). Svaki put kada se pozove funkcija, u stek se umetne aktivacijski slog. Slog sadrži prostor za informacije koje su potrebne tokom izvršavanja poziva funkcije i informacije o nastavku pozivnog programa nakon što se završi sa izvršavanjem funkcije.
#include <stdio.h> /* Rekurzivna verzija funkcija za racunanje n! */ long fakt (int n) { if (n) return n*fakt(n-1); else return 1; } /* KOMPAKTNIJI KÔD REKURZIVNE VERZIJE long fakt (int n) { return (n == 0) ? 1 : n * fakt (n-1); } */ /* ITERATIVNA VERZIJA long fakt(int n) { long f = 1; int i; for (i = 1; i<=n; i++) f *= i; return f; } */ main() { int n; printf("Unesite n: "); scanf("%d", &n); printf("%d! = %ld\n", n, fakt(n)); }R2. NCP koji će implementirati iterativnu i rekurzivnu funkciju za izračunavanje sume 1+2+3+...+n, pozivati tu funkciju za pozitivan ceo broj n koji se unosi sa standardnog ulaza. Suma se definiše 1+2+...+n= Sn=n + Sn-1, ako je n >0. Inače, S0=0.
#include <stdio.h> /* Rekurzivna verzija funkcija za racunanje Sn */ long suma (int n) { if (n) return n + suma(n-1); else return 0; } /* KOMPAKTNIJI KÔD REKURZIVNE VERZIJE long suma (int n) { return (n ) ? (n + suma(n-1)) : 0; } */ /* ITERATIVNA VERZIJA long suma(int n) { long s = 0; int i; for (i = 1; i<=n; i++) s += i; return s; } */ main() { int n; printf("Unesite n: "); scanf("%d", &n); printf("S%d = %ld\n", n, suma(n)); }R3. NCP koji će implementirati iterativnu i rekurzivnu funkciju za izračunavanje sume članova (double) niza a sa n članova, pozivati tu funkciju za pozitivan ceo broj n koji se unosi sa standardnog ulaza i za n članova (double) niza a koji se unose sa standardnog ulaza.
#include <stdio.h> #define MAX 10 /* Rekurzivna funkcija za racunanje zbira elemenata niza. */ double zbir (const double a[], int n) { return (n > 0) ? a[0] + zbir (a+1, n-1) : 0; } /*ITERATIVNA VERZIJA double zbir (const double a[], int n) { double s; int i; s=a[0]; for (i = 1; i<n; i++) s += a[i]; return s; } */ main() { int n,i; double a[MAX]; printf("Unesite n: "); scanf("%d", &n); printf("\nUnesite niz dimenzije %d: ", n); for(i=0; i <n; i++) scanf("%lf", &a[i]); printf("\nS%d = %lf\n", n, zbir(a,n)); }R4. NCP koji će implementirati iterativnu i rekurzivnu funkciju za izračunavanje binomnog koeficijenta C(n,k) za dato n i k i ispisati Pascalov trougao do nivoa 10.
#include <stdio.h> #define MAX 10 /* Rekurzivna funkcija za racunanje binomnog koeficijenta. */ int binko (int n, int k) { return (0<k && k<n) ? binko (n-1, k-1) + binko (n-1, k) : 1; }
/* Iterativno izracunavanje datog binomnog koeficijenta. int binko (int n, int k) { int i, j, b; for (b=i=1, j=n; i<=k; b=b*j--/i++); return b; } */ /* Ispisivanje Paskalovog trougla. */ main () { int n, k, i; putchar ('\n'); for (n=0; n<=MAX; n++) { for (i=0; i<MAX-n; i++) printf (" "); for (k=0; k<=n; k++) printf ("%4d", binko (n, k)); putchar ('\n'); } }44.K&R zadatak: NCP koji sa standardnog ulaza unosi nisku znakova. Konvertovati unesenu liniju u ceo broj, duplirati vrednost celog broja, potom ga odštampati na standardni izlaz, uz upotrebu rekurzivne funkcije. Pretpostavka je da je ulazan sintaksno i semanticki korektan.
#define LINELIMIT 1000
int getline( char linija[], int iLimit);
void printd( int n );
main()
{char linija[LINELIMIT]; /*tekuci ulaz */
int i; /*brojac u petlji */
/*ocitavanje ulaza */
while( getline( linija, LINELIMIT ) > 0 )
{ i=atoi( linija );
i*=2;
printd( i ); /*rekurzivna f-ja */
putchar('\n');
}
return 0;
}
/* getline: ucitava liniju i vraca njenu duzinu */
int getline( char linija[], int iLimit)
{int znakk, i;
for( i=0; i<iLimit-1 && (znakk=getchar())!=EOF&& znakk!='\n'; ++i) linija[i]=znakk;
if( znakk=='\n' ){linija[i]=znakk; ++i;}
linija[i]='\0';
return i;
}
/* printd: stampaj d decimalno */
void printd( int n )
{ if( n<0 )
{ putchar('-');
n = -n;
}
if( n/10 ) printd(n/10 );
putchar( n%10+'0' );
}
R5. NCP koji će implementirati iterativnu verziju i rekurzivnu funkciju za izračunavanje skalarnog proizvoda, i za pozitivan ceo broj n i dva niza double brojeva, koji se unosi sa standardnog ulaza izračunati skalarni proizvod i ispisati na standardni izlaz.
/* Skalarni proizvod dva vektora. */ #include <stdio.h> #define DIM 10 /* Rekurzivna funkcija za racunanje skalarnog proizvoda dva vektora. */ float skalpro (const float a[], const float b[], int n) { return (n > 0) ? a[0] * b[0] + skalpro (a+1, b+1, n-1) : 0; } /*ITERATIVNA VERZIJA float skalpro (const float a[], const float b[], int n) { float skal_pro; for (skal_pro=i=0; i<n; i++) skal_pro += a[i] * b[i]; return skal_pro; } */ main () { float a[DIM], b[DIM]; int i, n; while (1) { printf ("\nDuzina vektora (najvise %d)? ", DIM); scanf ("%d", &n); if (n <= 0 || n > DIM) break; printf ("\nUnesite vektor A: "); for (i=0; i<n; scanf ("%f", &a[i++])); printf ("\nUnesite vektor B: "); for (i=0; i<n; scanf ("%f", &b[i++])); printf ("\nSkalarni proizvod A*B= %10.3f\n", skalpro (a, b, n)); } }
45.
NCP koji sa standradnog ulaza čita niz pozitivnih brojeva x, dok se ne pročita nula.
Nije unapred poznat broj članova niza x, sem da ih neće biti više od 50.
Od članova niza x formirati niz y, tako što iz niza x izbaci
sve članove xk koji su deljivi nekim od brojeva x0, x1,...,
xk-1. Odštampati sve članove niza y. Pri učitavanju razviti sopstvene funkcije
za čitanje znakovne niske i konverziju u broj.
#include <stdio.h>
#include <ctype.h>
#define LINELIMIT 1000
#define MAXNIZ 50
unsigned atou( char s[] );
int getline( char line[], int lim);
int imaDelioce( unsigned clan, unsigned clanovi[],int granica);
/* glavni program */
main()
{
char linija[LINELIMIT]; /*tekuci ulaz */
unsigned tekuciBr; /*broj sa ulaza */
int xClanova=0; /*broj clanova niza x */
unsigned x[MAXNIZ];
int yClanova=0; /*broj clanova niza y */
unsigned y[MAXNIZ];
int i; /*brojac u petlji */
/*ucitavanje linija do markera kraja(0) i konverzija u broj */
xClanova=0;
do
{
i = getline(linija,LINELIMIT);
tekuciBr = atou(linija);
if( tekuciBr ) x[xClanova++] = tekuciBr;
}
while( tekuciBr );
/*provera svojstva clana niza x i kreiranje niza yzavisno od rezultata provere*/
yClanova = 0;
for( i=0; i<xClanova; i++ )
if( !imaDelioce( x[i], x, i ) ) y[yClanova++] = x[i];
/*izdavanje niza y */
for( i=0; i<yClanova; i++ ) printf( "%u\t", y[i] );
printf("\n");
return 0;
}
/* getline: ucitava liniju i vraca njenu duzinu */
int getline( char line[], int lim)
{int znak, indeks;
for( indeks=0; indeks<lim-1 && (znak=getchar())!=EOF&& znak!='\n'; ++indeks)
line[indeks]=znak;
if( znak=='\n' ) line[indeks++]=znak;
line[indeks]='\0';
return indeks;
}
/* atou: ascii to unsigned */
unsigned atou( char s[] )
{
int poz;
unsigned rezultat=0;
/* preskociti escape znake */
for( poz=0; isspace(s[poz]); poz++ )
;
/* preskociti znak '+' */
if( s[poz]=='+') poz++;
for( ; isdigit(s[poz]); ++poz) rezultat = 10*rezultat+(s[poz]-'0');
return rezultat;
}
/* provera da li niz clanovi do granice sadrzi delioce broja clan */
int imaDelioce( unsigned clan, unsigned clanovi[],int granica)
{
int i;
for( i=0; i<granica; i++ )
if( clan % clanovi[i]== 0 ) return -1;
return 0;
}
Jelena Grmusa | Osnovi programiranja |