[C] Tablica struktur i sortowanie przez proste wybieranie

Witam…jestem początkującym programistą i prosze o pomoc. Piszę program, który ma posortować tablicę struktur

Tablica ma być sortowana względem rodz. Udało mi sie posortować już nr i rodz, ale w żaden sposób nie potrafię przesortować naz i imi :evil: . Wiem ze istnieje funkcja qsort, ale nie mogę jej użyć. Koniecznie musi być przez proste sortowanie.

A oto pętla którą zastosowałem na posortowanie rodz i nr.

Jesli twoj algorytm dziala, to prosta zmiana ifa wystarczy:

if ( strcmp(tab[j].imi, tab[min].imi) > 0)

if ( strcmp(tab[j].naz, tab[min].naz) > 0)

(musisz miec wlączony nagłówek string.h)

(najlepiej by bylo, gdybys do kazdego porównania zrobił oddzielną funkcję przyjmującą jako parametry twoje struktury i zwracającą TRUE lub FALSE. - wtedy zmieniałbyś w ifie tylko nazwę funkcji).

EDIT:

ale to:

a=tab[min].rodz;

tab[min].rodz=tab_.rodz;_

tab_.rodz=a;_

to ma sortowac tylko jedną kolumne, a nie rekordy?!

znaczy się, to co ja napisałem to właśnie sortuje tylko jedna kolumnę z parametrami rodz, bo nic innego nie udało mi się wykombinować, jeżeli byłby sposób żeby sortować całe wiersze to bardzo chętnie go poznam :smiley:

niestety nie mam pomysłu jak to zrobić :?

a tak próbowałeś:

a=tab[min];

tab[min]=tab_;_

tab_=a;_

?

Tylko a musi być zadeklarowane jako:

struct dane a;

bez kitu, najprostszy sposób zawsze najlepszy :smiley: dzięki ogromne siedziałem nad tym uhuhuu i jeszcze trochę…nie wiem czy się na tym forum da ale jak tak to wystawię Ci pozytywa i to wielkiego :smiley:

mam jeszcze jedno pytanie…bo ja już to posortuje wegług rodz a w ramach tego jeszcze według naz tzn. jak rodz są takie same to naz alfabetycznie, to jak coś takiego zrobić…

Zrob sobie funkcje

//zwraca TRUE jeśli pierwszy element jest "wiekszy" od drugiego

//(jesli sortuje odwrotnie to znaczy, ze pomylilem znaki nierówności

porownaj(struct dane* a, struct dane* b){

    if(a->rodz > b->rodz) return TRUE;

    if(a->rodz < b->rodz) return FALSE;

    return ( strcmp( a->naz, b->naz ) > 1 ? TRUE : FALSE );

}

i w tym ifie co wcześniej mówiłem wywołaj:

if( porownaj(&tab[j], &tab[min]) )

Najlatwiej wlasnie w ten sposob - jak chcesz zmienic sposob sortowania to zmieniasz tylko funkcje porównującą elementy, a reszta sama działa.

wpisałem tę funkcje którą mi podałeś i kompilator krzyczy ze true i false nie sa zadeklarowane…nie bardzo wiem jak je zadeklarować, czy w globalnym czy raczej w funkcji i jak, czy bool czy int…

poza tym w tym programie trzeba wprowadzać dane, już się tym zagadnieniem zająłem, ale wprowadzanie danych ma zakończyć znak spacji w naz, probowałem użyć funkcji getch() i gets() ale coś nie bardzo mi to wychodzi…

to już by była ostatnia prośba i postaram się już Ciebie nie niepokoić… :slight_smile:

ja zawsze deklaruje globalnie:

#define TRUE 1;

#define FALSE 0;

To jest chyba w jakimś nagłówku, ale nie pamiętam w którym.

Co do wprowadzania danych to niestety nie pomogę - nigdy nie potrafiłem tego zrobić, ale poszukaj na forum, bo gdzieś były podobne tematy.

niestety ta funkcja sie wysypuje w ostatniej linijce, prawdopodobnie literówka jeżeli spojrzeć na to co kompilator wypisuję, ale odnaleźć nie mogę…

Nie napisałem co funkcja zwraca (nie pamietam czy to jest obligatoryjne, ale nie zaszkodzi sprawdzic:

int porownaj(struct dane* a, struct dane* b);

Właczyłes string.h?

#include

Więcej problemów nie widzę.

oto teoretyczne błędy, których odnaleźć nie mogę

Przy strcmp musi być > 0 a nie > 1 tak jak napisałem. Co do błędów - sprawdź czy gdzieś nawiasów nie brakuje. Tu masz całe źródło, które użyłem do sprawdzenia - kompilowałem gcc - bez błędów i asercje też się wykonują prawidłowo. Jakiego kompilatora używasz? Możesz też wkleić swoje źródło, jeśli nie znajdziesz błędu.

#include 

#include 


#define TRUE 1

#define FALSE 0


struct dane {

	char naz[2];

	char imi[2];

	int nr;

	int rodz;

}; 


int porownaj(struct dane* a, struct dane* b){

	if(a->rodz > b->rodz) return TRUE;

	if(a->rodz < b->rodz) return FALSE;

	return ( strcmp( a->naz, b->naz ) > 0 ? TRUE : FALSE );

}


int main(void){

	struct dane a;

	struct dane b;


	a.rodz = 0;

	a.naz[0] = 'a';

	a.naz[1] = '\0';


	b.rodz = 0;

	b.naz[0] = 'b';

	b.naz[1] = '\0';


	assert(porownaj(&b, &a) == TRUE);

	assert(porownaj(&a, &b) == FALSE);


	return 0;

}

rzeczywiście funkcja jest dobra, mój błąd przy deklaracji powodował te błędy kompilatora…już myślałem, że skończyłem ten program, a tu kolejny problem. Nie wiem jak zrobić funkcję która by zliczała ile razy razy wystąpił w tabeli taki sam wpis, czyli np. ile razy zmienna tab_.rodz = 3…także po raz kolejny proszę o pomoc_

Złączono Posta : 18.11.2007 (Nie) 19:13

juz mi sie udalo takze pytanie do usuniecia…sorry

Niby dlaczego? Póki wisi na forum jest cień szansy, że ktoś z podobnym lub identycznym problemem poszuka (i znajdzie) zamiast z miejsca pytać.

tylko ostatnie pytanie, a nie cały post, ale nie ważne…

niestety wystąpił kolejny problem… okazało sie ze program ktory pisze ma także mieć możliwość usuwania danych wpisów, nie pojedynczych danych, a całych wierszy danych czyli

tab_.naz tab .imi tab.nr tab__.rodz_

cały taki wiersz i nie wiem jak to zrobić pętle która będzie przypisywać wartości którą trzeba zmienić wartość z indeksem o 1 większa czyli i+1

bardzo proszę o szybka pomoc bo najpóźniej do jutra wieczorem muszę to mieć zrobione tj. do wtorku :?

Jak rozumiem nie robisz dynamicznego przydzielania pamieci? (malloc / free)

Jeśli tak, to po prostu przepisz dane z komórki nastepnej do poprzedniej. (Nie wiem jak porownujesz elementy zeby znalezc ten do skasowania). Ja bym zrobił tak:

int i,j;

for(i = 0, j = 0; i < sizeTablicy; i++, j++){

    if(i != j) tab[j] = tab[i];

    if(tu warunek kasowania){

        //tu wykasuj wpis (zamaz go)

        j--;

    }

}

Opis:

Masz dwie zmienne i i j. Za ich pomocą masz dostęp do tablicy. W pierwszej instrukcji sprawdzasz czy i == j. Jesli tak, to nic nie robisz. Jak znajdziesz element do skasowania, to zmniejszasz j–. W następnej iteracji j bedzie wskazywac na element skasowany, a i na element nastepny. Poniewaz i != j, to przepisze komorke nastepna do poprzedniej. I tak do konca tablicy poleci. Na oko będzie tez działać przy usuwaniu kilku elementow. Wazne, zebyś zamazywał wartość przy kasowaniu, bo jeśli np do skasowania bedzie ostatnie pare elementów, to wtedy nie będzie miał czego przepisywać z następnych komórek.

właśnie największy problem mam z tym zamazaniem danych…nie wiem jak to zrobic…probowalem

tab_.naz=0 tab__.imi=0…itd._

…=NULL;

probowałem zastępować tab_.naz = tab[i+1].naz …itd._

no i nie za bardzo chce to dzialac…

poza tym czy Twoja funkcja zostawia wolne miejsca w tabeli czy od razu przesuwa na wolne miejsca inne wpisy?? bo nie mogę do tego zbytnio dojść, a to dosyc ważne przy późniejszym sortowaniu…

warunkiem usunięcia jest to ze użytkownik wprowadza nr wpisu który powinien zostać usunięty… podana przez uzytkownika zmienna zauzmy y, wiec ten warunek powinien wygladac if(y=i) czy if(y=j)…

nasuwa mi sie jeszcze pytanie czy zmienne i i j to te same ktore moga byc potem uzyte podczas sortowania czy lepiej jest by byly to jakies zmienne inne badz lokalne…

jak chcesz skasować łańcuch znaków to w jego pierwszym znaku wpiszu ‘\0’. Np tab_.naz[0] = ‘\0’. Tak, moja funkcja od razu czyści puste miejsca przesuwając na nie następne wpisy. Ja bym zrobił oddzielną funkcje sortującą i usuwającą - wtedy nie bardzo jest możliwość ponownego użycia ‘i’ i ‘j’._

Witam, mam problem z kodem i nie wiem za bardzo gdzie jest błąd w funkcji żeby mi skompilowało

#include 

using namespace std;


int main()

{

struct element

{

int a;

int b;

};    


int a,N,i,s=0,x=0,m=0; 

cin>>N;


int t[N];


for(i=0;i

i=0;

while(x
{

cin>>a;

if(a==0){s=0;s=t[i];x++;}

else

{

s+=a;

for(m=0;m<100;m++){cin>>a;if(a!=0)s+=a;else break;}


t[i]=s;x++;s=0;

}


i++;

}


element blok[N-1];


for(i=0;i
{

blok[i].a=t[i];

blok[i].b=i;               

}


bool porownaj(element x,element y)

{

if(x.a>y.a)return 0;

else return 1;

}


sort(blok,blok+N-1,porownaj);


for(i=0;i

getchar();

};

Błędy:

44 a function-definition is not allowed here before ‘{’ token

44 expected ,' or;’ before ‘{’ token

49 porownaj’ undeclared (first use this function)

(Each undeclared identifier is reported only once for each function it appears in.)

lordor wywal deklaracje structa i funkcje porownaj przed main. Wtedy sie skompiluje ale nie wiem czy działa bo o poranku nie mam sił przebijać się przez ten [ironia] pięknie napisany i łatwy do zdebugowania kod[/ironia].