Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.68/34: Рейтинг темы: голосов - 34, средняя оценка - 4.68
14 / 14 / 1
Регистрация: 17.08.2015
Сообщений: 460
1

Qsort() Как отсортировать массив объектов по полю объекта

23.08.2015, 09:38. Показов 6895. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте!

Никак не могу сладить с функцией qsort().

У меня есть класс, и в нем нужно сделать сортировку по ОДНОМУ элементу (по ID) и вследствие этого рассортировать всех членов класса (то есть рассортировать по одному параметру, по ID)
C++ (Qt)
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include<iostream>
#include<iomanip>
#include<vector>
#include <locale>
#include <fstream>
#include <cstring>
#include <cstdlib>
 
using namespace std;
 
class worker //объявляем класс работник
{
    //поля класса делаем закрытыми
    char surname[64];
    char name[64];
    char patron[64];
    char post[128];
    double salary;
    double h_pay;
    int hours;
    int id;
public:
    //вот эти строчки непонятны. Зачем ???
    worker(){}; // мне непонятно, зачем здесь конструктор и деструктор??
    ~worker(){};  //м.б. |для очищения памяти|?
 
    int getID(){return id;} //фи-я возвращает значение, которое лежит в поле id класса worker
};
 
class arr //НАЧИНАЕМ ОПИСАНИЕ КЛАССА arr
{//w -  это переменная класса????? или что?
    vector <worker> w; // Так как в vector можно помещать объекты любого типа, то здесь мы поместили в него объекты класса 
                       // worker, and besides создав в классе arr объект класса worker
                      // а так как мы не знаем, сколько будет такой информации, нам нужно будет все время, по необходимости
                       // увеличивать размер этого объекта. Поэтому здесь используем vector, так как не знаем изначально
                       // какое количество нам нужно
public:
 
int comp(const void *a, const void *b){
    return * (char* )a-* (char*)b;
}
    //Сортировка данных по номеру ID
    void Sort()
        {
            char key;
            cout<<"How sort?"<<endl
                <<"1. bubble"<<endl
                <<"2. qsort "<<endl;
            cin>>key;
 
            if(key=='1')
            {
                worker temp; // временная переменная для хранения элемента массива
                bool exit = false; // булевая переменная для выхода из цикла, если массив отсортирован
 
                while (!exit) // пока массив не отсортирован
                {
                 exit = true;
                 for (int i = 0; i < (w.size()-1); i++) // внутренний цикл
                 //сортировка пузырьком по возрастанию - знак >
                 //сортировка пузырьком по убыванию - знак <
                 if (w[i].getID() > w[i + 1].getID()) // сравниваем два соседних элемента
                    {
                  // выполняем перестановку элементов массива
                        swap(w[i],w[i+1]); //меняем местами два элемента, без третьей переменнной!
                        exit = false; // на очередной итерации была произведена перестановка элементов
                    }
                 }
 
            }
 
            if(key==2)
            {
                 qsort(*w[0], w.size(), 28, comp);
            }
        }
 
 
 
};
 
 
int main()
{
     int ID; // в главной программе нам нужа будет переменная, которую мы будем сравнивать с полем, описанным в классе
            // worker
    char key;//сида считываем то, что ввели в МЕНЮ
 
 arr mas;  // создали ЕДИНСТВЕННЫЙ ОБЪЕКТ КЛАССА arr
    worker emp; //СОЗДАЛИ второй ОБЪЕКТ КЛАССА worker (первый был создан в классе arr)
 
    //далее просто в бесконечном цикле крутится меню, условие выхода введение q
    while(1)
    {
        cout<<endl
            <<"Enter the action"
           <<"C Sort data."<<endl
 
  switch(key)
        { 
            case 'c':
            mas.Sort();
        }
 
    }
 
    system("pause");
    return 0;
}
Но, что-то с функцией qsort не ладно. Как быть...?

P.S.
Я не стал вставлять в код другие функции, как то например ввод нового члена, просто потому что там все работает нормально, чтобы не загромождать код
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.08.2015, 09:38
Ответы с готовыми решениями:

Отсортировать массив объектов пользовательского типа по заданному полю
3.1. Написать программу, работающую с базой данных в виде мас- сива структур и выполняющую...

Отсортировать структуру User по заданному полю при помощи qsort
Нужно отсортировать структуру через qsort по полю surname define _CRT_SECURE_NO_WARNINGS #include...

Как отсортировать массив по по полю ?
C# как отсортировать массив по по полю Vp? using System; using System.Collections.Generic;...

Как отсортировать список объектов по одному из свойств этого объекта
Здравствуйте. У меня есть класс: public class kvit { ...

19
2443 / 1841 / 406
Регистрация: 15.12.2013
Сообщений: 8,238
23.08.2015, 10:12 2
Blitzor DDD, для сортировки std::vector есть std::sort из algorithm:
http://www.cplusplus.com/reference/algorithm/sort/
зачем вам C-шный qsort?
0
14 / 14 / 1
Регистрация: 17.08.2015
Сообщений: 460
23.08.2015, 10:18  [ТС] 3
Просто, я что-то никак не могу понять, как сортировать объекты по одному из полей этих объектов и все туманно поэтому...
0
12 / 12 / 8
Регистрация: 12.08.2015
Сообщений: 55
23.08.2015, 11:16 4
Blitzor DDD, посмотри тут я уже решал через квик сорт и расчёску Сортировка расчёской и быстрая сортировка
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
23.08.2015, 11:26 5
Цитата Сообщение от Blitzor DDD Посмотреть сообщение
как сортировать объекты по одному из полей этих объектов
См. вторую перегрузку std::sort, которая принимает компаратор. Элементарный пример для структуры из двух полей:
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
#include <algorithm>
#include <iostream>
#include <vector>
 
struct S {
    S(int x, int y) : x(x), y(y) {}
    int x;
    int y;
};
 
bool sortByX(const S& lhs, const S& rhs) {
    return lhs.x < rhs.x;
}
 
bool sortByY(const S& lhs, const S& rhs) {
    return lhs.y < rhs.y;
}
 
void print(const std::vector<S>& v) {
    for( const S& s : v ) 
        std::cout << s.x << ":" << s.y << ' ';
    std::cout << std::endl;
}
 
int main()  {
    
    std::vector<S> v{ S(1,200), S(2,100) };
    print(v); // Исходное состояние
    
    std::sort( v.begin(), v.end(), sortByY );
    print(v); // После сортировки по полю Y
    
    std::sort( v.begin(), v.end(), sortByX );
    print(v); // После сортировки по полю X
}
http://coliru.stacked-crooked.... 20dad38f04
2
14 / 14 / 1
Регистрация: 17.08.2015
Сообщений: 460
23.08.2015, 11:33  [ТС] 6
Да, видимо, как начинающий программист на С++ до этого я еще не дорос...
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
23.08.2015, 11:35 7
Blitzor DDD, если что-то не понятно по коду, спрашивай, не стесняйся
0
14 / 14 / 1
Регистрация: 17.08.2015
Сообщений: 460
23.08.2015, 11:38  [ТС] 8
Ладно) Я постараюсь с этим разобраться
0
14 / 14 / 1
Регистрация: 17.08.2015
Сообщений: 460
24.08.2015, 08:44  [ТС] 9
Здравствуйте! У меня задача может быть и классическая, однако я так и не нашел четкого ее описания и решения.
Дан массив из объектов класса, нужно отсортировать по одному из полей этого класса, я накидал примерный код, но вот, что должно быть в функции qsort() - в ф-ии быстрой сортировки я не знаю...

Может кто-нибудь помочь?


C++ (Qt)
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
#include <iostream>
#include <iomanip>
#include <cstdlib>
 
using namespace std;
class people{
 
    int ID;
    char Firstname[10];
    char Secondname[15];
 
public:
  getAll(){
      cout<<"Enter ID";cin>>ID;
      cout<<"Enter First name ";cin>>Firstname;
      cout<<"Enter Second name";cin>>Secondname;
  }
  showALL(){
      cout<<setw(4)<<ID;
      cout<<setw(12)<<Firstname;
      cout<<setw(16)<<Secondname;
      cout<<endl;
  }
 
  int comp(const void *a, const void *b)
  {
    return (* (int *) a - * (int *) b);}
 
  qsort( /*что должно быть тут? */ );
 
}w[3];
 
 
int main()
{
    int i;
     for(i=0;i<3;i++){
         w[i].getAll();
     }
     cout<<endl<<endl;
     cout<<setw(4)<<"ID"<<setw(12)<<"First Name"<<setw(16)<<"Second Name"<<endl;
     for(i=0;i<3;i++){
         w[i].showALL();
     }
 
     //Как теперь организовать сортировку??
    
 
}

Результатом выполнения программы до сортировки будет следующее, например:
Id First Name Second Name
9 Viktor Sergeev
1 Ivan Smolin
12 Igor Petrov


А после выполнения функции сортировки qsort() должно быть вот так:


Id First Name Second Name
1 Ivan Smolin
9 Viktor Sergeev
12 Igor Petrov



Сортирует по ID (поле класса people) и меняет местами объекты массива.
Как сделать сортировку по полю.....?
0
7795 / 6561 / 2985
Регистрация: 14.04.2014
Сообщений: 28,683
24.08.2015, 08:59 10
Лучший ответ Сообщение было отмечено Ilot как решение

Решение

qsort() - древняя функция из C для массивов. В C++ следует использовать std::sort().
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
#include <iostream>
#include <iomanip>
#include <cstdlib>
 
using namespace std;
class people{
 
    int ID;
    char Firstname[10];
    char Secondname[15];
 
public:
  getAll(){
      cout<<"Enter ID";cin>>ID;
      cout<<"Enter First name ";cin>>Firstname;
      cout<<"Enter Second name";cin>>Secondname;
  }
  showALL(){
      cout<<setw(4)<<ID;
      cout<<setw(12)<<Firstname;
      cout<<setw(16)<<Secondname;
      cout<<endl;
  }
 
}w[3];
 
int comp(const void *a, const void *b)
{
    return ((people *)a)->ID - ((people *)b)->ID;
}
 
 
int main()
{
    int i;
     for(i=0;i<3;i++){
         w[i].getAll();
     }
     cout<<endl<<endl;
     cout<<setw(4)<<"ID"<<setw(12)<<"First Name"<<setw(16)<<"Second Name"<<endl;
     for(i=0;i<3;i++){
         w[i].showALL();
     }
 
    qsort(w, 3, sizeof(w), comp);
 
}
1
1642 / 1091 / 487
Регистрация: 17.07.2012
Сообщений: 5,345
24.08.2015, 09:25 11
Лучший ответ Сообщение было отмечено Blitzor DDD как решение

Решение

Не знаю может немного криво(если что может покритикуйте кто-то), но мне в голову только такой путь пришел.
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
#include <iostream>
#include <iomanip>
#include <cstdlib>
 
using namespace std;
 
class people {
 
    int ID;
    char Firstname[10];
    char Secondname[15];
 
public:
    void getAll() {
        cout << "Enter ID:";cin >> ID;
        cout << "Enter First name:";cin >> Firstname;
        cout << "Enter Second name:";cin >> Secondname;
    }
    void showALL() {
        cout << setw(4) << ID;
        cout << setw(12) << Firstname;
        cout << setw(16) << Secondname;
        cout << endl;
    }
 
    friend int comp(const void *a, const void *b);
 
}w[5];
 
 
int comp(const void *a, const void *b)
    {
        return (reinterpret_cast<const people*>(a)->ID - reinterpret_cast<const people*>(b)->ID);
    }
 
int main()
{
    int i;
    const int n = 5;//Количество элементов массива
    for (i = 0;i<n;i++) w[i].getAll();
    cout << endl << endl;
    cout << "Before sort:" << endl;
    cout << setw(4) << "ID" << setw(12) << "First Name" << setw(16) << "Second Name" << endl;
    for (i = 0;i<n;i++) w[i].showALL();
    qsort(w, n, sizeof(people), comp);
    cout << endl << "After sort:" << endl;
    cout << setw(4) << "ID" << setw(12) << "First Name" << setw(16) << "Second Name" << endl;
    for (i = 0;i<n;i++) w[i].showALL();
    system("PAUSE");//Писал в Visual Studio, можно убрать
}
Дело в том что чтобы сравнить 2 объекта нужно иметь доступ к private данным класса(ID это же private). Поэтому я использовал дружественную функцию которая имеет доступ к приватным данным.
1
14 / 14 / 1
Регистрация: 17.08.2015
Сообщений: 460
24.08.2015, 09:26  [ТС] 12
Эх....

Жаль, но почему-то не работает.
Сборка проходит нормально, но вместо сортировки выдаёт

ID First Name Second Name
0
0 0
0


Не могу понять, что не так...
И Вы говорите, что лучше просто sort(), а что это за сортировка, может быть ее лучше использовать?
0
1642 / 1091 / 487
Регистрация: 17.07.2012
Сообщений: 5,345
24.08.2015, 09:27 13
Я сначала когда прогу запускал не понимал почему два раза выводит массив, а потом понял что это просто сливается как в один и сортированный и несортированный массив и потому добавил
C++
1
cout << "Before sort:" << endl;
1
14 / 14 / 1
Регистрация: 17.08.2015
Сообщений: 460
24.08.2015, 09:29  [ТС] 14
Новичок,
синтаксис у Вас не очень простой для чела, который меньше месяца прогает на С++)
0
1642 / 1091 / 487
Регистрация: 17.07.2012
Сообщений: 5,345
24.08.2015, 09:32 15
Blitzor DDD, ну так спросите что непонятно.
Цитата Сообщение от Новичок Посмотреть сообщение
reinterpret_cast<const people*>
Вас эта строка напугала? Это просто преобразование из const void* в const people*.
0
14 / 14 / 1
Регистрация: 17.08.2015
Сообщений: 460
24.08.2015, 09:37  [ТС] 16
Да, именно это и напугало)

То есть, насколько я понимаю, функция друг просто позволяет обратится к закрытому члену классу, можно и без нее, если int ID объявить типа public?

А скажи пожалуйста, в Вашей строке зачем нужно преобразование такое?
0
1642 / 1091 / 487
Регистрация: 17.07.2012
Сообщений: 5,345
24.08.2015, 09:41 17
Цитата Сообщение от Blitzor DDD Посмотреть сообщение
То есть, насколько я понимаю, функция друг просто позволяет обратится к закрытому члену классу, можно и без нее, если int ID объявить типа public?
Да, так и есть.
Цитата Сообщение от Blitzor DDD Посмотреть сообщение
А скажи пожалуйста, в Вашей строке зачем нужно преобразование такое?
Погуглите про приведения типов в С++. reinterpret_cast используется ,как правило, чтобы преобразовывать типы указателей.
0
14 / 14 / 1
Регистрация: 17.08.2015
Сообщений: 460
24.08.2015, 09:44  [ТС] 18
Спасибо Вам большое!
Внесли чуток света и ясности в мой тёмный, мутный омут)
0
Croessmah
24.08.2015, 10:02
  #19

Не по теме:

Внесли чуток света и ясности в мой тёмный, мутный омут)
Главное при этом сверического коня не спараллелепидеть :)

0
18899 / 9857 / 2410
Регистрация: 30.01.2014
Сообщений: 17,300
24.08.2015, 10:04 20
Цитата Сообщение от Новичок Посмотреть сообщение
reinterpret_cast используется ,как правило, чтобы преобразовывать типы указателей.
Из void*-то для преобразования достаточно static_cast.
1
24.08.2015, 10:04
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.08.2015, 10:04
Помогаю со студенческими работами здесь

Отсортировать список объектов по полю класса
Добрый вечер, есть некая структура, храню в списке объекты этой структуры. Хочу упорядочить список...

Отсортировать массив с помощью функции qsort
Приведите пожалуйста пример, как можно отсортировать массив с помощью функции qsort

Как отсортировать такой массив по полю ДАТА?
Как остортировать этот массив, по полю created_time (ДАТА) ?

Отсортировать вектор объектов класса по определенному полю
Нужно отсортировать вектор word объектов objectW по полю length. В 42 строке пытаюсь это сделать,...

Массив отсортировать в порядке возрастания (быстрой сортировкой, qsort)
Нужна помощь, у меня сделано задание нужно массив отсортировать в порядке возрастания, нужно...

Отсортировать массив методами: бинарных вставок, пузырька, пирамидальной сортировки и qsort
помогите, в сортировке по убыванию элементов. Методы: бинарных вставок, пузырька , пирамидальная...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru