Sortowanie w programowaniu obiektowym

0

Cześć,

zacząłem trochę programowania obiektowego. I totalnie sobie nie radzę z sortowaniem obiektów według atrybutu, nie rozumiem jak powinno zostać to zrobione. Czy mógłby ktoś wytłumaczyć?

Mam taki kod:

#include<iostream>
#include<string>
using namespace std;
class Ksiazka { 
	int id;
	string tytul; 
	string autor;
	float cena;
	float rok_wydania;
	float liczba_stron;
	string stan;
public: 
	void wpisz() {
		cout << "\nPodaj informacje o ksiazce\n";
		cout << "identyfikator ksiazki: ";
		cin >> id;
		cout << "tytul: ";
		cin >> ws; //wyczyszczenie wejscia z białych znaków
		getline(cin, tytul);
		cout << "autor: ";
		getline(cin, autor);
		cout << "cena: ";
		cin >> cena;
		cout << "rok wydania: ";
		cin >> rok_wydania;
		cout << "liczba stron: ";
		cin >> liczba_stron;
		cout << "stan: ";
		cin >> ws;
		getline(cin, stan);
	}
	void pokaz() {
		cout << "\n\"" << tytul << "\", " << autor << ", " << cena << " zl.";
	}
	float daj_cene() {
		return cena;
	}
	string daj_autora() {
		return autor;
	}
	float daj_rok() {
		return rok_wydania;
	}
};

int dodaj_ksiazki(int n, Ksiazka ksiazki[]) {

	char decyzja = 't';
	do {
		ksiazki[n].wpisz();
		n++;
		cout << "\nCzy chcesz dodac nowa ksiazke (t/n) ";
		cin >> decyzja;
	} while (decyzja == 't');
	return n;
}
void pokaz_wszystkie_ksiazki(int n, Ksiazka ksiazki[]) {
	for (int i = 0; i < n; i++) {
		ksiazki[i].pokaz();
	}
}
void pokaz_tanie_ksiazki(int n, Ksiazka ksiazki[]) {
	float cena_max;
	cout << "\nPodaj cene maksymalna: ";
	cin >> cena_max;
	for (int i = 0; i < n; i++) {
		if (ksiazki[i].daj_cene() <= cena_max) {
			ksiazki[i].pokaz();
		}
	}
}

}



int main() {
	Ksiazka ksiazki[100]; 
	int lb_ksiazek = 0;
	lb_ksiazek = dodaj_ksiazki(lb_ksiazek, ksiazki);
	pokaz_wszystkie_ksiazki(lb_ksiazek, ksiazki);
	pokaz_tanie_ksiazki(lb_ksiazek, ksiazki);

}

I moje pytanie: jak mogę posortować utworzone obiekty np. po cenie rosnąco?

Będę wdzięczny za pomoc
Pozdrawiam

4

Masz do wyboru:

  • Piszesz własną funkcję sortującą, która wewnątrz używa pola ceny do sortowania.
  • Implementujesz własny operator < i używasz std::sort

np.

bool operator<( const Ksiazka& k1 , const Ksiazka& k2  )
{
  return k1.cena<k2.cena;
}
0

Dodałem sobie coś takiego na koniec:

void posortuj_od_najtanszych(int n, Ksiazka ksiazki[]) {

	for (int i = 0; i < n; i++)
		for (int j = 1; j < n - i; j++)
			if (ksiazki[j - 1].daj_cene() > ksiazki[j].daj_cene)
				swap(ksiazki[j - 1].daj_cene, ksiazki[j].daj_cene);

}

int main() {
	Ksiazka ksiazki[100]; 
	int lb_ksiazek = 0;
	lb_ksiazek = dodaj_ksiazki(lb_ksiazek, ksiazki);
	pokaz_wszystkie_ksiazki(lb_ksiazek, ksiazki);
	pokaz_tanie_ksiazki(lb_ksiazek, ksiazki);
	pokaz_ksiazki_autora(lb_ksiazek, ksiazki);
	pokaz_ksiazki_roku(lb_ksiazek, ksiazki);
	posortuj_od_najtanszych(lb_ksiazek, ksiazki);
}

Ale dostaję błędy: "wskaźnik do powiązanej funkcji może zostać użyty tylko do wywołania tej funkcji", "żadne wystąpienie elementu funkcja przeciążona "swap" nie jest zgodne z listą argumentów"

=============================================================================

TomaszLiMoon napisał(a):

Masz do wyboru:

  • Piszesz własną funkcję sortującą, która wewnątrz używa pola ceny do sortowania.
  • Implementujesz własny operator < i używasz std::sort

np.

bool operator<( const Ksiazka& k1 , const Ksiazka& k2  )
{
  return k1.cena<k2.cena;
}

W jaki sposób wywołać mogę ten "sort"? Próbuję na podstawie przykładów w internecie ale coś nie idzie.

2

Rosnąco:

#include <algorithm>

// ...

	std::sort( ksiazki, ksiazki + lb_ksiazek, []( Ksiazka &a, Ksiazka &b )
	{
		return a.daj_cene() < b.daj_cene();
	} );
2

W jaki sposób wywołać mogę ten "sort"? Próbuję na podstawie przykładów w internecie ale coś nie idzie

Na Twoim miejscu użył bym std::vector do przechowywania książek. Poniżej masz typowy generic example.

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

struct Book
{ 
	int id {0};
	string title; 	
	int price {0};	
};

bool operator<( const Book& b1 , const Book& b2  )
{
   return b1.price<b2.price;
}

ostream& operator<<( ostream& out , const Book& b  )
{
   return out << b.id << " : " << b.title << " : " << b.price;
}

int main()
{
    vector<Book> bookstore; 

    bookstore.push_back( Book{ 1  ,"A" , 345 } );
    bookstore.push_back( Book{ 2  ,"B" , 145 } );
    bookstore.push_back( Book{ 3  ,"C" , 200 } );
     
    sort( begin(bookstore) , end(bookstore) );

    for( const auto& book : bookstore ) cout << book << endl;
}

https://godbolt.org/z/rYah9xPvY

0
rojasQ napisał(a):

Dodałem sobie coś takiego na koniec:

void posortuj_od_najtanszych(int n, Ksiazka ksiazki[]) {

	for (int i = 0; i < n; i++)
		for (int j = 1; j < n - i; j++)
			if (ksiazki[j - 1].daj_cene() > ksiazki[j].daj_cene)
				swap(ksiazki[j - 1].daj_cene, ksiazki[j].daj_cene);

}

Oczywiście, komparator to jest słuszne podejście, natomiast, aby Twoje rozwiązanie się skompilowało, brakuje ci ():

 			if (ksiazki[j - 1].daj_cene() > ksiazki[j].daj_cene())

itd.

2

Mi się bardziej podoba następujący koncept:

#include <iostream>
#include <functional>
#include <algorithm>
#include <vector>
using namespace std;

struct Book
{ 
	int id {0};
	string title; 	
	int price {0};
    static bool byId(const Book &a,const Book &b) { return less<typeof(id)>{}(a.id,b.id); }
    static bool byTitle(const Book &a,const Book &b) { return less<typeof(title)>{}(a.title,b.title); }
    static bool byPrice(const Book &a,const Book &b) { return less<typeof(price)>{}(a.price,b.price); }
};

int main()
{
	vector<Book> tb;
	sort(begin(tb),end(tb),Book::byId);
	sort(begin(tb),end(tb),Book::byTitle);
	sort(begin(tb),end(tb),Book::byPrice);
	return 0;
}
3

C++20 rocks:

#include <iostream>
#include <algorithm>
#include <vector>
#include <ranges>

struct Book
{ 
	int id {0};
	std::string title; 	
	int price {0};
};

std::ostream& operator<<(std::ostream& out, const Book& book)
{
    return out <<  book.id << ": " << book.title << "  $" << book.price;
}

void print(const auto& c)
{
    std::cout << "----\n";
    for(const auto& i : c) {
        std::cout << i << '\n';
    }
}

int main()
{
    using std::ranges::sort;
	std::vector books{
        Book {1, "Lords of the ring", 99},
        {0, "Symfonia C++", 55},
        {5, "Romeo i Julia", 5},
    };

    print(books);
    sort(books, {}, &Book::id);
    print(books);
    sort(books, {}, &Book::title);
    print(books);
    sort(books, std::greater{}, &Book::price);
    print(books);
    
	return 0;
}

https://godbolt.org/z/TdYjxrvGe

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