Sortowanie tablicy struktury

0

Witajcie,

Potrzebuję waszej pomocy w rozwiązaniu pewnego zadania. Treść wraz z kodem, który napisałem znajduje się w środku:

#include <iostream>
#include <conio.h>

using namespace std;

struct Person
{
string name;
int birth;
};

Person out (Person ludzie[],int n)
{
    for(int i=0; i<n; i++)
    {
        cout << ludzie[i].name << " " << ludzie[i].birth << endl;
    }
}

Person in (Person ludzie[], int n)
{
    for(int i=0; i<n; i++)
    {
        cout << "Podaj imie !" << endl;
        cin >> ludzie[i].name;
        cout << "Podaj rok urodzenia!" << endl;
        cin >> ludzie[i].birth;
    }
}

Person sort (Person ludzie[], int n)
{
      for (int i=0; i<n; i++)
    {
        for (int j=0; j<n; j++)
        {
            if (ludzie[j].birth >ludzie[j+1].birth)
            swap(ludzie[j].birth, ludzie[j+1].birth);
        }        
    }
}

int main()
{
    int n;
    Person ludzie[n];
    cout << "Ile osob chcesz wczytac?" << endl;
    cin >> n;

    in(ludzie,n);
    sort(ludzie,n);
    out(ludzie,n);

    getch();
}

Co należałoby zrobić, aby nazwisko było sortowane razem z rokiem urodzenia oraz, aby w przypadku takich samych nazwisk sortowało rokiem?? Jak na razie próbowałem sortować samą tablicę, sortować nazwiskami i rokiem.

Nie oczekuję gotowego rozwiązania, a jedynie jakąś sugestię.

Dziękuję.

4
swap(ludzie[j].birth, ludzie[j+1].birth);

Swapuj ludzi, a nie ich lata urodzenia.

Poza tym: jeśli deklarujesz, że funkcja zwróci instancję obiektu typu Person, to musisz taką zwrócić, w przeciwnym wypadku masz UB.

0

Swapuj ludzi, a nie ich lata urodzenia.

Poza tym: jeśli deklarujesz, że funkcja zwróci instancję obiektu typu Person, to musisz taką zwrócić, w przeciwnym wypadku masz UB.

W zadaniu jest podane, aby najpierw posortowac ich wedlug lat urodzenia, ale pamietajac o tym, aby nazwiska pozostawaly obok roku urodzenia..

swap(ludzie[j].birth, ludzie[j+1].birth);

Czyli zamienic "birth" na "name" czy w ogole zostawic sama tablice? I co to jest UB?

2

Czyli zamienic "birth" na "name" czy w ogole zostawic sama tablice?

Pomyśl chwilę logicznie: czy jeśli będziesz podmieniał same imiona (podobnie jak teraz podmieniasz same daty urodzenia), nie będzie Ci czegoś w tej podmianie brakować? Na przykład... daty urodzenia?
Musisz swapować całe struktury.

I co to jest UB?

undefined behaviour - http://lmgtfy.com/?q=cpp+ub

0

Udalo mi sie posortowac strukture tak jak radziliscie i faktycznie wyswietla dane tak jak chcialbym.

struct ludzie
{  
  char nazwisko[25];
  int rok;
  
  bool operator < (const ludzie &x)const  
  {
    return rok<x.rok;						// Zachowanie sie operatora podczas swap
  }
 
};

ludzie in (ludzie tablica[], int n)
{
	for(int i=0;i<n;i++)
  {
    cout<<"Nazwisko: " << endl;
    cin >> tablica[i].nazwisko;
    cout<<"Rok urodzenia: " << endl;
    cin >> tablica[i].rok;
  }
}

ludzie sort(ludzie tablica[], int n)
{
	sort(tablica, tablica+n);
}

ludzie out(ludzie tablica[], int n)
{
  cout<<endl;
  cout<<"Po sortowaniu: "<<endl<<endl;
  
  for(int i=0;i<n;i++)
    cout<<"Nazwisko: "<<tablica[i].nazwisko << " Rok: " << tablica[i].rok << endl;
}
 
int main()
{  
  int n;
  cout<<"Ile osob chcesz wprowadzic?"<<endl;
  cin >> n;
  
    ludzie tablica[n]; 
	in(tablica, n);
	sort(tablica, n);
    out(tablica, n);
 
  
  system("pause");
  return 0;
}

Nalezaloby jeszcze dodac opcje sortowania alfabetycznego dla osob, ktore urodzily sie w tym samym roku. Czy powinienem utworzyc dodatkowa funkcje do tego czy gdzies dopisac linijke? Jakas podpowiedz jak to zrobic?

bool operator < (const ludzie &x)const  
  {
    return rok<x.rok;					
  }

Dodalem taka linijke w strukturze, a raczej pozyczylem z pewnej strony o strukturach i o dziwo zadzialalo. Czy jest to konieczne do dzialania funkcji sortowania? Po co to?

3
ludzie tablica[n]; 

To się nazywa VLA i nie istnieje jako-tako w C++ (tj. tworzenie tablicy dla n, które nie jest stałe) - wykorzystaj std::vector lub new int[n] (skądinąd anty-idiom w nowoczesnym C++ :P).

Nalezaloby jeszcze dodac opcje sortowania alfabetycznego dla osob, ktore urodzily sie w tym samym roku.

Które z tych podejść masz na myśli?
1.Posortowanie przefiltrowanej tablicy zawierającej tylko osoby urodzone w danym roku.
2.Posortowanie tablicy najpierw po roku, a następnie alfabetycznie.

0
Patryk27 napisał(a):
ludzie tablica[n]; 

To się nazywa VLA i nie istnieje jako-tako w C++ (tj. tworzenie tablicy dla n, które nie jest stałe) - wykorzystaj std::vector lub new int[n] (skądinąd anty-idiom w nowoczesnym C++ :P).

Wprawdzie dopiero zaczynam nauke programowania na uczelni i jeszcze nie slyszalem o czyms takim jak VLA. Dodam takze, ze wielkosc tablicy zapisujemy wlasnie tak jak zapisalem w kodzie, wiec byc moze jest to "do przezycia".

Moglbym dodac wyraz CONST dla 'n', wtedy jak sadze 'n' powinno byc stala.

Vectorów jeszcze nie miałem, więc musiałbym jeszcze o tym jeszcze trochę poczytać zanim wprowadzę coś nowego do swojego programu.

2.Posortowanie tablicy najpierw po roku, a następnie alfabetycznie.

Najpierw sortuje po roku, jezeli beda osoby ktore urodzily sie w tym samym roku to posortuje ich dodatkowo wedlug nazwisk, czyli alfabetycznie.

2

Moglbym dodac wyraz CONST dla 'n', wtedy jak sadze 'n' powinno byc stala.

Przecież wczytujesz ją z klawiatury - jak może być zatem stała? ;-)

Najpierw sortuje po roku, jezeli beda osoby ktore urodzily sie w tym samym roku to posortuje ich dodatkowo wedlug nazwisk, czyli alfabetycznie.

Zatem prosta sprawa:

bool operator < (const ludzie &x) const  {
	if (this->rok == x.rok) {
		return // porównywanie po imieniu
	}
	
	return this->rok < x.rok;                   
}

personalnie lubię wciskać wszędzie this-> dla kryształowej pewności - możesz oczywiście również pomijać tam, gdzie wolno

2
Wprawdzie dopiero zaczynam nauke programowania na uczelni i jeszcze nie slyszalem o czyms takim jak VLA.
Nic nie stoi na przeszkodzie aby zerknąć do sieci: VLA in C++
0

Nic nie stoi na przeszkodzie aby zerknąć do sieci: VLA in C++

Juz to zrobilem.

Zatem prosta sprawa:

bool operator < (const ludzie &x) const  {
	if (this->rok == x.rok) {
		return // porównywanie po imieniu
	}
	
	return this->rok < x.rok;                   
}

personalnie lubię wciskać wszędzie this-> dla kryształowej pewności - możesz oczywiście również pomijać tam, gdzie wolno

Super! Dziala i wypisuje wyniki jak nalezy!

Glupio mi troche, bo wystarczylo dodac najzwyklejszego if'a.. Jeszcze musze sie duzo nauczyc...
Dziekuje bardzo za pomoc i zycze milego wieczoru! ;)

PS:
Czym jest this->? Strzalka odnosi sie do adresu struktury jak sądzę?

1 użytkowników online, w tym zalogowanych: 0, gości: 1