![]() |
![]() |
|
Programiranje Programski jezici, tehnike, alatke... |
![]() |
|
Alatke vezane za temu | Vrste prikaza |
![]() |
#1 |
Član
Član od: 4.11.2005.
Poruke: 285
Zahvalnice: 15
Zahvaljeno 7 puta na 6 poruka
|
![]()
Pozdrav!
Treba da ispisem mali programcic u C-u koji radi sledece: ucitava niz, a zatim trazi duzinu najduzeg podniza koji se sastoji od nula i ispisuje pocetnu i krajnju poziciju tog podniza. Npr, niz je 1 2 0 0 3 0 4 0 0 0 0 8 dakle, duzina najduzeg podniza 0 jeste 4, a pocetna i krajnja pozicija su 8 i 11. Ovde imam delic koda Kod:
duz = 0; d = 0; for(j=1;j<db;j++) { if (b[j-1]==0) {d++; kraj=j; if(d>duz)duz=d;} else if(b[j]!=0)d=0; } petlja for prolazi kroz niz, ako je tekuci element jednak nuli, duzina niza se uvecava za 1, a promenljiva kraj oznacava da je taj element poslednji. Ako je tekuca duzina veca od duzine, duzina dobija vr tekuce duzine. Zatim se proverava da li je naredni element razlicit od nule. Ako jeste, dolazimo do toga da tekucu duzinu resetujemo na nulu. Ovo je kostur, za koji sam svestan da ne radi... Medjutim, kako sam pocetnik, i vec sat i po se mlatim sa ovim, trenutno nisam u stanju da smislim logicne ispravke za kod, te bih molio za pomoc. |
![]() |
![]() |
![]() |
#2 |
Starosedelac
|
![]() Kod:
// b = niz int pocetak = 0, kraj = 0, duzina = 0, tmp_pocetak = 0, tmp_kraj = 0, tmp_duzina = 0; for (int i = 0; i < db; i++) { if (b[i] == 0) { if (tmp_duzina++ == 0) tmp_pocetak = i; tmp_kraj = i; } else { if (tmp_duzina > duzina) { pocetak = tmp_pocetak; kraj = tmp_kraj; } tmp_duzina = 0; } } ![]() Ideja je da čuvaš najveće vrednosti u pocetak, kraj i duzina, i imaš neke pomoćne promenljive koje ćeš da koristiš pri prolasku kroz niz. for petlja kaže sledeće: Kod:
ukoliko je trenutni član jednak nuli: ukoliko je pomoćna dužina jednaka nuli, znači da je to početak niza nula pa postavljam tmp_pocetak na trenutan broj uvećam dužinu za 1 postavim kraj na trenutan broj ukoliko nije, ovo je kraj niza ili uopšte nije bio niz: ako je dužina niza kog sam trenutno izbrojao veća od dužine nekog prethodnog niza: postavi pravi početak na moj pomoćni početak postavi pravi kraj na moj pomoćni kraj postavi pomoćnu dužinu na 0 |
![]() |
![]() |
Sledeći korisnik se zahvaljuje korisniku EclipsE na korisnoj poruci: | ||
absonic (31.3.2012) |
![]() |
#3 |
Član
Član od: 16.4.2010.
Lokacija: Pančevo
Poruke: 462
Zahvalnice: 41
Zahvaljeno 68 puta na 63 poruka
|
![]()
Ne treba ti toliko promenjivih jer možeš i sa manje da uradiš istu stvar.
Samo sam malo izmenio tvoj kod i već lepše izgleda ![]() Kod:
int kraj = 0, duzina = 0, tmp_duzina = 0; for (int i = 0; i < db; i++) { if (b[i] == 0) { tmp_duzina++; } else { if (tmp_duzina > duzina) { duzina = tmp_duzina; kraj = i; } tmp_duzina = 0; } } ![]() |
![]() |
![]() |
![]() |
#4 |
Član
Član od: 4.11.2005.
Poruke: 285
Zahvalnice: 15
Zahvaljeno 7 puta na 6 poruka
|
![]()
Veliko hvala, ljudi!
Ako jos negde zapnem, pitam ovde ![]() EDIT: Todos, sada sam isprobao ovaj kod, i javlja se mali problem. Kada je niz nula na kraju, tipa 1 2 3 0 0 2 0 0 0 0, program ga ne konstatuje, tj izbacuje da je najduzi niz nula duzine 2? EDIT 2: uspeo sam da resim problem tako sto sam izmenio sledeci deo Kod:
for (int i = 0; i <= db; i++) Poslednja ispravka: absonic (31.3.2012 u 17:39) |
![]() |
![]() |
![]() |
#5 |
Starosedelac
Član od: 8.4.2006.
Lokacija: Beograd
Poruke: 2.568
Zahvalnice: 888
Zahvaljeno 578 puta na 358 poruka
|
![]()
Sa tom promenom operatora u uslovu for petlje (< ba <=) pristupas i 12 elementu niza (probijas index), a ako kojim slucajem je to null terminator '\0' onda se i to racuna ako nije takav niz mozes da dobijes neku gresku u toku izvrsenja a i nemoras.
Mozda najsigurnije resenje je da dodas posle bloka for petlje Kod:
if(tmp_duzina > duzina) duzina = tmp_duzina |
![]() |
![]() |
![]() |
#6 |
Član
Član od: 4.11.2005.
Poruke: 285
Zahvalnice: 15
Zahvaljeno 7 puta na 6 poruka
|
![]()
Dada, sigurnija varijanta.
Sad, još jedno pitanje: imam niz 1 2 3 4 5 6 7 8 9 10 pošto jezik c indeksee elemenata niza računa od 0, broj 4 bi mi bio na poziciji 3 ili 4? |
![]() |
![]() |
![]() |
#7 |
Starosedelac
|
![]() Kod:
niz: 1 2 3 4 5 6 7 8 9 10 poz: 0 1 2 3 4 5 6 7 8 9 |
![]() |
![]() |
![]() |
#8 |
Član
Član od: 16.4.2010.
Lokacija: Pančevo
Poruke: 462
Zahvalnice: 41
Zahvaljeno 68 puta na 63 poruka
|
![]()
Pa i sam si rekao, broj 3
![]() Heh nisam video da je eclipse već odgovorio. Btw. Todos na španskom znači sve, a ja sam ipak Todors ![]() Poslednja ispravka: Todors (31.3.2012 u 19:19) Razlog: Brži je bio eclipse |
![]() |
![]() |
Sledeći korisnik se zahvaljuje korisniku Todors na korisnoj poruci: | ||
absonic (31.3.2012) |
![]() |
#9 |
Član
Član od: 4.11.2005.
Poruke: 285
Zahvalnice: 15
Zahvaljeno 7 puta na 6 poruka
|
![]()
Oprosti, Todors, nenamerna greška
![]() Uglavnom, igrao sam se malo i modifikovao kod Kod:
for (j = 0; j < db; j++) // pronalazenje najduzeg niza nula u nizu b. { if (b[j] == 0) { d++; } if((d > duz) && (b[j] == 0)){duz = d; kraj=j;} else { if (d > duz) { duz = d; } d = 0; } } Kod:
if((d > duz) && (b[j] == 0)){duz = d; kraj=j;} Sta sam sada zeznuo ![]() |
![]() |
![]() |
![]() |
#10 |
Starosedelac
Član od: 8.4.2006.
Lokacija: Beograd
Poruke: 2.568
Zahvalnice: 888
Zahvaljeno 578 puta na 358 poruka
|
![]()
Sa me mrzi da mnogo razmisljam idem da pijem, sutra cemo.
Ali usput mi je palo jedno "pokvareno" resenje ![]() Samo promenis for petlju. |
![]() |
![]() |
![]() |
#11 |
Član
Član od: 4.11.2005.
Poruke: 285
Zahvalnice: 15
Zahvaljeno 7 puta na 6 poruka
|
![]()
Snasao sam se, ovo radi posao, za sada sam ovo probao jedno 20x za razne primere i radi posao
Kod:
for (j = 0; j < db; j++) // pronalazenje najduzeg niza nula u nizu b. { if (b[j] == 0) { d++;; if(d > duz){duz=d;kraj=j;} } else { d = 0; } } |
![]() |
![]() |
![]() |
#12 |
Član
Član od: 4.11.2005.
Poruke: 285
Zahvalnice: 15
Zahvaljeno 7 puta na 6 poruka
|
![]()
Evo mene opet
![]() Zanima me sledece: treba da unesem string, ciju duzinu ne znam unapred. Memorija treba da se alocira dinamicki. ja sam to uradio na sledeci nacin: dodelio sam jedan bajt memorije (za znak '\0'), a zatim svaki put kada ucitam novi karakter sa getchar() (dok god je getchar()!='\n') uvecam brojac duzine za jedan i alociram (d+1)*sizeof(char) preko realloc. Medjutim, uvek mi izbacuje duzi string nego sto to zapravo jeste. Npr unesem test, kad stavim printf("%s", string), izbaci test=2222 itd. Ako neko moze da pogleda kod, i pomogne da pronadjem gde je greska Kod:
void main() { char *niz; char c; int d=1,i=0; niz=(char*)malloc(sizeof(char)); while ( (c=getchar()) != '\n') { d++; niz = (char*)realloc (niz, d); niz[i]=c; i++; } |
![]() |
![]() |
![]() |
#13 |
Starosedelac
|
![]()
Prebrises '\0' i onda nemas null terminated string (tacnije nikad ga i ne dodelis xd).
Kod:
void main() { char *niz; char c; int d = 1; niz=(char*)malloc(sizeof(char)); while ( (c=getchar()) != '\n') { niz = (char*)realloc(niz, ++d); niz[d - 2] = c; } niz[d - 1] = '\0'; } |
![]() |
![]() |
![]() |
#14 |
Član
Član od: 4.11.2005.
Poruke: 285
Zahvalnice: 15
Zahvaljeno 7 puta na 6 poruka
|
![]()
'De je onaj smajli sto se mlati u glavu
![]() Hvala ![]() |
![]() |
![]() |
![]() |
#15 |
V.I.P. GNU/Linux
Član od: 1.11.2005.
Poruke: 10.989
Zahvalnice: 1.965
Zahvaljeno 4.818 puta na 2.777 poruka
|
![]()
Takođe izbegavaj to realociranje za po jedan bajt više, nije dobro za performanse. Realociraj u koracima od npr 20, 50, 100 itd bajtova (tako što održavaš neki brojač u while petlji pa kad otkuca do određene cifre, tek onda realloc).
|
![]() |
![]() |
![]() |
#16 |
Veteran
Član od: 3.5.2008.
Lokacija: Beograd
Poruke: 760
Zahvalnice: 81
Zahvaljeno 213 puta na 144 poruka
|
![]()
A najlakše je koristiti funkciju koja ti čita ceo string sa ulaza.
fgets(char* buffer, int legth, FILE* stream); Kod:
//Alociraš memoriju, recimo 200 bajtova char* buffer = malloc(200) //i pozoveš fgets(buffer, 200, stdin); |
![]() |
![]() |
![]() |
#17 |
Član
Član od: 4.11.2005.
Poruke: 285
Zahvalnice: 15
Zahvaljeno 7 puta na 6 poruka
|
![]()
Imam jos jedno pitanje
Da li je moguce u string ubaciti vrednost neke promenljive. Recimo, n=5; string = "Ovo je n. mesec u godini", ali, naravno da umesto n stoji 5. Znam da ovo nece raditi, ali da li postoji neki nacin da se ovo izvede. (po mogucstvu bez upotrebe strcat)? |
![]() |
![]() |
![]() |
#19 |
Član
Član od: 4.11.2005.
Poruke: 285
Zahvalnice: 15
Zahvaljeno 7 puta na 6 poruka
|
![]()
Opet pitanje.
Imam jednu komandu Kod:
akcija=(char*)malloc(3*sizeof(char)); akcija=">="; Probao sam rucno da stavim znak za kraj kao a[2]='\0', ali ni to nije pomoglo? edit: trebalo je da stavim free(akcija) van while petlje u kojoj dodeljujem vrednost stringu) |
![]() |
![]() |
![]() |
#20 |
V.I.P. GNU/Linux
Član od: 1.11.2005.
Poruke: 10.989
Zahvalnice: 1.965
Zahvaljeno 4.818 puta na 2.777 poruka
|
![]()
Ne možeš raditi takvo dodeljivanje u čistom C-u, već u string upisuješ sa strcpy
#include <string.h> ... strcpy(akcija, ">="); A ti si uradio sledeće: napravio si pokazivač akcija koji si uperio na novoalocirani blok memorije (sa malloc), pa si onda taj pokazivač pomoću znaka jednakosti samo preusmerio na drugi blok memorije (ovo ">=") koji je privremeno stvoren kao literal negde na steku te funkcije, i onda si pokušao da uradiš free tog bloka (koji pripada zaštićenom steku) i zato je puklo. Onaj prvi blok ti je pritom ostao "izgubljen" (nemaš više ništa što pokazuje na njega i zato ne možeš da ga dealociraš osim ubijanjem procesa) čime si dobio curenje memorije. Znak jednakosti u C-u znači dodelu vrednosti samo za proste tipove, a char* je niz i u tom slučaju (kao i u slučaju bilo kojih drugih nizova) jednakost samo preusmerava pokazivač na neki blok memorije. |
![]() |
![]() |
Sledeći korisnik se zahvaljuje korisniku voodoo_ na korisnoj poruci: | ||
absonic (9.5.2012) |
![]() |
Bookmarks sajtovi |
Alatke vezane za temu | |
Vrste prikaza | |
|
|
![]() |
||||
tema | temu započeo | forum | Odgovora | Poslednja poruka |
Procena računara | alien | Šta da kupim? | 6897 | 7.5.2022 10:50 |
PASTE teksta, pomoc hitno potrebna | Kobilic | Kvarovi | 4 | 31.10.2011 15:48 |
Virus POMOC | Kobilic | otpaTci | 11 | 9.5.2011 19:21 |
Potrebna mi pomoc! | Snakebite | 2D radovi | 4 | 30.4.2009 1:08 |
Kako postici anonimnost kod koriscenja P2P programa | The Finest Serbian Since '82 | Internet tehnologije | 31 | 7.8.2007 1:35 |