Sortowanie tablicy wskaźników na struktury

Awatar użytkownika
Harry Xin
Użytkownik
Użytkownik
Posty: 545
Rejestracja: 9 sie 2007, o 19:15
Płeć: Mężczyzna
Podziękował: 148 razy
Pomógł: 83 razy

Sortowanie tablicy wskaźników na struktury

Post autor: Harry Xin »

Zdefiniować N - elementową tablicę wskaźników na stuktury typu stuct tosoba {char naz[20]; unsigned rok, mies, dzien; long id}, gdzie N jest stałą w programie. Zdefiniować zmienną unsigned ile=0, która ma służyć do przechowywania liczby wskaźników wsprowadzonych do tablicy. Opracować następujące funkcje:
a) tworzącą zmienną dynamiczną typu tosoba oraz inicjującą zmienną losowymi wartościami..

[...]

e) sortującą elementy tablicy wskaźników w taki sposób, aby wskazywane stuktury tworzyły ciąg uporządkowany według nazwisk (należy zamieniać wskaźniki bez modyfikacji położenia stuktur w pamięci); wykorzystać funkcję qsort

Kod: Zaznacz cały

//w pliku nagłówkowym

//...

 struct tosoba
  {
   char naz[20];
   unsigned rok,mies,dzien;
   long id;
  };

 const int N=4;
 tosoba *t[N];
 unsigned ile=0;

 void funkcja1(void)
 void sortuj(void);

//...

//w I pliku do funkcji

 void funkcja1(void)
  {
   tosoba *a=new tosoba;

   t[ile]=a;

//...

   ile++;
  }

//w II pliku do funkcji

 void sortuj(void)
  {
   qsort(t,ile,sizeof(t[0]),por1);
  }

//w III pliku do funkcji

 int por1(const void *a, const void *b)
  {
   tosoba *x=(tosoba*)a,*y=(tosoba*)b;

   return strcmp(x->naz,y->naz);
  }

To oczywiście nie jest całe polecenie ani cały kod, ale nie chcę tu przerażać ogromną tekstu (jakby był potrzebny jeszcze jakiś fragment to oczywiście wkleję).

Szczerze mówiąc nie wiem co się w danej chwili sortuje. ;/
Pewnie błąd tkwi w funkcji por1, ale nie wiem jak to zrobić. Proszę o pomoc.
matshadow
Użytkownik
Użytkownik
Posty: 941
Rejestracja: 17 gru 2007, o 21:48
Płeć: Mężczyzna
Lokalizacja: Kingdom Hearts
Podziękował: 6 razy
Pomógł: 222 razy

Sortowanie tablicy wskaźników na struktury

Post autor: matshadow »

... qsort.html
Przerób kod stamtąd
Awatar użytkownika
Harry Xin
Użytkownik
Użytkownik
Posty: 545
Rejestracja: 9 sie 2007, o 19:15
Płeć: Mężczyzna
Podziękował: 148 razy
Pomógł: 83 razy

Sortowanie tablicy wskaźników na struktury

Post autor: Harry Xin »

Patrzyłem na tamten opis niejednokrotnie. Niestety dotyczy on sytuacji sortowania jednowymiarowej tablicy liczb (chyba najprostszy przykład). A tutaj mam posortować tablicę wskaźników na dynamicznie utworzone stuktury, pod względem łańcuchów będących składowymi tych stuktur. ;/
adek05
Użytkownik
Użytkownik
Posty: 450
Rejestracja: 3 kwie 2007, o 18:38
Płeć: Mężczyzna
Lokalizacja: Biała Podlaska
Podziękował: 12 razy
Pomógł: 68 razy

Sortowanie tablicy wskaźników na struktury

Post autor: adek05 »

Sortowanie jak każde jedno, zmieniasz tylko funkcję porównującą. Ustawisz w tym konkretnym przypadku na porównanie ciągów nazwisk.
Awatar użytkownika
Harry Xin
Użytkownik
Użytkownik
Posty: 545
Rejestracja: 9 sie 2007, o 19:15
Płeć: Mężczyzna
Podziękował: 148 razy
Pomógł: 83 razy

Sortowanie tablicy wskaźników na struktury

Post autor: Harry Xin »

Kod: Zaznacz cały

 int por1(const void *a, const void *b) 
  { 
   tosoba *x=(tosoba*)a,*y=(tosoba*)b; 

   return strcmp(x->naz,y->naz); 
  } 
W takim razie co w powyższej funkcji jest nie tak?
matshadow
Użytkownik
Użytkownik
Posty: 941
Rejestracja: 17 gru 2007, o 21:48
Płeć: Mężczyzna
Lokalizacja: Kingdom Hearts
Podziękował: 6 razy
Pomógł: 222 razy

Sortowanie tablicy wskaźników na struktury

Post autor: matshadow »

a spróbuj sam napisać to strcmp, może coś w tej funkcji nie jest ok
Awatar użytkownika
Harry Xin
Użytkownik
Użytkownik
Posty: 545
Rejestracja: 9 sie 2007, o 19:15
Płeć: Mężczyzna
Podziękował: 148 razy
Pomógł: 83 razy

Sortowanie tablicy wskaźników na struktury

Post autor: Harry Xin »

Kod: Zaznacz cały

 int por1(const void *a, const void *b)
  {
   tosoba *x=(tosoba*)a,*y=(tosoba*)b;
   int i=0,j=0;
   char p,q;

   while(i<20)
    {
     p=(char)x->naz[i];
     q=(char)y->naz[j];
     if(p<q) return -1;
     else if(p>q) return 1;
     else
      {
       i++;
       j++;
      }
    }

   return 0;
  }
Niby się kompiluje ale wydruki przed i po sortowaniu kolejnych stuktur są identyczne. Sortuję w ten sposób struktury a nie wskaźniki do nich pewnie. ;/
Może źle napisałem wywołanie quicksorta?

Kod: Zaznacz cały

   qsort(t,ile,sizeof(tosoba),por1);
matshadow
Użytkownik
Użytkownik
Posty: 941
Rejestracja: 17 gru 2007, o 21:48
Płeć: Mężczyzna
Lokalizacja: Kingdom Hearts
Podziękował: 6 razy
Pomógł: 222 razy

Sortowanie tablicy wskaźników na struktury

Post autor: matshadow »

wskaźników dopiero się zacznę uczyć, więc póki co nie pomogę. A na kiedy potrzebujesz?
Awatar użytkownika
Harry Xin
Użytkownik
Użytkownik
Posty: 545
Rejestracja: 9 sie 2007, o 19:15
Płeć: Mężczyzna
Podziękował: 148 razy
Pomógł: 83 razy

Sortowanie tablicy wskaźników na struktury

Post autor: Harry Xin »

W sumie to okazało się, że nie zdążymy przeprowadzić tego laboratorium bo zajęcia przepadły - co nie oznacza, iż nie obowiązuje nas to na kolejnym semestrze. W czwartek spytam wykładowcę.
Awatar użytkownika
wafello
Użytkownik
Użytkownik
Posty: 35
Rejestracja: 7 sty 2009, o 21:50
Płeć: Mężczyzna
Lokalizacja: Józefina
Pomógł: 6 razy

Sortowanie tablicy wskaźników na struktury

Post autor: wafello »

zamiast qsort użyj sort

void sort(RandomAccessIterator first, RandomAccessIterator last,
StrictWeakOrdering comp);
np : sort(t,t+ile,por1);

i nie używaj void tylko bezpośrednio wskaźników na tosoba:
int por1(const tosoba *a, const tosoba *b)
Awatar użytkownika
Harry Xin
Użytkownik
Użytkownik
Posty: 545
Rejestracja: 9 sie 2007, o 19:15
Płeć: Mężczyzna
Podziękował: 148 razy
Pomógł: 83 razy

Sortowanie tablicy wskaźników na struktury

Post autor: Harry Xin »

W poleceniu pisze, że mam użyć funkcji qsort.
Awatar użytkownika
wafello
Użytkownik
Użytkownik
Posty: 35
Rejestracja: 7 sty 2009, o 21:50
Płeć: Mężczyzna
Lokalizacja: Józefina
Pomógł: 6 razy

Sortowanie tablicy wskaźników na struktury

Post autor: wafello »

możesz jeszcze podać deklaracje struktury tosoba?

EDIT:

to powinno pomoc:

Kod: Zaznacz cały

 /* qsort example upgrade by wafello */
#include <stdio.h>
#include <stdlib.h>

int values[] = { 40, 10, 100, 90, 20, 25 };
int* ws[6];


int compare (const void * a, const void * b)
{
  return ( *(*(int**)a) - *(*(int**)b) );
}

int main ()
{
  int n;

  for (n=0; n<6; n++)
    ws[n] = &values[n];
  
  qsort (ws, 6, sizeof(int), compare);

  for (n=0; n<6; n++)
     printf ("%d %d
",values[n],*ws[n]);
  return 0;
}
u nie mam wydruk z działania programu:

Kod: Zaznacz cały

40 10
10 20
100 25
90 40
20 90
25 100
Co pokazuje że pierwsza tablica została nienaruszona a tablica wskazników posortowana - przyjrzyj się funkcji compare - szczególnie patrz na rzutowania na wskaźniki i wyłuskiwana wartości (gwiazdki)
Awatar użytkownika
Harry Xin
Użytkownik
Użytkownik
Posty: 545
Rejestracja: 9 sie 2007, o 19:15
Płeć: Mężczyzna
Podziękował: 148 razy
Pomógł: 83 razy

Sortowanie tablicy wskaźników na struktury

Post autor: Harry Xin »

Hmmm... A w przypadku wskaźnika do łańcucha będącego składową zdefiniowanej stuktury tosoba to na co mam zrzutować?
Szkoda, że użyłeś w tym przykładzie typu integer bo mało widać co tu się dzieje, skoro wskaźniki i tak zawsze zajmują 4 bajty.
Awatar użytkownika
wafello
Użytkownik
Użytkownik
Posty: 35
Rejestracja: 7 sty 2009, o 21:50
Płeć: Mężczyzna
Lokalizacja: Józefina
Pomógł: 6 razy

Sortowanie tablicy wskaźników na struktury

Post autor: wafello »

Mam nadzieję że to rozwieje już wszelkie wątpliwości:

Kod: Zaznacz cały

 /* qsort example upgrade by wafello */
#include <stdio.h>
#include <stdlib.h>

class T
{
  public:
    char a[20];
    int p;
};

T values[6];
T* ws[6];



int compare (const void * a, const void * b)
{
  return ( ((*(T**)a))->p > ((*(T**)b))->p );
}

int main ()
{
  int n;
  
  for (n=0; n<6; n++)
    {
      values[n] = 20-n;
      ws[n] = &values[n];
    }

  qsort (ws, 6, sizeof(T*), compare);

  for (n=0; n<6; n++)
     printf ("%d %d
",values[n].p,(*ws[n]).p);
  return 0;
}
ODPOWIEDZ