Sortowanie "Flaga Polski", wykrzaczenie programu

0

Funkcja sortuje tablice w taki sposób, aby studenci z wiekiem <18 byli po lewej stronie tablicy, a >=18 po prawej stronie tablicy. Program "wywraca się" przy sortowaniu (funkcja sortStudnetsAge), nie bardzo rozumiem dlaczego, mogę liczyć na Waszą pomoc ? :)

#include <iostream>

using namespace std;

struct Students
{
    int id;
    char sex;
    int age;

};
void sortStudnetsAge(Students *student,int students)
{
    int i=0;
    int a=students-1;
    while(i<a)
    {
        if(student[i].age<18)
        {
            if(student[a].age>=18)
            {
                Students tmp = student[i];
                student[i]=student[a];
                student[a]=tmp;
                i++;
            }
            else
            {
                a--;
            }
        }
        else
        {
            i++;
        }
    }
}
void createStudents(Students *student, int students)
{
    for(int i=0; i<students; i++)
    {
        // cout<<"Podaj Id studenta"<<endl;
        // cin >> student[i].id;
        cout<<"Podaj wiek studenta"<<endl;
        cin >> student[i].age;
        // cout<<"Podaj plec studenta (K lub M)"<<endl;
        // cin >> student[i].sex;
    }
}
void showStudents(Students *student, int students)
{
    for(int i=0; i<students; i++)
    {
        // cout<<i+1<<"- Id "<<student[i].id;
        cout<<" | wiek "<<student[i].age;
        // cout<<" | plec "<<student[i].sex<<endl;
    }
}
int main()
{
    cout << "Podaj liczbe studentow"<<endl;
    int students;
    cin >> students;
    Students *student = new Students;
    createStudents(student,students);
    showStudents(student,students);
    sortStudnetsAge(student,students);
    cout <<   endl;
    cout << "----------------------------------------------------"<<endl;
    cout <<   endl;
    showStudents(student,students);
    return 0;
}
1

Co to znaczy że się wywraca?
Jeśli chodzi o kolejność po sortowaniu to po prostu zmień warunek na:

if(student[i].age>=18)
{
   if(student[a].age<18) {}
}
2

Deklarujesz

Students *student = new Students;

jednego studenta. Potrzebujesz zadeklarować liczbę studentów:

Students *student = new Students[liczba_studentow];

Dodatkowo przed return lub kiedy skończysz korzystać z tych danych należy je zwoolnić(same się nie zwolnią):

delete []student;

Dodatkowo nazywasz pojedyńczego studenta jako "Students", a grupę studentów jako "student", to nie dobrze.

Zamiast new i delete skorzystaj z inteligentnych wskaźników, unique_... .

1
    int students;
    cin >> students;
    Students *student = new Students;
    createStudents(student,students);

new Students tworzy jednego studenta. Jeśli masz "tablicę" zawierającą więcej niż jednego studenta to program się wywala bo masz UB. Użyj std::vector aby zaoszczędzić sobie problemów i błędnego kodu. Nie wiem czy to jakieś zadanie czy tylko chcesz osiągnąć zamierzony efekt. Jeśli to drugie - użyj std::partition.

Polecam lekturę: https://dsp.krzaq.cc/post/176/ucze-sie-cxx-kiedy-uzywac-new-i-delete/

0

Tak sobie myślę: a nie możesz dać wszystkich studentów na lewo, a dopiero później powyżej 18 lat odsiać na prawo? Jeden warunek w pętli mniej.

0

Można to zrobić też tak:

int partition_by_age(vector<Student> &students, int age, int b, int e) {
	// Make e last index, not index after last element!
	--e;

	// Just a normal partition you would use in quicksort.
	while (b < e) {		
		// Increment beginning while elements are on good side.
		while (b < e && age < students[e].age)
			--e;
		// Decrement end while elements ore on good side.
		while (b < e && students[b].age <= age)
			++b;
		// If we're here elements need swap.
		if (b < e)
			swap(students[b], students[e]);
	}
}

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