Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Sortowanie struktur - menu

Ostatnio zmodyfikowano 2015-12-10 12:11
Autor Wiadomość
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...

C/C++
#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 ]; // 1-11 indeksy ind[0] zostawic    -- wstawic 0 jesli semestru nie ukonczyl.
    bool operator <( const student & x ) const
    int porownaj = strcmp( nazwisko, x.nazwisko );
   
    if( porownaj == 0 ) //gdy nazwiska są równe sortujemy według imion
         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;
}
P-141629
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.
P-141632
darko202
» 2015-12-09 12:49:17
P-141656
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).

C/C++
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.

C/C++
std::sort( tab, tab + n, indeks );
// funkcja
bool indeks( student & s1, studenst & s2 ) {
    if( s1.nr_indeksu <= s2.nr_indeksu )
         return true;
    else
         return false;
   
 Takie też nie działa.
P-141704
Monika90
» 2015-12-10 11:30:14
Jak to może nie działać? Pewnie kompilator Ci się popsuł.
P-141706
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ę.


P-141709
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.
P-141710
carlosmay
» 2015-12-10 12:11:45
C/C++
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.


P-141711
« 1 »
  Strona 1 z 1