Форум программистов, компьютерный форум CyberForum.ru

Сортировка класса - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 20, средняя оценка - 4.65
snakext
 Аватар для snakext
6 / 6 / 1
Регистрация: 08.06.2010
Сообщений: 35
03.12.2010, 15:21     Сортировка класса #1
Имеется класс :
C++
1
2
3
4
5
6
7
class cat{
    string name;
public:
    int catscore;
    void setname(string Name); // через эту ф-цию потом получаем name
......
};
Имеется массив объектов
C++
1
2
3
4
5
void main () {
....
cat cats[5];
...
}
Вопрос:
Как остортировать имена в зависимости от очков (int catscore) ?
Пробовал qsort - не вышло, сортировку Хоара не совсем понял, классы только начал изучать.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
03.12.2010, 15:59     Сортировка класса #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <iomanip>
#include <string>
#include <algorithm>
 
class Cat {
    std::string _name;
    int _score;
public:
    Cat(std::string n, int s) : _name(n), _score(s) {}
    Cat() : _name("unnamed"), _score(0) {}
    std::string name() const { return _name; }
    void name(std::string n) { _name = n; }
    int score() const { return _score; }
    void score(int s) { _score = s; }
    // bla bla bla
};
 
std::ostream & operator << (std::ostream & ost, const Cat & cat){
    ost << cat.name() << '\t' << cat.score();
    return ost;
}
 
struct CatCmp {
    bool operator () (const Cat & a, const Cat & b) {
        return a.score() < b.score();
    }
};
 
int main(){
    const int size(5);
    Cat cats[size];
    std::string name;
    int score;
    
    for ( int i = 0; i < size; ++i ){
        std::cout << "Name: ";
        std::cin >> name;
        std::cout << "Score: ";
        std::cin >> score;
        cats[i].name(name);
        cats[i].score(score);
    }
    
    std::sort(cats, cats + size, CatCmp());
    
    std::cout << "Name\tScore" << std::endl;
    for ( int i = 0; i < size; ++i )
        std::cout << cats[i] << std::endl;
    
    return 0;
}
Sudoki
124 / 64 / 1
Регистрация: 19.04.2010
Сообщений: 196
03.12.2010, 16:03     Сортировка класса #3
void qsort ( void * base, size_t num, size_t size, int ( * comparator ) ( const void *, const void * ) );

base
Pointer to the first element of the array to be sorted.
num
Number of elements in the array pointed by base.
size
Size in bytes of each element in the array.
comparator
Function that compares two elements. The function shall follow this prototype:

int comparator ( const void * elem1, const void * elem2 );

The function must accept two parameters that are pointers to elements, type-casted as void*. These parameters should be cast back to some data type and be compared.

The return value of this function should represent whether elem1 is considered less than, equal to, or greater than elem2 by returning, respectively, a negative value, zero or a positive value.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* qsort example */
#include <stdio.h>
#include <stdlib.h>
 
int values[] = { 40, 10, 100, 90, 20, 25 };
 
int compare (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}
 
int main ()
{
  int n;
  qsort (values, 6, sizeof(int), compare);
  for (n=0; n<6; n++)
     printf ("%d ",values[n]);
  return 0;
}
В твоем случае функция compare будет другом твоего класса и в нем уже можешь сравнивать по любым полям.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
03.12.2010, 16:19     Сортировка класса #4
Очень плохая затея - использовать функции из С с классами С++
Допустим, в классе определено поле - массив и оператор копирования
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
class ArrayHolder {
  int * arr;
  int size;
// ...
public:
  ArrayHolder() : arr(0), size(0) {}
  ArrayHolder(const ArrayHolder & another){
    *this = another;
  }
  ArrayHolder & operator = (const ArrayHolder & another){
    if ( this != &another ){
      if ( arr )
        delete [] arr;
      size = another.size;
      arr = new int [ size ];
      for ( int i = 0; i < size; ++i )
        arr[i] = another.arr[i];
    }
    return *this;
  }
  // ...
};
ну или вроде того. Угадайте, что при сортировке с помощью qsort() получится...

да и вообще в массивах лучше указатели на объекты класса хранить, а не сами объекты.
Sudoki
124 / 64 / 1
Регистрация: 19.04.2010
Сообщений: 196
03.12.2010, 16:25     Сортировка класса #5
Цитата Сообщение от Sudoki Посмотреть сообщение
The function must accept two parameters that are pointers to elements, type-casted as void*. These parameters should be cast back to some data type and be compared
Вы это перевидите в функцию передаются указатели. Если указатели привести к указателям на класс то никаких вызовов копирования и присваивания не будет.
snakext
 Аватар для snakext
6 / 6 / 1
Регистрация: 08.06.2010
Сообщений: 35
03.12.2010, 16:29  [ТС]     Сортировка класса #6
easybudda,спасибо за помощь, но я же специально выложил не весь код, чтобы мне подсказали только саму сортировку. А класс в целом и остальные вычисления у меня немного другие, то есть ваш код не подходит, кроме того, вот этот кусок
C++
1
2
3
4
std::ostream & operator << (std::ostream & ost, const Cat & cat){
        ost << cat.name() << '\t' << cat.score();
        return ost;
}
мне совершенно непонятен.


У меня есть :
C++
1
2
cats[i].setname("name1");  // и так до пятого
cats[i].catscore = X ;
И сортировать мне надо их. Полностью написанный код мне надо.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
03.12.2010, 16:37     Сортировка класса #7
Цитата Сообщение от snakext Посмотреть сообщение
я же специально выложил не весь код, чтобы мне подсказали только саму сортировку
так я собственно сам способ сортировки и показал, только на примере некоторого условного класса. Суть в следующем - определяется класс-функтор для сравнения объектов исходного класса, в котором собственно и происходит сравнение отдельно взятых полей. Второй вариант - в самом классе оператор < перегрузить...

Цитата Сообщение от snakext Посмотреть сообщение
вот этот кусок
C++
1
2
3
4
std::ostream & operator << (std::ostream & ost, const Cat & cat){
 ost << cat.name() << '\t' << cat.score();
 return ost;
}
мне совершенно непонятен.
Перегрузка оператора << для вывода на экран, не более того.
Sudoki
124 / 64 / 1
Регистрация: 19.04.2010
Сообщений: 196
03.12.2010, 16:39     Сортировка класса #8
int compare (cat* left, cat* right){
if (cat->left < cat->right)return 1;
if (cat->left == cat->right)return 0;
if (cat->left > cat->right)return -1;
}Но когда вызвал qsort, он выдал ошибку на этом compare в параметрах
qsort (cats,5,sizeof(cat),compare

так не пойдет
C++
1
2
3
4
5
int compare (const void* left, const void* right){
  Cat* l = static_cast<Cat*>left;
  Cat* r = static_cast<Cat*>right;
  //тут должно быть одно сравнение
}
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
03.12.2010, 16:42     Сортировка класса #9
Цитата Сообщение от Sudoki Посмотреть сообщение
Если указатели привести к указателям на класс то никаких вызовов копирования и присваивания не будет.
Ну при таком подходе - да, так я же и написал
Цитата Сообщение от easybudda Посмотреть сообщение
в массивах лучше указатели на объекты класса хранить, а не сами объекты.
И тем не менее ещё раз повторюсь
Цитата Сообщение от easybudda Посмотреть сообщение
Очень плохая затея - использовать функции из С с классами С++
lemegeton
 Аватар для lemegeton
2908 / 1337 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
03.12.2010, 16:54     Сортировка класса #10
easybudda очень прав, использовать функции С в программе С++ очень плохая идея. Не сегодня, так завтра нахватаетесь таких багов, которые опознать будет крайне непросто.

По теме.
Ну, STL вы уже используете, так что немного больше STL не повредит.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// подключение STL алгоритмов
#include <algorithm>
...
 
// функция сравнения cat.
bool compare_cats(cat &a, cat &b) { return a.name < b.name; }
...
 
// массив вместо обычного vector
vector<cat> cats[n];
...
 
// сортировка STL sort. Реализация quicksort. В среднем случае 
// сложность n*log(n).
sort(cats.begin(), cats.end(), compare_cats);
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.12.2010, 17:03     Сортировка класса
Еще ссылки по теме:

C++ Сортировка по одному из полей класса
C++ Сортировка массива с объектами класса
Не работает сортировка объектов класса C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
snakext
 Аватар для snakext
6 / 6 / 1
Регистрация: 08.06.2010
Сообщений: 35
03.12.2010, 17:03  [ТС]     Сортировка класса #11
easybudda, еще раз спасибо, все получилось
Yandex
Объявления
03.12.2010, 17:03     Сортировка класса
Ответ Создать тему
Опции темы

Текущее время: 01:52. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru