Vezbe iz Osnova programiranja

62. NCP koji unosi sa standardnog ulaza unosi dva kompleksna broja (Realni, Imaginarni deo) i ispisuje na standardni izlaz njihov zbir, razliku, proizvod, kolicnik. Ako je drugi broj 0, onda prekinuti dalje ucitavanje i ispis (deljenje nulaom!!!) i ispisati vrednost imaginarne jedinice(0+i).
/* STRUKTURE                            */

#include <math.h>  /*zbog pow(x,2)   */
#include <stdio.h>

typedef struct { double re, im; } Kompl;  /* Struktura kompleksnog broja. */
/*alternativa:  struct KB { double re, im; };  typedef struct KB Kompl ; */

Kompl  zbir    (Kompl a, Kompl b); /*funkcija racuna a+b, kao rezultat vraca strukturu, tj. kompleksan broj */
Kompl  razlika (Kompl a, Kompl b);  /* a-b */
Kompl  proizvod (Kompl a, Kompl b); /* funkcija racuna a*b, kao rezultat vraca strukturu, tj. kompleksan broj  */
Kompl  kolicnik (Kompl a, Kompl b) ; /*   a/b   */

main () {
  Kompl x, y, z;
   Kompl  j = {0, 1};   /*primer eksplicitnog zadavanja polja strukture Kompl: prvo polje re=0, drugo polje im=1 */


/*ucitavanje dva kompleksna broja - brojevi sa tastature se unose u polja strukture */
  while (1) {
    printf ("\nUnesite prvi broj x- Re, Im: "); scanf ("%lf%lf", &x.re, &x.im);
    printf (  "Unesite drugi broj y- Re, Im: "); scanf ("%lf%lf", &y.re, &y.im);
      if (y.re==0 && y.im==0) break;  /*bez  deljenja nulom */
    printf ("x     = (%f,%f)\n", x.re, x.im);
    printf ("y     = (%f,%f)\n", y.re, y.im);
    z = zbir     (x, y); printf ("x+y   = (%f,%f)\n", z.re, z.im);
    z = razlika  (x, y); printf ("x-y   = (%f,%f)\n", z.re, z.im);
    z = proizvod (x, y); printf ("x*y   = (%f,%f)\n", z.re, z.im);
    z = kolicnik (x, y); printf ("x/y   = (%f,%f)\n", z.re, z.im);
  }
  z = proizvod (j, j); printf ("\nj^2   = (%f,%f)\n", z.re, z.im);
}





Kompl  zbir    (Kompl a, Kompl b) { a.re += b.re; a.im += b.im; return a; }

Kompl  razlika (Kompl a, Kompl b) { a.re -= b.re; a.im -= b.im; return a; }

Kompl  proizvod (Kompl a, Kompl b) { Kompl c;
  c.re = a.re * b.re - a.im * b.im; c.im = a.im * b.re + a.re * b.im;
  return c;
}

Kompl  kolicnik (Kompl a, Kompl b) { Kompl c;
  double d = pow(b.re, 2) + pow(b.im, 2);
  c.re = (a.re*b.re + a.im*b.im)/d; c.im = (a.im*b.re - a.re*b.im)/d;
  return c;
}



63. NCP koji učitava iz datoteke ulaz.htm informacije(naziv hale, lokacija:ulica i grad, kapacitet izrazen u broju mesta za gledaoce, cenu renoviranja) o sportskim halama regiona (do 4 hale), a potom ispisuje na standardni izlaz sve rasplozive informacije za hale cija cena renoviranja ne prelazi 10000. Jednostavnosti radi, moze se prtpostaviti da se svi pojavni nazivi u ulaznoj datoteci sastoje od jedne reci (fscanf(...)).

#include 
#define MARKER_KRAJ_STRINGA   1
#define MAX_ZNAK              30
#define MAX_HALA              4
struct  hala_podatak {
  char  naziv [ MAX_ZNAK + MARKER_KRAJ_STRINGA ],  /*naziv hale */
	ulica[ MAX_ZNAK + MARKER_KRAJ_STRINGA  ],  /*naziv ulice hale */
	grad  [ MAX_ZNAK + MARKER_KRAJ_STRINGA  ]; /*ime grada kome pripada hala*/
  int   mesta;   /*kapacitet hale */
  float cena;    /*cena radova */ 
};
main( )
{
  struct hala_podatak NizHala[ MAX_HALA ]; /*niz struktura koji sadrzi podatke o halama */ 
  int i;  /*brojac u petlji */
  char s[6];  /* pomocna niska */
  float cenafix; 
  FILE *f;

   f=fopen("ulaz.txt", "r");

/*ucitavanje podataka o svakoj hali iz datoteke ulaz.txt */
  for( i = 0; i < MAX_HALA; i++ ) 
{
  
  fscanf(f, "%s", NizHala[ i ].naziv);
  fscanf(f, "%s", NizHala[ i ].ulica);
  fscanf(f, "%s", NizHala[ i ].grad);
  fscanf(f, "%d",  &NizHala[ i ].mesta);
  fscanf(f, "%f",  &cenafix);
 NizHala[ i ].cena = cenafix;
 printf("\n\n");
 }

/*formatiran ispis hala cija cena renoviranja ne prelazi 10000*/
for( i = 0; i < MAX_HALA; i++ ) 
   if (NizHala[ i ].cena <= 10000)
     {  printf("\n");
         printf("==============HALA %d ================ "
           "\nNaziv:\t\t%25s"
           "\nUlica:\t\t%25s"
           "\nGrad:\t\t%25s"
           "\nKapacitet:\t%25d"
           "\nCenaRadova:\t\t%25.2f",
           i+1,
           NizHala[ i ].naziv,
           NizHala[ i ].ulica,
           NizHala[ i ].grad,
           NizHala[ i ].mesta,
           NizHala[ i ].cena);
  }

fclose(f);
return 0;
}

64. Grupa od N ljudi redom numerisanih od 1 do N obrazovala je krug. Počevši od prvog čoveka, a krećući se u smeru kazaljke na satu iz kruga redom izlazi M-ti čovek. Preostali ljudi obrazuju novi manji krug pri čemu odbrojavanje počinje od levog suseda izbačenog. Celi brojevi M, N nisu unapred poznati, već se unose sa standardnog ulaza. NCP koji ispisuje redne brojeve osoba u redosledu napuštanja kruga.
/*josif zadatak */
#include <stdio.h>
#include <stdlib.h>
typedef struct covek_cvor
{ int rbr;
   struct covek_cvor *sledeci;
}covek;
main()
{ int i;       /*brojac u petljama */
  int  N;      /*broj ljudi u krugu */
  int M;       /*redni broj za izbacivanje */
covek *prvi,*p,*pom;
/*covek *p;
    covek *prvi;
    covek *pom;
*/
printf("Unesite N za ukupan broj ljudi koji obrazuje krug  i M za svaki M-ti koji se izbacuje iz kruga ");  
scanf("%d %d",&N,&M);
/*prvi clan liste ljudi u krugu */
prvi=(covek*) malloc(sizeof(covek));
prvi->rbr=1;
p=prvi;
/*formiranje susednih clanova liste */
for(i=2;i < N+1;i++)
{ if (    (p->sledeci= (covek*) malloc(sizeof(covek) ) )  == NULL)
 { printf("Nema u memoriji dovoljno mesta za malloc\n");
    exit(1);
}
p=p->sledeci;
p->rbr=i;
}
/*zatvaranje kruga */
p->sledeci=prvi;  
/*izbacivanje  M-tog  */
while( p != p->sledeci)   /*tj. dok ne ostane samo jedan u krugu */
{ 
for(i=1;i< M;i++)   p=p->sledeci;
printf("Izbaciti  %d\n", p->sledeci->rbr);
pom=p->sledeci;
p->sledeci=p->sledeci->sledeci;
free(pom);
}
/*ispis rezultata */
printf("I na kraju ostao je %d\n",p->rbr);
}
65. NCP koji iz neprazne datoteke broj.txt ucitava paran broj celih brojeva x[1], x[2],...,x[n], gde n nije unapred poznato. Ispisati poruku na standardni izlaz da li vazi da x[1]==x[n], x[2]==x[n-1],..., x[k]=x[k+1], k=1..n/2
#include <stdio.h>
#include <stdlib.h>

typedef struct listacv dvlista; 
/*dvostruko povezana linearna lista*/
struct listacv
{  int broj; /*informaciono polje je clan niza x*/
   dvlista *sledeci, *prethodni;
};

dvlista *ubaci(dvlista *tek, int broj);
/*dodaje broju u clan liste tek i vraca cvor sa kraja liste*/

main()
{
 dvlista *prvi, *kraj;  /*prvi i poslednji cvor dvostruke liste*/
 int n;  /*broj ucitanih celih brojeva*/
 int broj; /*tekuci broj sa ulaza*/
 int jednak; /*indikator jednakosti dva clana - cuva vrednost 0 ili 1 */
 FILE *ulaz;
 int i;  /*brojacka promenljiva*/

 /*otvaranje datoteke za citanje i upis brojeva iz datoteke u 
 dvostruku povezanu listu */
 ulaz=fopen("broj.txt", "r");
 fscanf(ulaz, "%d", &broj);

 /*kreiranje prvog cvora liste za prvi ucitan broj */
 prvi=(dvlista*)malloc(sizeof(dvlista));
 prvi->broj=broj;
 prvi->sledeci=NULL;
 prvi->prethodni=NULL;

 kraj=prvi; n=1; //za sada ucita je samo jedan clan

 /*formiranje liste od brojeva koji se ucitavaju sve do kraja datoteke - feof(ulaz) */
 while (!feof(ulaz))
 { fscanf(ulaz, "%d", &broj);
   kraj=ubaci (kraj, broj);
   n++;
 }

 fclose(ulaz);

 /*testiranje jednakih parova uz poeranje tekuceg prvog clana i tekuceg poslednjeg
 clana ka sredini liste*/
 jednak=1;
 for(i=1; i<=n/2 && jednak; i++)
 { jednak=jednak&&(prvi->broj==kraj->broj);
    prvi=prvi->sledeci;   /*pomeranje ka sredini liste */
	kraj=kraj->prethodni;  /*pomeranje ka sredini liste */
 }
printf("Za unete broje jednakost ");
if(!jednak) printf("ne ");
printf("vazi\n");
return 0;
}

dvlista *ubaci(dvlista *kraj, int broj)
{
  dvlista *novi;  /*novi cvor za umetanje u listu*/
  novi=(dvlista *)malloc(sizeof(dvlista)); /*alokacija memorije za novi cvor liste*/
  novi->broj=broj; /*inicijalizacija polja broj u cvoru novi */
  novi->sledeci=NULL;
  novi->prethodni=kraj; /*novi element se dodaje na kraj postojece liste*/
  kraj->sledeci=novi; /* do tada poslednji cvor kraj je ispred clana novi*/
  kraj=novi; /*poslednji dodat element je novi kraj liste*/
  return kraj;
}






66. NCP koji sa standardnog ulaza ucitava dva pravougaonika u ravni A, B i na standrdni izlaz ispisuje povrsinu preseka pravougaonika, povrsinu unije pravougaonika, povrsinu razlike pravougaonika(A\B). Pravougaonik se zadaje preko x,y koordinata donjeg levog i gornjeg desnog temena pravougaonika. Stranice pravougaonika su paralelne koordinatnim osama.


#include <stdio.h>
#include  <stdlib.h>
typedef   struct _rect
{ float  x,y;     /*koordinate donjeg levog ugla */
  float  x1,y1;   /*koordinate gornjeg desnog ugla */
} Pravougaonik ;
void ucitavanje (Pravougaonik *P);  /*ucitavanje donjeg levog i gornjeg desnog temena pravougaonika */
Pravougaonik  Presek(Pravougaonik *A, Pravougaonik *B);  /*presek pravougaonika A i pravougaonika  B */
float Povrsina (Pravougaonik *A);   /*izracunavanje povrsine datog pravougaonika */
main()
{   Pravougaonik  A,B ;           /*zadati pravougaonici */
     Pravougaonik presekAB ;   /*presek zadata dva  pravougaonika */
     float povrsinaA;  /*povrsina pravougaonika A*/
     float povrsinaB;  /*povrsina pravougaonika  B*/
     float povrsAB;    /*povrsina preseka pravougaonika A i pravougaonika B*/
    /*ucitavanja pravougaonika sa standardnog ulaza */ 
    ucitavanje(&A);
    ucitavanje(&B);
   /*odredjivanje A*B */
   presekAB  =  Presek  (&A  ,  &B);
   /*izracunavanje povrsine datih  pravougaonika i njihovog preseka */
  povrsinaA=Povrsina(&A);
  povrsinaB=Povrsina(&B);
  povrsAB=  Povrsina  (&presekAB);
  /*ispis rezultata */
 printf( "Povrsina unije        :  %g\n", povrsinaA+povrsinaB-povrsAB);
 printf( "Povrsina preseka      :  %g\n", povrsAB);
 printf( "Povrsina prve razlike :  %g\n", povrsinaA - povrsAB);
 
return 0;
}
void ucitavanje (Pravougaonik *  P)
{  /*ucitavanje koordinata  za odgovarajuca dva temena */
    scanf("%f%f%f%f", &P->x,   &P->y,  &P->x1,    &P->y1);
}
Pravougaonik  Presek  (Pravougaonik *A, Pravougaonik  *B)
{ 
/*Racuna se i vraca presek pravougaonika A i B.
  Ako se A i B ne seku , funkcija vraca pravougaonik cije su sve koordinate jednake 0 */
 
 Pravougaonik  rezultat;   /*presek zadata dva pravougaonika */
 
/*odredjivanje koordinata donjeg levog ugla preseka-uociti tacka i strelica notaciju kod rezultat i kod A, B */
rezultat.x  = (A->x  > B->x) ? A->x : B->x;
rezultat.y  = (A->y  > B->y) ? A->y : B->y;
/*odredjivanje koordinata gornjeg  desnog ugla preseka => relacijski operator manje */
rezultat.x1  =      (A->x1  <  B->x1) ? A->x1 : B->x1;
rezultat.y1  =     (A->y1  < B->y1) ? A->y1 : B->y1;
/*pravljenje korekcije u slucaju da je rezultat preseka prazan */
  if  (rezultat.x  >=  rezultat. x1  ||  rezultat.y  >=  rezultat.y1  )
       rezultat.x=rezultat.y = rezultat.x1  =  rezultat.y1  = 0;
return rezultat;
}
float Povrsina  (Pravougaonik  *P )
{ /*vraca se rezultat mnozenja duzina dveju susednih stranica znajuci za paralelnost sa koordinatnim osama */ 
   return (P->x1 -P->x) * (P->y1 - P->y );
}
67. Pod pretpostavkom da postoji bar jedna reč na ulazu, ispisati na standardni izlaz samo različite reči sortirane leksikografski. Uz svaku reč ispisati i broj pojava. Kraj unosa je marker kraja (EOF), a dužina reči nije veća od 30 karaktera. Smatrati da 1) reč je niska sastavljen isključivo od slova i cifara 2) tip int je dovoljan za čuvanje broja pojava svake reči
/* Samoreferentne strukture  , binarno pretrazivacko stablo   */
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define MAXREC 31
typedef struct drvo_tag
	{
    		char *rec;                 	/* pokazuje na rec  teksta */
    		int broj;                  	/* broj pojavljivanja pod pretpostavkom da je int dovoljan */
    		struct drvo_tag *levo;        /* leva grana */
    		struct drvo_tag *desno;       /* desna grana */
	} drvo;	
/* Prototipovi funkcija */
drvo *addtree(drvo *, char *);
void treeprint(drvo *);
int uzmi_rec(char *, int);
drvo *talloc( void );
char *strdpl(char *);
void osloboditi( drvo *k);
main()
{
   drvo *koren;         /*koren stabla pretrazivanja */
   char rec[MAXREC];    /*sadrzaj reci sa ulaza */
   
   /*ucitavanje reci ciji broj pojavljivanja se broji */
   koren = NULL;
   while( 1 )
   {
   	int kraj = uzmi_rec(rec, MAXREC);
      /*dodavanje novog cvora u stablo ili izmena nad poljem broj vec postojeceg cvora */
	if( strlen(rec)) koren = addtree( koren, rec);
	if(kraj == EOF) break;   /*ucitavanje se vrsi do markera kraja */
   }
   /*stampanje sadrzaja stabla -leksikografski poredak reci */
   treeprint(koren);
   /*oslobadjanje zauzetog prostora za  stablo pretrage */
   osloboditi(koren);   
   return 0;
}
/* addtree - dodaje cvor sa tekstom na koji pokazuje w, na ili ispod p u drvetu*/
drvo *addtree( drvo *p, char *w )
{
   int cond;
   if( p == NULL )       /* naisla nova rec */
   {
   	p = talloc();
      	p->rec = strdpl(w);
      	p->broj = 1;
      	p->levo = p->desno = NULL;
   }
   else if ((cond = strcmp(w,p->rec)) == 0 )
      p->broj++;       /* ponovljena rec */
   else if ( cond < 0 ) /* manje => levi  ogranak  */
      p->levo = addtree(p->levo, w);  
   else                        /*vece =>desni ogranak*/
      p->desno = addtree(p->desno, w);
   return p;
}
void treeprint(drvo  *p)  /* treeprint - rekurzivno stampanje drveta*/
{
    if( p != NULL )
    {
		treeprint( p->levo );
		printf("%4d %s\n", p->broj, p->rec );
		treeprint( p->desno );
    }
}
int uzmi_rec(char s[], int lim)
{
	char c, i = 0;
	/* preskociti  sve znake do slova ili cifre */
	while( !isalnum(c = s[0] = getchar()) && c!=EOF);
	if( c==EOF ) {s[0] = '\0'; return EOF;} /*  prazna rec i vratiti EOF */
	/* ucitati ostatak reci: (u s[0] se vec nalazi prvo slovo) */
	while( (c = getchar()) != EOF && isalnum(c) && i < lim) s[++i] = c;
     	s[++i] =  '\0';	/* zavrsiti  nisku */
	if( c==EOF ) return EOF;
	return i;
}
/* talloc pravi jedan cvor drveta */
drvo *talloc(void)
{ return (drvo *) malloc(sizeof(drvo)); }
char *strdpl(char *s)   /* pravi se kopija niske s */
{
   char *p;
   p = (char *) malloc(strlen(s) + 1 );
   if( p != NULL ) strcpy(p,s);
   return p;
   /* u <string.h> postoji standardna funkcija "strdup" koja obavlja navedene operacije*/
}
void osloboditi( drvo *k)
{ /*rekurzivno se oslobadja levo i desno podstablo korena zadatog stabla */
  if (k->levo)  osloboditi (k->levo);
  if (k->desno)  osloboditi (k->desno);
  free (k);   /*brisanje cvora koji predstavlja koren zadatog stabla */
}

Jelena Grmusa Osnovi programiranja

e-mail: Jelena Grmuša


Copyright © 2002, Jelena Grmusa
Poslednja izmena: februar 2004.
URL: http://www.matf.bg.ac.yu/~jelenagr/op/