| skullek Temat założony przez niniejszego użytkownika | Sortowanie struktur - menu » 2015-12-08 20:12:31 Witam mam standardowe zadanie ze struktur, stworzenie struktury, wpisanie do niej danych i w menu wybór sortowania - według nazwiska(Potem imie jesli nazwisko sie powtarza), nr_index,pesel i max_srednia. Doszedłem do momentu sortowania, coś tam poszperałem i udało mi się skleić tak, że sortuje według nazwisko+imie - ale nie wiem jak to przerobić żeby działało na kolejne elementy struktury. Nie wiem jak teraz posortować według indexów  itd... #include <iostream>#include <cstdlib>
 #include <string>
 #include <algorithm>
 #include <iomanip>
 using namespace std;
 
 struct student
 {
 
 string imie;
 char nazwisko[ 40 ];
 string nr_index;
 string pesel;
 float oceny[ 11 ];
 bool operator <( const student & x ) const
 int porownaj = strcmp( nazwisko, x.nazwisko );
 
 if( porownaj == 0 )
 return imie < x.imie;
 
 return porownaj > 0 ? 0: 1;
 }
 
 };
 
 void wczytaj_dane( student *& tab, int n )
 {
 for( int i = 0; i < n; ++i )
 {
 cout << "Student nr " << i + 1 << endl << "Imie: ";
 cin >> tab[ i ].imie;
 cout << "Nazwisko: ";
 cin >> tab[ i ].nazwisko;
 cout << "Numer Indeksu: ";
 cin >> tab[ i ].nr_index;
 cout << "Pesel: ";
 cin >> tab[ i ].pesel;
 cout << "Srednia semestralna ocen: " << endl;
 for( int j = 1; j <= 10; ++j )
 {
 if( cin.good() ) cin >> tab[ i ].oceny[ j ];
 
 std::cin.clear();
 std::cin.sync();
 }
 cout << "-------------------------" << endl;
 
 }
 cout << endl;
 }
 
 
 
 
 
 void menu_sort_choose( student *& tab, int n )
 {
 int menu_sortowanie_tab;
 cin >> menu_sortowanie_tab;
 switch( menu_sortowanie_tab )
 {
 case 1:
 
 std::sort( tab, tab + n );
 for( int i = 0; i < n; i++ )
 {
 std::cin.clear();
 std::cin.sync();
 cout << "Nazwisko: " << tab[ i ].nazwisko << endl;
 cout << "Imie: " << tab[ i ].imie << endl;
 cout << "Nr_index: " << tab[ i ].nr_index << endl;
 cout << "Pesel: " << tab[ i ].pesel << endl;
 }
 break;
 
 case 2:
 
 break;
 
 case 3:
 
 break;
 
 case 4:
 
 break;
 
 case 5:
 
 break;
 
 }
 
 }
 
 
 void menu_sort_list( student *& tab, int n )
 {
 cout << "*****Wybierz sortowanie*****" << endl;
 cout << "[1]. Porzadek alfabetyczny nazwisk i imion studentow" << endl;
 cout << "[2]. Numer indeksu" << endl;
 cout << "[3]. Data Urodzenia" << endl;
 cout << "[4]. Maksymalna srednia" << endl;
 cout << "[5]. Wyjdz" << endl;
 menu_sort_choose( tab, n );
 
 }
 
 
 
 
 
 int main()
 {
 int liczba_studentow;
 cout << "Ilu studentow wpisac: ";
 cin >> liczba_studentow;
 student * tablica = new student[ liczba_studentow ];
 wczytaj_dane( tablica, liczba_studentow );
 cout << "-----Studenci wpisani-----" << endl << endl;
 menu_sort_list( tablica, liczba_studentow );
 delete[] tablica;
 system( "pause" );
 return 0;
 }
 
 | 
|  | 
| carlosmay | » 2015-12-08 20:45:17 Napisz predykat do funkcji  std::sort() , który będzie porównywać indeksy czy pesel, czy co tam sobie zapragniesz.
 edit: Nie wiem czy da się napisać predykat dla zwykłej tablicy.
 Nigdy tego nie robiłem. Właśnie próbowałem i nie sortuje (tylko w podstawowym zakresie bez predykatu).
 Dla  std::vector  sortuje prawidłowo i to zarówno dla zewnętrznej funkcji jak i wyrażenia lambda.
 Może jest jakiś sposób. Jeśli nie, zostaje napisać ręcznie sortowanie dla każdego wariantu lub jakiś kontener.
 | 
|  | 
| darko202 | » 2015-12-09 12:49:17 | 
|  | 
| carlosmay | » 2015-12-10 10:02:45 @darko202. Próbowałem na różne sposoby i nie udało mi się napisać predykatu dla sortowania wg indeksu lub peselu. Może pokażesz działający przykład takiego zastosowania. Sam jestem ciekawy ( może kiedyś się przyda). std::sort( tab, tab + n,[]( student & s1, student & s2 ) { return s1.nr_indeksu <= s2.nr_indeksu; }
 
 Takie rozwiązanie działa dla std::vector  a dla takiej tablicy nie. std::sort( tab, tab + n, indeks );
 bool indeks( student & s1, studenst & s2 ) {
 if( s1.nr_indeksu <= s2.nr_indeksu )
 return true;
 else
 return false;
 
 
 Takie też nie działa. | 
|  | 
| Monika90 | » 2015-12-10 11:30:14 Jak to może nie działać? Pewnie kompilator Ci się popsuł. | 
|  | 
| carlosmay | » 2015-12-10 11:44:50 | Jak to może nie działać? Pewnie kompilator Ci się popsuł. | 
  I właśnie tego nie rozumiem. std::vector  działa a tablica nie. Pomyślałem, że może to być różnica w przekazywaniu argumentów do funkcji. std::sort( tab, tab + n );  sortuje wg imienia, czyli pierwszego pola w strukturze. Dodanie predykatu powoduje brak sortowania.  Kompilator nie wyświetla żadnych komunikatów. Wieczorem jeszcze popatrzę. | 
|  | 
| Monika90 | » 2015-12-10 11:57:53 A już widzę. Nie można porównywać za pomocą tego operatora <=, musi być < albo >, takie są wymagania algorytmu sort. | 
|  | 
| carlosmay | » 2015-12-10 12:11:45 struct ss {string name;
 ss()
 : name( "" )
 { }
 ss( const string & s )
 : name( s )
 { }
 };
 
 int main()
 {
 ss ts[ 5 ];
 vector < ss > tv;
 for( int i = 0; i < 5; i++ ) {
 getline( cin, ts[ i ].name );
 tv.push_back( ts[ i ].name );
 }
 
 std::sort( ts, ts + 5,[]( ss & s1, ss & s2 ) { return s1.name < s2.name; } );
 for( ss & el: ts ) cout << el.name << endl;
 
 std::sort( tv.begin(), tv.end(),[]( ss & s1, ss & s2 ) { return s1.name < s2.name; } );
 for( ss & el: tv ) cout << el.name << endl;
 
 }
 
Faktycznie coś mi chyba szwankuje. To działa. Dla <=  też działa dobrze. Zmieniłem na ten znak w czasie kombinowania i tak zostało. Nie wiem co jest z kompilatorem. Co jakiś czas daje takie dziwne zachowania. | 
|  | 
| « 1 » |