Laboratorija za računarsku tehniku

Projekti / Nastava => Nastavni predmeti => Programski jezici => Temu započeo: MilosM 06.03.2011, 20:17

Naslov: Domaci iz programskih jezika
Poruka od: MilosM 06.03.2011, 20:17
mi smo dobili domaci: Napisati program koji proverava da li su zagrade ( i ) dobro uparene. Na primer :
()(()()) tačno, ()())() netačno.
Da li da ga radim preko stringova (preko neke funkcije poredjenja) ili preko obicnih funkcija?
Naslov: Odg: Domaci iz programskih jezika
Poruka od: holodoc 06.03.2011, 21:30
Interesantno. Baš da vidim kakve će ideje da izniknu oko pisanja ovako jednog malečkog parsera :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: MilosM 07.03.2011, 11:01
 :D Polako holodoc, radicemo mi i teze programe :D
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Zepi 07.03.2011, 13:06
Ova je jedna od klasičnijih problematika koja se naravno kasnije komplikuje upotebom svih zagrada {[()]}.

Odmah i naznaka da će biti i težih zadataka :)

Poenta je da ovaj zadatak rešite na bilo koji način sa znanjem koje posedujete do sad.

Funkcije počinjemo sledećeg časa...

Ovo je više logički problem nego problem načina realizacije.

Unosite znakove dok ne unesete enter a onda u unetom tekstu proverite zagrade!!!
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Marko Аcović 09.03.2011, 22:06
Jeste da malo kasnim, ali evo jedne ideje. Mozda nekom bude od koristi.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 1024

int checkBrackets(char *s)
{
int i, status = 0;
int size = strlen(s);
char openBracket = '(';
char closeBracket = ')';

if (s[0] == closeBracket || s[size - 1] == openBracket) {
status = 1;
return status;
}

for(i = 0; i < size; ++i)
{
if (s[i] == openBracket)  status ++;
if (s[i] == closeBracket) status --;
}

return status;
}

int main(void)
{
char* inputString;
inputString = (char *)calloc(MAX, sizeof(char));

printf("Unesi ulazni string: ");
gets(inputString);

printf("%s", checkBrackets(inputString) ? "NETACNO" : "TACNO");
printf("\n");

return EXIT_SUCCESS;
}


Nisam detaljno testirao kod tako da moguce da mozda ima neki bug  :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: marjan 09.03.2011, 23:38
Reče čovek da funkcije rade tek narednog časa  :D
Markova verzija je "na steroidima".

Nego.. ideja je, je li, da se proveri da li string počinje sa otvorenom i završava sa zatvorenom zagradom, a onda se broje zagrade i za svaku otvorenu uveća brojač, a za svaku zatvorenu smanji. Ako je nula na kraju, OK, u suprotnom su neispravne zagrade.
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Marko Аcović 09.03.2011, 23:46
Zato sam i sacekao malo dok ne predju i funkcije tako da lako mogu da isprate ovo sto sam postovao. :) Ne znam samo da li su radili pokazivace. Ako nekom nije jasno, neka se javi pa da pojasnimo. :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: holodoc 10.03.2011, 00:05
Oho imamo i veterana na temi :D Čekamo da vidimo da li još neko da se javi pa da ja pokupim lepo sve Bambije na kraju  :dzavo: Ima valjda Bambija za nagradu? :((
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Marko Аcović 10.03.2011, 00:16
Ako imas elegantnije resenje, dobijas bambije :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: holodoc 10.03.2011, 00:28
Citat: marko_gm  10.03.2011, 00:16
Ako imas elegantnije resenje, dobijas bambije :)
Onda spremaj Bambije :P

Sad stvarno jel ima još neka ideja? :D

Umešao sam se u priču samo zato što sam pre nekih mesečak dana postavio identičan zadatak osobi koja se sprema da upiše faks pa tako voli da kad-kad ukrade po neki trik iz programiranja. Prvo je i on rešio zadatak sa proverom prve i poslednje zagrade i brojanjem ukupnog broja otvorenih i zatvorenih zagrada. Onda sam mu rekao da zaboravi na matematiku i logiku i porazmisli šta je to baš karakteristično za uparivanje :)

Proveo je skoro tri dana crtkajući zagrada ali je na kraju uz moju (malu) pomoć došao do rešenja :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Marko Аcović 10.03.2011, 00:30
Da mi ne bismo provodili po tri dana, kazi koja je fora :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: holodoc 10.03.2011, 00:38
Citat: marko_gm  10.03.2011, 00:30
Da mi ne bismo provodili po tri dana, kazi koja je fora :)
Ma strpi se malo možda nekome nešto još padne na pamet mada ne znam koliko je "legalno" to što se mi mešamo u rađenje domaćih zadataka :D Žepi ima da nas pošalje u kosmos bez toplog donjeg veša  :dzavo:

Elem da ne ispadne da samo duvam u žito a od žiške ni traga ni glasa reći ću samo da je caka u preciznoj definiciji uslova uparenosti zagrada: "svaka otvarajuća zagrada mora da ima odgovarajuću zatvarajuću zagradu". Potreban alat? Ako sam dobro izračunao samo jedna if i for petlja. Nikakve statusne promenjljive nisu potrebne :D Ajd ostaviću malo da prenoći ideja pa možda neko shvati šta sam hteo da kažem.
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Zepi 10.03.2011, 07:48
Veoma interesantna diskusija. Verovatno su se i studenti koji treba da rese domaci obradovali :)

Videcu sad na casu ko je sta uradio pa krecemo sa funkcijama a pokazivace pocinjem za jedno 4 casa tako da im Markovo resenje verovatno samo unosi zabunu.

Kada je rec samo o () zagradama logika je veoma prosta i bukvalno jedan if resava stvar samo kada se logicki resi problem.
Prica sa svim zagradama je vec malo slozenija, ali ima vremena i za to :)

Naslov: Odg: Domaci iz programskih jezika
Poruka od: Marko Аcović 10.03.2011, 13:33
CitatVidecu sad na casu ko je sta uradio pa krecemo sa funkcijama a pokazivace pocinjem za jedno 4 casa tako da im Markovo resenje verovatno samo unosi zabunu.
Bice im jasno kad za to dodje vreme :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: maxogm 13.03.2011, 13:09
Koristi LIFO stack.
Kad se kreces kroz dobijeni string, sve otvarajuce zagrade stavljas na stack. Kad naidjes na neku zatvarajucu zagradu nju proveravas sa elementom sa vrha stack-a itd...

Ideja je ne samo za () vec i za {} [] ()

Kod necu jos da postavim :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: holodoc 13.03.2011, 13:58
Citat: maxogm  13.03.2011, 13:09
Koristi LIFO stack.
Kad se kreces kroz dobijeni string, sve otvarajuce zagrade stavljas na stack. Kad naidjes na neku zatvarajucu zagradu nju proveravas sa elementom sa vrha stack-a itd...

Ideja je ne samo za () vec i za {} [] ()

Kod necu jos da postavim :)
Svaka čast :bravo: Na stack sam i mislio :) K'o što Herr Maksimilijan reče dobra strana tog algoritma je što uopšte nije bitno koje se sve zagrade koriste a ako je u pitanju praktičan izraz sa sve operandima i operacijama dovoljno je napraviti pomoćni string koji će sadržati samo zagrade u redosledu kako se pojavljuje u originalnom stringu. Doduše sa brojem različitih tipova komplikuej se malo i kod ali ništa specijalno.

Hoće li sad bar neko od kolega kojima je domaći i namenjen da proba da napiše kod? :P
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Zepi 14.03.2011, 09:13
Sto se tice resenja studenata mogu samo da kazem da su bila veoma losa.

Neka koda koji nije pogresio za sledeci unos )( .

Maxogm vidi se da si imao iskustva sa ovom problematikom :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Marko Аcović 14.03.2011, 10:37
LIFO stack! Kako se toga ne setih pre! :)
CitatSvaka čast :bravo: Na stack sam i mislio :)
Lepo si mislio samo se nisi dobro odrazio pa te nisam odma' razumeo sta si hteo da kazes. :)

PS. Valjalo bi i aktuelni studenti da se malo ukljuce u razgovor sa predlozima a ne samo mi "veterani" :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: maxogm 14.03.2011, 18:31
Citat: Zepi  14.03.2011, 09:13
Maxogm vidi se da si imao iskustva sa ovom problematikom :)

I moje prvo resenje nije bilo ko zna kakvo ;)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Marko Аcović 15.03.2011, 00:08
Evo jednog resenja. :) Nadam se da nisam omanuo negde :)


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 1024

void push(char i);
char pop(void);
int isInArray(char c, char* niz);

int top;
char stek[MAX];

int main(void) {

    int i, size, pos = -1;
    char* inputString;
    char s;

    char openingBrackets[] = {'{', '[', '('};
    char closingBrackets[] = {'}', ']', ')'};

    inputString = (char *)calloc(MAX, sizeof(char));

    printf("Unesi ulazni string: ");
    gets(inputString);

    size = strlen(inputString);
    for (i = 0; i < size; ++i) {
       
        if ((pos = isInArray(inputString[i], openingBrackets)) > -1) {
            push(inputString[i]);
        } else if ((pos = isInArray(inputString[i], closingBrackets)) > -1) {
            s = pop();
            if (s == 0) {
                printf("NETACNO\n");
                return EXIT_FAILURE;
            }

            pos = isInArray(s, openingBrackets);

            if (inputString[i] != closingBrackets[pos]) {
                printf("NETACNO\n");
                return EXIT_FAILURE;
            }

        } else {
            continue;
        }
        pos = -1; // reset position
    }

    printf("%sTACNO\n", (top == 0) ? "" : "NE");
    return EXIT_SUCCESS;
}

// dodaj element na stek
void push(char i) {
    if (top > MAX) {
        printf("STACK FULL");
        return;
    } else {
        top++;
        stek[top] = i;
    }
}

// uzmi element sa steka
char pop(void) {
    char a;
    if (top <= 0) {
        //printf("STACK EMPTY");
        return 0;
    } else {
        a = stek[top];
        top--;
    }
    return a;
}

// proveri da li se dati karakter nalazi u nizu i
// ako se nalazi, vrati njegovu poziciju
int isInArray(char c, char* niz) {
    int i, size, found = -1;
    size = strlen(niz);
    for (i = 0; i < size; ++i) {
        if (c == niz[i]) {
            found = i;
            break;
        }
    }
    return found;
}

Ako neko ima elegantnije resenje, neka izbaci :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: maxogm 15.03.2011, 19:20
Citat: marko_gm  15.03.2011, 00:08
Evo jednog resenja. :) Nadam se da nisam omanuo negde :)

Probaj da ukucas za string: ()(jskjdks
Naslov: Odg: Domaci iz programskih jezika
Poruka od: maxogm 15.03.2011, 19:26
Jos nesto ali ovo je ne vezano za Markovo resenje i da li to tu ima.

Funkcija:

   gets(input);


je deprecated i nebi je trebalo koristiti. Koriscenjem funkcije gets() niste ogranicili korisnika koliko sme da unese maksimalno karaktera pa veoma lako moze doci do pucanja vase aplikacije ukoliko niste alocirali dovoljnu kolicinu memorije. Bolje je koristit fgets()


   if(fgets(input, 100, stdin) != NULL)
   {
     free(input);
   }
Naslov: Odg: Domaci iz programskih jezika
Poruka od: holodoc 15.03.2011, 19:28
Citat: maxogm  15.03.2011, 19:26
Jos nesto ali ovo je ne vezano za Markovo resenje i da li to tu ima.

Funkcija:

   gets(input);


je deprecated i nebi je trebalo koristiti. Koriscenjem funkcije gets() niste ogranicili korisnika koliko sme da unese maksimalno karaktera pa veoma lako moze doci do pucanja vase aplikacije. Bolje je koristit fgets()


   if(fgets(input, 100, stdin) != NULL)
   {
     free(input);
   }

Ko to nama koristi -Wall parametar u gcc kompajleru? :P
Naslov: Odg: Domaci iz programskih jezika
Poruka od: maxogm 15.03.2011, 19:34
Citat: holodoc  15.03.2011, 19:28
Ko to nama koristi -Wall parametar u gcc kompajleru? :P
Pa kad nemam ni jedan drugi C kompajler :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: holodoc 15.03.2011, 19:39
Citat: maxogm  15.03.2011, 19:34
Citat: holodoc  15.03.2011, 19:28
Ko to nama koristi -Wall parametar u gcc kompajleru? :P
Pa kad nemam ni jedan drugi C kompajler :)
Ista sam ti taka :D U poslednje vreme sve češće hvatam samog sebe kako se preko SSH kačim na kućni server da bih na brzaka nešto iskompajlirao sa gcc-om :D Samo da mi onaj šuntavi nano ne smeta sve više i više :(
Naslov: Odg: Domaci iz programskih jezika
Poruka od: marjan 15.03.2011, 20:01
CitatProbaj da ukucas za string: ()(jskjdks
Nemoj, Marko, to je neki shellcode, će da ti pobriše MBR!
:P
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Marko Аcović 15.03.2011, 21:03
U pravu ste. :) Ipak ima bug :). Dodao sam jos jednu proveru u kodu (modifikovao sam postojeci primer koji sam postovao) i sad bi trebalo da radi. Probajte :)

PS. Znam da je gets() deprecated i da treba da se koristi fgets() ali me mrzelo da je ubacujem, jer fgets() dodaje i enter na kraj stringa a ovo je ipak )demonstracioni primer a ne nesto sto ce da radi u realnom svetu :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: MilosM 17.03.2011, 23:47
E hvala ljudi na pomoci, iako je sustina zadatka zakasnila, svi smo se zeznuli sa )(!!!! :D
i tako, domaci idu dalje...
sada imamo domaci sa nizovima preko funkcija...
valjda cemo se snaci :)
Opet hvala!!!!
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Marko Аcović 17.03.2011, 23:55
Kad imate neki problem, prvo pokusajte da ga resite sami pa ako bas ne ide, bacite ovde da vam pomognemo ali prvo morate sami da pokusate. :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: holodoc 18.03.2011, 01:41
Nizovi su verovatno jedna od najbitnijih stvari koje su izmišljene u prethodnom milenijumu. Ako ne računamo naravno mašinu za kafu  =))
Naslov: Odg: Domaci iz programskih jezika
Poruka od: PulSaR 18.03.2011, 09:24
je l moze neko da postavi taj drugi domaci? hvala
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Marko Аcović 18.03.2011, 09:30
Citatje l moze neko da postavi taj drugi domaci? hvala

1. Koji je drugi domaci? :)
2. Nemoj da ocekujes da ce neko da vam radi domace a da ne mrdnete ni prstom? Forum ne sluzi za to!
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Zepi 18.03.2011, 09:32
Citat
je l moze neko da postavi taj drugi domaci? hvala

Treba ti resenje ili tekst ???

Naslov: Odg: Domaci iz programskih jezika
Poruka od: PulSaR 18.03.2011, 19:46
tekst tekst :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: MilosM 18.03.2011, 20:31
. Napisati funkciju koja radi sazimanje istih elemenata niza na sledeci nacin:
•   Isti elementi niza koji se pojavljuju zaredom se zamenjuju sa sumom njihovih vrednosti.
•   Nije dozvoljeno koriscenje pomocnog niza
2,2,2,2,3,4,4,5,6,6,5      //dobija se
8,3,8,5,12,5

ja imam problem samo oko pomeranja niza, u smislu dobijam bas iz ovog primera 8,2,2,2,3,8,4,5,12,5
Naslov: Odg: Domaci iz programskih jezika
Poruka od: holodoc 18.03.2011, 21:56
Jeste li radili continue direktivu? Uz pomoć nje možeš bilo gde u petlji da nasilno izazoveš prelazak na sledeću iteraciju for petlje kojom prelaziš kroz kompletan niz :)

Dakle generalna ideja je da koristiš petlju koja će prolaziti kroz kompletan niz i da u svakoj petlji ispituješ da li je neki uslov ispunjen pa ako jeste da nešto odradiš i da izazoveš sledeću iteraciju a ako nije treba da uradiš nešto da naznačiš rezultat dotadašnjih iteracija :)

Neću namerno da postavljam kod jer je ovo poprilično lak zadatak ako znaš da koristiš continue direktivu :) Ako baš želiš dodatnu pomoć možeš da postaviš svoj kod ovde. Naravno ako to nije protiv pravila :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: marjan 18.03.2011, 22:26
Super su ovi domaći...
Malo da se "prokrče" ganglije.
Continue, continue, šta to bi  :o Može i bez continue, bar ovo što sam nešto "sklepao" na brzinu (dobro, nije baš na brzinu :)))
Dakle, neki algoritam je da jedan brojač ide normalno redom kroz elemente, a drugi da se kreće "brže", sabirajući usput one koji se ponavljaju i smeštajući zbirove u elemente redom (prema prvom brojaču).


Naslov: Odg: Domaci iz programskih jezika
Poruka od: holodoc 18.03.2011, 23:48
Citat: marjan  18.03.2011, 22:26
Super su ovi domaći...
Malo da se "prokrče" ganglije.
Continue, continue, šta to bi  :o Može i bez continue, bar ovo što sam nešto "sklepao" na brzinu (dobro, nije baš na brzinu :)))
Dakle, neki algoritam je da jedan brojač ide normalno redom kroz elemente, a drugi da se kreće "brže", sabirajući usput one koji se ponavljaju i smeštajući zbirove u elemente redom (prema prvom brojaču).
Možda nisam dobro razumeo ideju ali šta tačno podrazumevaš pod time da se drugi algoritam kreće "brže"? :) To mi nekako liči na još jednu for petlju. Plus što je uslov zadatka da nisu dozvoljeni pomoćni nizovi. Mašim li poentu negde?

EDIT: Zadatak bi bio mnogo praktičniji i vredniji kada bi se rezultati obrade ipak smeštali u neki rezultantni niz ne samo da se ispišu :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Marko Аcović 19.03.2011, 00:05
CitatZadatak bi bio mnogo praktičniji i vredniji kada bi se rezultati obrade ipak smeštali u neki rezultantni niz ne samo da se ispišu
Slazem se sa ovim. Ako je potrebno da se rezultat koristi na dalje, bolje da se smesti u poseban niz. Mozda ne bi bilo lose da se taj uslov skine iz zadatka.
Naslov: Odg: Domaci iz programskih jezika
Poruka od: marjan 19.03.2011, 00:07
CitatMožda nisam dobro razumeo ideju ali šta tačno podrazumevaš pod time da se drugi algoritam kreće "brže"?  To mi nekako liči na još jednu for petlju. Plus što je uslov zadatka da nisu dozvoljeni pomoćni nizovi. Mašim li poentu negde?
Pa i ne koristi se nikakav pomoćni niz, nego se "gazi" postojeći.
Rekoh već da sam primer sklepao, ima for i while, nije lep, ali radi.
Šta ću, nešto nabadam perl ovih dana, pa sam raspoložen za quick 'n' dirty kod. Što se nekad pretvori u "just dirty" kod:D

A niz je tu, novi-stari, a i  mala "kvaka" je to "pomeranje niza", kako ga nazva kolega.
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Zepi 19.03.2011, 00:10
Citat
EDIT: Zadatak bi bio mnogo praktičniji i vredniji kada bi se rezultati obrade ipak smeštali u neki rezultantni niz ne samo da se ispišu

Samo da ponovim da se radi sazimanje niza tj rezultat se ne ispisuje nego se niz sazima i u njemu se nalazi rezultat koji se kasnije moze ponovo obradjivati ali je normalno original niza unisten.

Ipak takav je ovaj zadatak, sazimanje niza bez koriscenja pomocnog niza :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: holodoc 19.03.2011, 00:28
Citat: Zepi  19.03.2011, 00:10Samo da ponovim da se radi sazimanje niza tj rezultat se ne ispisuje nego se niz sazima i u njemu se nalazi rezultat koji se kasnije moze ponovo obradjivati ali je normalno original niza unisten.

Ipak takav je ovaj zadatak, sazimanje niza bez koriscenja pomocnog niza :)
Nisam baš siguran da je dobra ideja mešati početne podatke i rezultate obrade a evo i zašto :)

Recimo da su za početne podatke izabrane sledeće vrednosti int array[] = {2,2,2,2,3,4,4,5,6,6,5}; Dakle to je direktno inicijalizovan početni niz bez eksplicintog navođenja dužine koja u ovom slučaju iznosi 11 elemenata. 

Ako je rezultat obrade 8,3,8,5,12,5 to znači da će na kraju niz izgledati ovako. array = {8,3,8,5,12,5,4,5,6,6,5};
Šta su od ovoga početni podaci a šta rezultat? :D

Sve dok ne počnu da se rade pokazivači ili makar strukture ovakve funkcije i nemaju baš mnogo preterane koristi u praksi :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Zepi 19.03.2011, 00:42
Za sad im je poenta da logici rese ovaj problem a to resenje dimenzije novog niza da vrate kao rezultat funkcije.

Na taj nacin se prevazilazi problem elemenata koji ostaju u nizu, sto i nije neka greska sobzirom ako se zna da svaki staticki alociran niz osim kada je potpuno iskoriscen ima elemente koje ne treba koristiti, tj. koristi se cuveno n kao dimenzija niza sto ne znaci da ih posle tog n nema vise :)

Zato treba da naprave funkciju int sazimanje(int a[], int n) koja bi vratila kao rezultat novo n tj bila bi pozvana na sledeci nacin u main-u
n = sazimanje(a, n);

A nakon ovoga se nastavlja sa koricenjem klasicnog n za npr ispis niza
ispis(a, n);
Naslov: Odg: Domaci iz programskih jezika
Poruka od: MilosM 19.03.2011, 13:17
Znaci funkcija sazimanje niza menja dimenziju niza na onoliko koliko se puta sazimanje dogodi...
dobro... probacu nesto...   :whistle2:
Hvala svima 'veteranima' na pomoci!!!  :bravo:
PS: Nismo radili continue...
Naslov: Odg: Domaci iz programskih jezika
Poruka od: holodoc 19.03.2011, 15:22
Citat: MilosM  19.03.2011, 13:17PS: Nismo radili continue...
Čudno... Ako ste radili petlje (for, while, do) onda bi trebalo da ste se upoznali sa continue i break jer dobar deo algoritama se oslanja na njih. Ajd da budem bar malko od koristi :) Komentari u kodu bi trebali da budu i više nego jasni ali ako ima pitanja... Well... Pa tu smo negde :)

continue se koristi za bezuslovni prelazak na sledeću iteraciju petlje (bilo da je for, while ili možda do) dok break služi za bezuslovan prekid najbliže petlje i prelazak na izvršavanje prve linije koje dolazi posle prekinutog bloka.

continue direktiva
/**
* Izracunavanje sume svih brojeva koji nisu deljivi sa brojem 7 uz pomoc continue direktive.
*/
#include <stdio.h>
#include <stdlib.h> // Zaglavlje sadrzi konstantu EXIT_SUCCESS

int main(){
int i, sum = 0, length;
int data[] = {1,3,7,15,47,49,127};

// Duzina niza (dobija se deljenjem ukupnog prostora u memoriji sa velicinom koju zauzima jedan takav podatak, u ovom slucaju int).
length = sizeof(data) / sizeof(int);

for(i = 0; i < length; i++){ // Za svaki element niza...
if(!(data[i] % 7)){ // ... proverava se da li njegov moduo 7 ne ostavlja ostatak sto znaci da je broj deljiv sa 7...
continue; // ... pa ako jeste njega cemo da preskocimo i odmah prelazimo na sledecu iteraciju for petlje (nista se od ove linije nadalje u ovoj iteraciji ne izvrsava).
}
sum += data[i]; // Do ovog dela stizemo samo ako je broj nedeljiv sa 7.
}
printf("Suma svih brojeva koji nisu deljivi sa 7 je: %d!\n", sum);
getchar(); // Sluzi cisto da se ekran ne zatvori kod testiranja - u prakticnim programima ne sluzi nicemu.
return EXIT_SUCCESS; // Koriscenje EXIT_SUCCESS-a umesto nule je bolje jer garantuje kompatibiulnost sa svim C kompajlerima (nije svuda nula indikacija uspesnog izvrsenja)
}


break direktiva
/**
* Izracunavanje sume vrednosti u nizu do prvog "naleta@ na broj deljiv sa 7.
*/
#include <stdio.h>
#include <stdlib.h> // Sadrzi EXIT_SUCCESS

int main(){
int i = 0, sum = 0, length;
int data[] = {47, 87, 12, 16, 17, 16, 15, 119, 6, 13};
length = sizeof(data) / sizeof(int); // Duzina niza

do { // Petlja se vrti sve dok se ne ispuni uslov iz while linije (pogledati dole)...
if(!(data[i] % 7)){ // ... ukoliko je neki od elemenata deljiv sa sedam...
break; // momentalno se prekida najbliza petlja (u ovom slucaju do) i prelazi na prvu liniju posle nje (to bi bio if blok oznacen sa #1).
}
sum += data[i]; //... u suprotnom posto broj nije deljiv sa sedam petlja se nastavlja a suma uvecava...
i++;
} while (i < length); // ... sve dok je redni broj elementa niza manji od ukupnog broja (zato sto je i zero-based a length non-zero-based!!!)

// #1
if(i < length - 1){ // Ukoliko je vrednost i po izlasku iz petlje manja od broja clanova niza znaci da je bilo nasilnog izlaza iz petlje...
printf("Doslo je do prekida na %d. elementu!\nSuma DO elementa pod rednim brojem %d je %d.\n", i + 1, i + 1, sum);
} else { // ... u suprotnom nije bilo elemenata koji su deljivi sa sedam.
printf("Nema prekida.\nUkupna suma je %d.\n", sum);
}

getchar();
return EXIT_SUCCESS;
}

Naslov: Odg: Domaci iz programskih jezika
Poruka od: Marko Аcović 19.03.2011, 21:21
Vezano za break i continue, mislim da je najbolje da pogledate Krausovu knjigu "Programski jezik C" gde su slikovito prikazani kako funkcionisu break i continue.
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Asrijel 24.03.2011, 14:23
Break smo radili za continue hvala.
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Krule 05.04.2011, 14:55
I možemo li dobiti rešenje tog famoznog zadatka za domaći ?

Citat: MilosM  18.03.2011, 20:31
. Napisati funkciju koja radi sazimanje istih elemenata niza na sledeci nacin:
•   Isti elementi niza koji se pojavljuju zaredom se zamenjuju sa sumom njihovih vrednosti.
•   Nije dozvoljeno koriscenje pomocnog niza
2,2,2,2,3,4,4,5,6,6,5      //dobija se
8,3,8,5,12,5
Inače nisam na kursu RT al me živo interesuje rešenje jer moj kod SAMO ispisuje rešenja?  >:D<
Naslov: Odg: Domaci iz programskih jezika
Poruka od: holodoc 05.04.2011, 16:05
Citat: Krule  05.04.2011, 14:55
I možemo li dobiti rešenje tog famoznog zadatka za domaći ?

Citat: MilosM  18.03.2011, 20:31
. Napisati funkciju koja radi sazimanje istih elemenata niza na sledeci nacin:
•   Isti elementi niza koji se pojavljuju zaredom se zamenjuju sa sumom njihovih vrednosti.
•   Nije dozvoljeno koriscenje pomocnog niza
2,2,2,2,3,4,4,5,6,6,5      //dobija se
8,3,8,5,12,5
Inače nisam na kursu RT al me živo interesuje rešenje jer moj kod SAMO ispisuje rešenja?  >:D<
Pa možeš da postaviš kod ovde i dole staviš jedan veliki debeli copyright da te ostali ne bi kopirali a onda možemo da vidimo kako možeš da dovršiš zadatak :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Zepi 06.04.2011, 09:36
Tema je otvorena za diskusiju pa ne bi bilo interesantno da se postavi resenje.

Najbolje bi bilo da svako ko ima problema postavi svoj kod koji bi diskutovali.
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Krule 07.04.2011, 01:14
Evo mog koda:
//autor: Krule
//Copyright 2011 Mirko Kruscic. All rights reserved.                       

#include "stdio.h"

void unos(int n, int a[50])
{                                 
for (int i=0; i<n; i++)         
{                           
printf("A[%d]= ",i+1); 
scanf("%d",&a[i]);       
}
}                               
void func(int a[50], int n, int k)
{
int i,j,s;
k=0;
for (i=0;i<n;)
{
s=a[i];
for (j=i+1;j<n;j++)
if (a[i]==a[j])
s+=a[j];
else
{
i=j;
break;
}
a[k]=s;
k+=1;
}
}

void ispis(int a[50], int k)
{
for (int i=0; i<k-1; i++)       
printf("A[%d]= %2d , ",i+1,a[i]);
}

int main()
{
int a[50],n,k=0;
printf("Unesi dimenziju a potom i elemente niza: ");
scanf("%d",&n);
printf("\n");
unos(n,a);
func(a,n,k);
printf("Novi niz je: \n");
ispis(a,k);

getchar();
return 0;
}


Koristim Visual Studio 2008 i konstantno mi pokazuje gresku : Unhandled exception at 0x00000004 in sazimanje niza cpp.exe: 0xC0000005: Access violation reading location 0x00000004.
:mad:
Tako da za kod ne mogu 100% da garantujem :dontknow:
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Marko Аcović 07.04.2011, 09:48
Nemam na poslu VS pa ne mogu da probam. Probaj da debugujes liniju po liniju da vidis gde puca.
Naslov: Odg: Domaci iz programskih jezika
Poruka od: marjan 07.04.2011, 10:16
Puca svakako. Negde u func
Ako kreneš da dibaguješ, verovatno ćeš ostati jaaako dugo, jer ova petlja nema kraja:
for (i=0;i<n;)
a i se posle ne uvećava nikako i for loopuje non-stop.

A ona funkcija ispis ti radi sa k, a k stavljaš da je nula, pa ispis ne odradi ništa.
BTW1, među argumentima funkcija nema potrebe stavljati dimenziju niza, dovoljno je int a[] ili čak int *a.
BTW2, komentarisanje koda je dosadno, ali se isplati.

Tako da - natrag za crtaću tablu ;)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Zepi 07.04.2011, 10:24
Velika greska koju pravis je u funkciji func jer ne uspevas da vratis dimenziju novog niza K na nacin na koji si zamislio.

Funkcije koje tenutno radimo vrse prenos parametara po vrednosti pa je svaka promenljiva koja se prenosi preko argumenata funkcije lokarno kopirana unutar funkcije i svaka promena na njoj se ne vidi van funkcije.

U prevodu
Citat
void func(int a[50], int n, int k)

nece  imati nikakvu vrednost za sledecu funkciju pa ti se nikada nece ni ispisati niz jer k nema vrednost koju treba da ima.

Probaj da je ispises pre funkcije ispis tj.
Citat
printf("k= %d ", k);
void ispis(int a[50], int k)

Moraces k da vratis kao rezultat funkcije da bi ovo radilio.

Citat
Puca svakako. Negde u func
Ako kreneš da dibaguješ, verovatno ćeš ostati jaaako dugo, jer ova petlja nema kraja:
for (i=0;i<n;)
a i se posle ne uvećava nikako i for loopuje non-stop.

Nije beskonacna petlja jer radi dodelu i=j kad god susedna dva elementa u nizu nisu ista pa se tako pomera i pa ce i petlja da se zavrsi :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: marjan 07.04.2011, 10:36
CitatNije beskonacna petlja jer radi dodelu i=j kad god susedna dva elementa u nizu nisu ista pa se tako pomera i pa ce i petlja da se zavrsi
A šta kada su svi elementi različiti??

Evo npr kako loopuje.. Da budem precizniji - ovo je potencijalno beskonačna petlja :)
(http://dl.dropbox.com/u/18532910/loop.png)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Zepi 07.04.2011, 11:08
Kompajlirao na brzinu u glavi i pogledao kod koji radi kada jesu isti.

Jeste problem sa razlicitim elementima jer nema nastavak iteracije pa je uvek i<n.
Naslov: Odg: Domaci iz programskih jezika
Poruka od: marjan 07.04.2011, 11:10
Nisam se ja udubljivao mnogo u kod, samo sam pustio i video otprilike prvi "prelaz" da ima falinki.
Najbolje da Mirko malo ispravi, iskomentariše, isproba, pa polako ;)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Krule 07.04.2011, 13:13
Mislio sam da mi bag prijavljuje zbog VS, jer tek sam počeo da radim sa njim pa nisam znao da treba da menjam kod, zato sam i reko da ne garantujem da je ispravan jer nisam uspeo da ga proverim. :whistle2:

Hvala na komentarima i ispravkama, odoh o5 da se bacim na kod pa se javljam sa novim rez.  =P~

edit: a[50] >> 50 treba samo u deklaraciji ne i u argumentima f-je... my bad  :banghead:   
Thx  :klanja:
Naslov: Odg: Domaci iz programskih jezika
Poruka od: marjan 07.04.2011, 13:30
Možda bi ti neko i konkretnije pomogao, ispravljajući kod, ali si stavio
//Copyright 2011 Mirko Kruscic. All rights reserved.
tako da moraš ti.
:)

Citattreba samo u deklaraciji ne i u argumentima f-je... my bad
Funkcija može da uzme samo pokazivač, odnosno početak niza i da "tera" po njemu. Ne možeš prenositi čitav niz kao parametar. U stvari, kada bi moglo, bilo bi vrlo nezgodno, jer bi lako potrošio stek, kopirajući elemente pri pozivu funkcije. A i trebaju nam svakako izmene nad originalom.
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Zepi 07.04.2011, 14:22
Sto se tice nizova i njihovog vracanja kroz funkcije sve ce biti jasnije uskoro kad se pocne sa pokazivacima, ali o tom potom.
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Krule 08.04.2011, 10:43
Finaly 

//Copyright 2011 Mirko Kruscic. All rights reserved.

#include "stdio.h"

void unos (int a[], int n)
{
for (int i=0;i<n;i++)
{
printf("A[%d]= ",i+1);
scanf("%d",&a[i]);
}
}
void ispis (int a[], int n)
{
for (int i=0;i<n;i++)
printf("\nA[%d]= %d",i+1,a[i]);
}

int testiranje(int a[], int n)
{
int b=0,k,s;
for (int i=0;i<n;i++)
{
s=a[i];
k=i+1;
while (a[i]==a[k])
{
s+=a[i];
k++;
}
a[b]=s;
b++;
if (k!=i+1)
i=k-1;

}
return (b);
}

int main()
{
int k,a[250],n;
printf("Uneti broj clanova niza a potomi niz: ");
scanf("%d",&n);
unos(a,n);
k=testiranje(a,n);
printf("\n\nNovi niz je: ");
ispis(a,k);

getchar();
return 0;
}


Ako Vam ovaj kod bude, mozda nekim slucajem  :D, bagovao ostavicu i c++ kod posto sam prvo u njemu radio pa posle samo prebacio cin i cut u scanf i printf i sve sto ide uz te komande.  ;)

Edit: Tek sam sad video da ima skoro isti zadatak na vezbama iz struktura i da je umesto
if (k!=i+1)
     i=k-1;
moglo da se jednostavno napise k++;i++; jos u while petlji :D
Naslov: Odg: Domaci iz programskih jezika
Poruka od: holodoc 08.04.2011, 16:57
Mali praktičan savet. Pokušaj da funkcije koristiš isključivo za kod koji će se izvršavati više od jednog puta, tj. za tzv. "reusable" kod. Funkcije mogu da spreče nepotrebno ponavljanje koda ali mogu i bitno da uspore aplikaciju jer se svakim pozivom funkciji menja kontekst toka izvršavanja aplikacije pa hardver mora da troši dodatne procesorske cikluse za te operacije.

Za ovako jednostavan primer kao što je tvoj to i nije preterano veliki problem ali pogledaj recimo sledeći primer gde imaš petlju koja ima par desetina ili čak stotina hiljada iteracija.
Primer 1
void funkcija(){
// Kod funkcije.
}

for(i = 0; i < 100000; i++){
     funkcija();
}


Primer 2
for(i = 0; i < 100000; i++){
     // Kod "funkcije".
}

Sa 10 000 i više iteracija preciznim merenjem ćeš utvrditi značajnu prednost drugog primera jer isti ne troši vreme na pozivanje funkcije i time gubi ne dodatno vreme. Tek sa 100 000 i više iteracija prednost nepozivanja funkcija kada to zaista nije potrebno se uočava.

U tvom konkretnom primeru razlike u performansama nećeš uočiti ako sadržaj funkcija unos() i ispis() ubaciš u main() ali ćeš pratiti ustaljenu praksu koja kaže da se kod koji se ne upotrebljava više od jednog puta ne odvaja u funkcije. Plus što je kod lakši za praćenje.

Da ne bude zabune, kod C++-a je situacija recimo skoro potpuno drugačija jer se tamo zbog tzv. "enkapsulacije" (težnje da klase mogu da budu "same sebi dovoljne i nezavisne od ostalih") gleda da se čak i najmanja sposobnost klase evidentira metodom (ekvivalent funkciji sa bitnom razlikom da metoda mora da opisuje sposobnost klase). Otom potom :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: marjan 08.04.2011, 20:28
Znam da malo idem u offtopic, ali me holodoc asocirao da dodam - znači, Žepi,  holodoc je kriv, nisam ja!  :P

Elem, pozivanje funkcije podrazumeva "pakovanje" parametara na stek, kao i povratne adrese pozivajuće f-je itd, a ako ima toga puno, onda se stek optereti, a ako se mnogo često f-je pozivaju, onda to "šetanje" ume da potraje, pa ako postoji rekurzija, i da pukne itd.
Elem, postoji ono što se zove inline funkcija - kada se f-ja definiše kao inline, znači da kad je neko pozove, kod ne skače na nju, nego je kod faktički iskopiran u pozivajućoj f-ji - ovde u main()u. Praktikuje se za manje funkcije - u suprotnom nije baš celishodno, jer uvećava program.

Elem, evo mali primer, prost mnogo.

#include <stdio.h>
inline void radinesto1(int i)
{
while (i <1000)
i++;
printf("Zavrsio prvi\n");
}

void radinesto2(int i)
{
while (i <1000)
i++;
printf("Zavrsio drugi!\n");
}


int main(int argc, char**argv)
{
int broj;
printf("Unesi neki mali broj :) %d:\n"),
scanf("%d", &broj);

radinesto1(broj);
radinesto2(broj);

return 0;
}

Ovde je jedna funkcija (radinesto1) inline, a druga (radinesto2) je "obična". A rade iste stvari i telo izgleda identično. Uvećava neki brojač do hiljadu.
Kada se pogleda asembly (počev od starta main-a), vidi se da se "pozivanje" inline svodi na kopiranje inline koda, dok druga f-ja ima regularan call.
(http://dl.dropbox.com/u/18532910/inline.png)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: holodoc 08.04.2011, 21:00
Nevolja kod inline funkcija je što kompajleri umeju ponekad da se prave mutavi i da ih ignorišu pa ih zato nećeš baš često nalaziti u kodu sa multiplatformskom podrškom :) U svakom slučaju poenta je ista... Ne pozivati funkciju ako kod može lepo da se izvrši u kontekstu trenutnog toka izvršavanja.
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Zepi 09.04.2011, 23:37
Što se tiče poziva funkcija koje se možda samo jednom pozivaju slažem se da može doći do gubitka performansi ali samo u ekstremni slučajevima sa rekurzivnim funkcijama na primer to može imati uticaja.

Pretmet prvog dela vežbi iz programskih jezika upravo rad sa funkcijama pa za vežbu treba svaki problem da reše preko funkcija i da koriste što više manjih funkcija dok se ne naviknu.
Ali ne vezano za ovo ja ovakav pristup preporučujem iz više razloga:

Naslov: Odg: Domaci iz programskih jezika
Poruka od: holodoc 10.04.2011, 00:14
Citat: Zepi  09.04.2011, 23:37Što se tiče poziva funkcija koje se možda samo jednom pozivaju slažem se da može doći do gubitka performansi ali samo u ekstremni slučajevima sa rekurzivnim funkcijama na primer to može imati uticaja.
E ali rekurzivne funkcije su danas po nečemu toliko posebne da zbog tog "nečeg"mogu ponekad da sa'rane i klasičnu iterativnu obradu podataka (klasične petlje u neprekidnom toku obrade) :dzavo:

"Tail recursion". Ring a bell? :) Iskreno nemam pojma kako ovo domaći autori prevode ako uopšte prevode. Možda "repno ponavljanje" :bla: Ukratko, ovo je fora pozajmljena iz programskog jezika Scheme (prvo su njegovi kompajleri podržavali ovaj vid optimizacije) a poenta cele priče je da ako rekurzivna funkcija vrši rekurziju u poslednjoj liniji funkcije koja je već pod rekurzijom onda se uopšte ne radi granjanje i formiranje novog steka (ne radi se poziv) već kompajler radi posebnu vrstu inline zamene koda i tako sprečava da se uopšte rade bilo kakvi prekidi (i popunjavanje steka kad smo već kod toga) :)

U kratkim crtama objašnjenje kako prepoznati "repnu" rekurziju.
void funkcija(){
     // Neki kod...
     return funkcija();
}

Ovde se jasno vidi da se rekurzivni poziv nalazi na poslednjoj liniji funkcije koja je potencijalno već rekurzivno pozvana pa pošto je to poslednja linija nema potrebe da se pamti adresa na koju program treba da se vrati kad se završi rekurzivni poziv (jer nema više linija posle rekurzivnog poziva) :) Kompajler ovo jasno identifikuje kao tail rekurziju i optimizuje krajnji program sa raznim inline zamena i sl.

Dobra stvar kod tail rekurzije je što je bar 99% rekurzivnih funkcija ovog tipa. Da ne bude zabune ne mora poslednja linija koda u rekurzivnoj funkciji da bude rekurzivni poziv već je bitno samo da tok programa ne sadrži više ni jednu liniju posle rekurzivnog poziva. Evo jednog primera kako najčešće izgleda realna rekurzivna funkcija.
void funkcija(){
     if(uslov){
          return funkcija();
     } else {
          // Neki kod...
     }
}

Ovde se jasno vidi da je tok uslovnog if bloka takav da posle njega nema više nijedne linije koda i ovo će kompajler jasno prepoznati kao "tail rekurziju" :)

"Tail rekurzija" mora eksplicitno da se "uključi" u kompajlerima sa -O opcijama i ako me sećanje dobro služi (nisam odavno pisao C/C++ kod) potreban je level 3 optimizacije -O3 da bi "tail rekurzija" bila uključena.

EDIT: Uz ovaj post sam prikačio jedan PDF dokument koji detaljno objašnjava "tail rekurziju". Inače ovo je diplomski rad Marka Probsta, u tadašnje vreme diplomca Tehničkog fakulteta u Beču koji je u velikoj meri odgovoran za to što je GNU GCC dobio dobru podršku za "tail rekurziju" :) Okačio sam ga ovde zato što je originalan dokument u PostScript formatu pa bi bio potreban Acrobat Distiller da se od njega dobije PDF dokument. Ovako sam ga ja konvertovao u PDF :)

Čisto usput da vidite kako izgleda diplomski rad diplomca u bečkom sistemu visokoškolskog obrazovanja :)

P.S. Negde možda ima teksta na nemačkom ali to ne bi trebalo da predstavlja problem jer su najbitniji delovi na engleskom.
Naslov: Odg: Domaci iz programskih jezika
Poruka od: MilosM 11.05.2011, 18:41
ok... prvi kolokvijum je prosao. Osvojio sam 70% poena, kodovi funkcija su uglavnom bili ok, ali pozivanje funkcije je bilo veoma lose. Hteo sam to naravno da popravim smatrajuci da znam vise. bio je i popravni osvojio sam 59% i ukapirao da sam naucio pozivanje funkcija ali kodove nisam umeo da resim, ipak je programiranje test inteligencije...   <:-P
Elem...  domaci idu dalje radili smo pokazivace, i poslednji cas smo radili malloc, realloc i calloc, funkcije za dinamicku alokaciju niza...

domaci je naci presek dva niza, na casu smo radili uniju pa cu je porediti na osnovu tog zadatka...

Ideje?  =||
Naslov: Odg: Domaci iz programskih jezika
Poruka od: holodoc 11.05.2011, 18:49
Citat: MilosM  11.05.2011, 18:41
ok... prvi kolokvijum je prosao. Osvojio sam 70% poena, kodovi funkcija su uglavnom bili ok, ali pozivanje funkcije je bilo veoma lose. Hteo sam to naravno da popravim smatrajuci da znam vise. bio je i popravni osvojio sam 59% i ukapirao da sam naucio pozivanje funkcija ali kodove nisam umeo da resim, ipak je programiranje test inteligencije...   <:-P
Elem...  domaci idu dalje radili smo pokazivace, i poslednji cas smo radili malloc, realloc i calloc, funkcije za dinamicku alokaciju niza...

domaci je naci presek dva niza, na casu smo radili uniju pa cu je porediti na osnovu tog zadatka...

Ideje?  =||

Pa nema tu ideja. Dinamičko alociranje ti neće pomoći da na drugačiji način rešiš zadatak već da budeš u mogućnosti da radiš sa podacima koji nemaju predefinisanu veličinu :) A

ko znaš da uradiš zadatak sa statički zadatim dužinama niza onda samo treba da uradiš isti taj kod tako da koristi dinamički alociranu memoriju.
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Marko Аcović 11.05.2011, 21:10
Evo ti ukratko ideja:


/**
* Proverava da li dati element postoji u nizu
*
* @param int* a, pokazivac na niz
* @param int n, dimenzija niza
* @param int elem, element za koji se proverava da li je u nizu
* @return int 1=elem postoji u nizu, 0=elem ne postoji u nizu
*/   
int inArray(int *a, int n, int elem) {
    int i;
    int found = 0;
    for (i = 0; < n; ++i) {
        if (elem == a[i]) {
            found = 1;
            break;
        }
    }
    return found;
}

int main(void)
{
    // deklaracija promenljivih
    // unos elemenata oba niza
    // definisi rezultujuci niz koji ce da sadrzi presek
    int *result = calloc(n, sizeof(int));
   
    // prodji kroz elemente veceg niza (npr. niz A)
    j = 0;
    for (i = 0; i < n; ++i) {
        // za svaki element niza A proveri da li se nalazu u B
        if (inArray(b, m, a[i])) {
            // ako se nalazi, proveri da li se nalazi u rezultujucem nizu
            // ovo nam treba da se neki od elemenata ne bi ponavljao
            if (!inArray(result, n, a[i])) {
                // ako se NE nalazi u rezultujucem nizu, ubaci u rezultujuci niz
                result[j++] = a[i];
            }
        }
    }
   
    // stampaj rezultujuci niz
    return 0;
}


Kod nisam proveravao, jer pisem napamet ali to bi mogla da ti bude ideja. Nadam se da sam bio od pomoci :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: holodoc 11.05.2011, 21:52
Citat: marko_gm  11.05.2011, 21:10
Evo ti ukratko ideja:


/**
* Proverava da li dati element postoji u nizu
*
* @param int* a, pokazivac na niz
* @param int n, dimenzija niza
* @param int elem, element za koji se proverava da li je u nizu
* @return int 1=elem postoji u nizu, 0=elem ne postoji u nizu
*/   
int inArray(int *a, int n, int elem) {
    int i;
    int found = 0;
    for (i = 0; < n; ++i) {
        if (elem == a[i]) {
            found = 1;
            break;
        }
    }
    return found;
}

int main(void)
{
    // deklaracija promenljivih
    // unos elemenata oba niza
    // definisi rezultujuci niz koji ce da sadrzi presek
    int *result = calloc(n, sizeof(int));
   
    // prodji kroz elemente veceg niza (npr. niz A)
    j = 0;
    for (i = 0; i < n; ++i) {
        // za svaki element niza A proveri da li se nalazu u B
        if (inArray(b, m, a[i])) {
            // ako se nalazi, proveri da li se nalazi u rezultujucem nizu
            // ovo nam treba da se neki od elemenata ne bi ponavljao
            if (!inArray(result, n, a[i])) {
                // ako se NE nalazi u rezultujucem nizu, ubaci u rezultujuci niz
                result[j++] = a[i];
            }
        }
    }
   
    // stampaj rezultujuci niz
    return 0;
}


Kod nisam proveravao, jer pisem napamet ali to bi mogla da ti bude ideja. Nadam se da sam bio od pomoci :)

Hm... To nije ideja to je kod ;D
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Marko Аcović 11.05.2011, 21:56
Dobro, necemo sad u detalje  :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: MilosM 11.05.2011, 22:22
evo moje ideje...

#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[]){
int n1,n2,n3,i,j;
double *s1, *s2, *s3;

printf("Unesi broj elemenata skupova: ");
scanf("%d%d",&n1,&n2);

s1=(double *)malloc(n1*sizeof(double));

printf("Elementi prvog skupa su: ");
for(i=0;i<n1;scanf("%lf",&s1[i++]));
if (n1==0) putchar('\n');

s2=(double *)malloc(n2*sizeof(double));

printf("Elementi drugog skupa: ");
for(i=0;i<n2;scanf("%lf",&s2[i++]));
if (n2==0) putchar('\n');
if(n1>n2)
s3=(double *)malloc((n1)*sizeof(double));

for(n3=0;n3<n1;n3++);
for(j=0;j<n2;j++){
for(i=0;i<n1;i++)
if(s2[j]==s1[i]) break;
s3[n3++]=s2[j];
}
s3=(double *)realloc(s3,n3*sizeof(double));
else
s3=(double *)malloc((n2)*sizeof(double));
for(n3=0;n3<n1;n3++);
for(j=0;j<n2;j++){
for(i=0;i<n1;i++)
if(s2[j]==s1[i]) break;
s3[n3++]=s2[j];
}
s3=(double *)realloc(s3,n3*sizeof(double));

printf("Presek pocetnih skupova: ");
for(i=0;i<n3;i++)
printf("%lf ",s3[i]);
free(s1);
free(s2);
free(s3);
    return 0;
}

nisam siguran dal moze...
Naslov: Odg: Domaci iz programskih jezika
Poruka od: MilosM 11.05.2011, 22:26
greska u drugoj for petlji n3 ide do n2... n3<n2
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Marko Аcović 11.05.2011, 22:32
Nisam proveravao funkcionalnost ali cim ti se ponavlja kod, znaci da ti dizajn nije dobar. Krsis DRY (Don't Repeat Yourself) princip. Zato su i izmisljene funkcije kako bi kod koji se ponavlja izmestio u njih.
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Zepi 12.05.2011, 11:30
Kod ima gresaka i logickih i sintaksickih.

Sto se tice ponavljanja koda to u ovom slucaju nije bila poenta a normalno da se funckije pisu gde god je potrebno(unos dva niza dobar primer :) )

prvo:
Citat

for(n3=0;n3<n1;n3++);

ne radi nista tj isto kao i n3 = n1;

drugo ovo je presek skupa a ne unija pa ni provera koja je dimenzija veca nije potrebna pa samim tim ni else deo koda.

Da bi ovo stvarno bila dobra vezba, valjalo bi ovo resiti pokazivacima i dinamckom alokacijom memorije pomocu funkcija, ciji deklaracija bi trebala da izgleda ovako:


#include<stdio.h>
#include<stdlib.h>

void unos(double* a, int n){

}

void ispis(double* a, int n){

}

void presek(double* s1, int n1, double* s2, int n2, double* s3, int *n3){

}

int main(int argc, char *argv[]){
int n1,n2,n3;
double *s1, *s2, *s3;

printf("Unesi broj elemenata skupova: ");
scanf("%d%d",&n1,&n2);

s1=(double *)malloc(n1*sizeof(double));

unos(s1, n1);

s2=(double *)malloc(n2*sizeof(double));

unos(s2, n2);

ispis(s1, n1);
ispis(s2, n2);

        s3=(double *)malloc((n1)*sizeof(double));

presek(s1, n1, s2, n2, s3, &n3);

s3=(double *)realloc(s3,n3*sizeof(double));

printf("\n\nPRESEK\n");
ispis(s3, n3);

free(s1);
free(s2);
free(s3);
    return 0;
}


Popunite tela funkcija tj definisite sta treba da rade a da rese ovu problematiku.
Napomena: raditi sve preko pokazivaca tj. da u kodu nema nigde simbola za niz [].

JOS JEDNA:
obratiti paznju na sledeca dva skupa:
n1 = 2, 2, 3, 4
n2 = 3, 3, 2, 5

resenje treba da bude:
n3 = 2, 3

Citat
ipak je programiranje test inteligencije...   

POZDRAV 
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Marko Аcović 12.05.2011, 11:41
Ako ste vec tematski presli funkcije, ja bih insistirao na koriscenju istih (pokazivaci i nisu bitni za ovaj konkretan primer. Sve moze da se uradi i sa statickim nizovima). Veoma je bitno da se studenti od samog pocetka nauce da pisu efikasan i pregledan kod. Sutra kad se zaposle, nadredjeni nece biti ni malo popustljivi ako vide da su im programeri 'aljkavi'. :)
Naslov: Odg: Domaci iz programskih jezika
Poruka od: pesovic 12.05.2011, 12:59
Samo jedna ispravka u delkaraciji programa koju je preporucio Zepi

Sledecom linijom se alocira prostor za presecni niz s3 koji je jednak dimenziji prvog niza

s3=(double *)malloc((n1)*sizeof(double));

mozda je pre toga bolje ispitati koji je niz kraci pa za niz s3 alocirati manje prostora:


if (n1<n2)
    s3=(double *)malloc((n1)*sizeof(double));
else
     s3=(double *)malloc((n2)*sizeof(double));


Mozda ovo i nema nekog preteranog smisla posto se nakon nalazenja preseka vrsi realokacija niza, ali opet je prakticnije alocirati onoliko prostora koliko ce nam najverovatnije trebati.

Pozdrav
Uros
Naslov: Odg: Domaci iz programskih jezika
Poruka od: Zepi 12.05.2011, 13:02
Nije lose zapazanje, ali razlika i nije velika posto se u svakom slucaju radi relloc posle funkcije presek :)