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

std::sort. Как сортировать список? (список указателей на объект) - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 58, средняя оценка - 4.81
res
56 / 9 / 1
Регистрация: 05.04.2010
Сообщений: 143
12.01.2012, 05:41     std::sort. Как сортировать список? (список указателей на объект) #1
Всем доброго времени суток!
Извините за флуд темами, я не специально

С простыми типами то всё понятно:
C++
1
2
3
std::vector<string> vStr;
... заполнили как то
std::sort(vStr.begin(), vStr.end());
но вот если свой тип?
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
struct Poet
{
    std::string lname; // фамилия
    std::string fname; // имя
};
 
void main()
{
    std::list<Poet*> listPoet;
 
    // создам поэтов
    Poet poet0, poet1, poet2;
 
    // заполняем
    poet0.lname = "Esenin";
    poet0.fname = "Sergey";
 
    poet1.lname = "Lermontov";
    poet1.fname = "Michael";
 
    poet2.lname = "Pushkin";
    poet2.fname = "Alexander";
 
    // добавляем поэтов в список
    listPoet.push_back(&poet0);
    listPoet.push_back(&poet1);
    listPoet.push_back(&poet2);
 
    // ?? как отсортировать список по фамилий и имени? 
        // listPoet.sort(....
 
        // вывод: Фамилия Имя
    for(std::list<Poet*>::iterator it = listPoet.begin(); it != listPoet.end(); ++it)
        std::cout << (*it)->lname << " " << (*it)->fname << std::endl;
 
        std::cin.get();
}
Вопрос: как отсортировать список поэтов по фамилий и имени?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.01.2012, 05:41     std::sort. Как сортировать список? (список указателей на объект)
Посмотрите здесь:

2-связный список на основе указателей next и pred C++
C++ Список(List) как отсортировать по убыванию используя функции reverse(); sort(); ао убыванию
Список указателей C++
Как сортировать массив при помощи функцыи sort C++
std::sort + std::lower_bound C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
12.01.2012, 05:50     std::sort. Как сортировать список? (список указателей на объект) #2
У своего типа дожнен быть перегружен оператор <, либо нужно указать функцию сравнения
res
56 / 9 / 1
Регистрация: 05.04.2010
Сообщений: 143
12.01.2012, 06:02  [ТС]     std::sort. Как сортировать список? (список указателей на объект) #3
Nameless One, хорошо, я про это читал, но в мозг не доходит.
Эх показали бы именно для моего примера, был бы рад.
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
12.01.2012, 06:21     std::sort. Как сортировать список? (список указателей на объект) #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
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
#include <iostream>
#include <algorithm>
#include <string>
 
struct foo
{
    std::string s;
    int i;
 
    foo(const std::string&, int);
    bool operator < (const foo&) const;
};
 
foo::foo(const std::string& _s, int _i)
    : s(_s), i(_i)
{
}
 
bool foo::operator < (const foo& rhs) const
{
    if(s == rhs.s)
    return i < rhs.i;
    return s < rhs.s;
}
 
bool comp(const foo& f1, const foo& f2)
{
    return f1.i > f2.i;
}
 
void display(const foo* farr, size_t size, const char* prompt="")
{
    std::cout << prompt << std::endl;
 
    for(size_t i = 0; i < 3; ++i)
    std::cout << farr[i].s << " " << farr[i].i << std::endl;
}
    
int main()
{
    foo farr[3] = {
    foo("foo", 5),
    foo("bar", 2),
    foo("quuz", 10)
    };
 
    display(farr, 3, "Initial array:");
    
    // используем оператор <
    std::sort(farr, farr + 3);
    display(farr, 3, "Sorted with member operator:");
    
    // используем определенную функцию сравнения
    std::sort(farr, farr + 3, comp);
    display(farr, 3, "Sorted with comparison function");
}
res
56 / 9 / 1
Регистрация: 05.04.2010
Сообщений: 143
12.01.2012, 07:24  [ТС]     std::sort. Как сортировать список? (список указателей на объект) #5
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
struct Poet
{
        std::string lname; // фамилия
        std::string fname; // имя
 
    bool operator < (const Poet& second)
    {
        return lname < second.lname;
    }
};
 
void main()
{
        std::list<Poet*> listPoet;
 
        // создам поэтов
        Poet poet0, poet1, poet2;
 
        // заполняем
        poet0.lname = "Esenin";
        poet0.fname = "Sergey";
 
        poet1.lname = "Lermontov";
        poet1.fname = "Michael";
 
        poet2.lname = "Pushkin";
        poet2.fname = "Alexander";
 
        // добавляем поэтов в список
        listPoet.push_back(&poet0);
        listPoet.push_back(&poet1);
        listPoet.push_back(&poet2);
 
       listPoet.sort();
 
        // вывод: Фамилия Имя
        for(std::list<Poet*>::iterator it = listPoet.begin(); it != listPoet.end(); ++it)
                std::cout << (*it)->lname << " " << (*it)->fname << std::endl;
 
        std::cin.get();
}
Ну вот перегрузил оператор <, но он не сортирует указатели
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
12.01.2012, 08:03     std::sort. Как сортировать список? (список указателей на объект) #6
Можно и указатели.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class TItem
{
 ...
};
void Sort(TItem **data, int n)
{
 int **i;
 int **j;
 int *t;
 for (i=Data+n-1; i>Data; --i)
 {
  for (j=i-1; j>=Data; --j)
  {
   if (**i<**j) // Сравнение обратное, если <, то по возрастанию
   {
    t=*i;
    *i=*j;
    *j=t;
   }
  }
 }
}
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
12.01.2012, 08:07     std::sort. Как сортировать список? (список указателей на объект) #7
res, конечно не сортирует, т.к. ты перегрузил оператор < не для указателя на тип (т.к. это сделать уже не получится), а для самого типа. Напиши функцию сравнения, которая будет принимать два указателя, и передавай ее в качестве параметра для sort. И да, list::sort != std::sort

Добавлено через 3 минуты
taras atavin, ты вообще читаешь, что ТС написал? Зачем ему твой пузырек?
res
56 / 9 / 1
Регистрация: 05.04.2010
Сообщений: 143
12.01.2012, 08:15  [ТС]     std::sort. Как сортировать список? (список указателей на объект) #8
Nameless One,
так?
C++
1
2
3
4
5
6
7
8
9
10
11
12
class PoetCompare{
public:
    bool operator() (const Poet *first, const Poet *second) 
    {
         return first->lname < second->lname;
    }
    bool operator() (const Poet &first, const Poet &second)
    {
        return first.lname < second.lname;
    }
 
} compare;
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
12.01.2012, 08:45     std::sort. Как сортировать список? (список указателей на объект) #9
Да, можно так (только для ссылок перегрузка сравнения не нужна)
res
56 / 9 / 1
Регистрация: 05.04.2010
Сообщений: 143
12.01.2012, 19:04  [ТС]     std::sort. Как сортировать список? (список указателей на объект) #10
Не понятно, почему не сортируется по фамилий и имени, вроде бы условие правильное поставил
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
struct Poet
{
        std::string lname; // фамилия
        std::string fname; // имя
};
 
struct Sort
{
public:
    bool operator() (const Poet *first, const Poet *second) 
    {
         return (first->lname < second->lname) && (first->fname < second->fname);
    }
    bool operator() (const Poet &first, const Poet &second)
    {
        return (first.lname < second.lname) && (first.fname < second.fname);
    }
}
void main()
{
        std::list<Poet*> listPoet;
 
        // создам поэтов
        Poet poet0, poet1, poet2;
 
        // заполняем
        poet0.lname = "Esenin";
        poet0.fname = "Sergey";
 
        poet1.lname = "Lermontov";
        poet1.fname = "Michael";
 
        poet2.lname = "Pushkin";
        poet2.fname = "Alexander";
 
        // добавляем поэтов в список
        listPoet.push_back(&poet0);
        listPoet.push_back(&poet1);
        listPoet.push_back(&poet2);
 
       listPoet.sort();
 
        // вывод: Фамилия Имя
        for(std::list<Poet*>::iterator it = listPoet.begin(); it != listPoet.end(); ++it)
                std::cout << (*it)->lname << " " << (*it)->fname << std::endl;
 
        std::cin.get();
}
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
12.01.2012, 22:19     std::sort. Как сортировать список? (список указателей на объект) #11
Цитата Сообщение от res Посмотреть сообщение
listPoet.sort();
А как этот метод узнает, что сравнивать надо оператором (), а не < ?
res
56 / 9 / 1
Регистрация: 05.04.2010
Сообщений: 143
12.01.2012, 22:22  [ТС]     std::sort. Как сортировать список? (список указателей на объект) #12
Цитата Сообщение от Chelioss Посмотреть сообщение
А как этот метод узнает, что сравнивать надо оператором (), а не < ?
Sort poetSort;
ну listPoet.sort(poetSort), просто забыл правильно сюда скопипастить, но суть не меняет
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
12.01.2012, 22:32     std::sort. Как сортировать список? (список указателей на объект) #13
C++
1
 listPoet.sort(Sort());

После закрывающей фигурной скобки } класса и структуры надо ставить ;
Только запутываете нас.

Добавлено через 56 секунд
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
53
54
#include <iostream>
#include <list>
#include <string>
#include <cctype>
using namespace std;
 
struct Poet
{
        std::string lname; // фамилия
        std::string fname; // имя
};
 
struct Sort
{
public:
    bool operator() (const Poet *first, const Poet *second) 
    {
         return (first->lname < second->lname) && (first->fname < second->fname);
    }
    bool operator() (const Poet &first, const Poet &second)
    {
        return (first.lname < second.lname) && (first.fname < second.fname);
    }
};
void main()
{
        std::list<Poet*> listPoet;
 
        // создам поэтов
        Poet poet0, poet1, poet2;
 
        // заполняем
        poet0.lname = "Esenin";
        poet0.fname = "Sergey";
 
        poet1.lname = "Lermontov";
        poet1.fname = "Michael";
 
        poet2.lname = "Pushkin";
        poet2.fname = "Alexander";
 
        // добавляем поэтов в список
        listPoet.push_back(&poet0);
        listPoet.push_back(&poet1);
        listPoet.push_back(&poet2);
 
       listPoet.sort(Sort());
 
        // вывод: Фамилия Имя
        for(std::list<Poet*>::iterator it = listPoet.begin(); it != listPoet.end(); ++it)
                std::cout << (*it)->lname << " " << (*it)->fname << std::endl;
 
        std::cin.get();
}
res
56 / 9 / 1
Регистрация: 05.04.2010
Сообщений: 143
12.01.2012, 22:54  [ТС]     std::sort. Как сортировать список? (список указателей на объект) #14
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
53
struct Poet
{
    std::string lname; // фамилия
    std::string fname; // имя
};
 
struct Sort
{
public:
    bool operator() (const Poet *first, const Poet *second) 
    {
         return (first->lname < second->lname) && (first->fname < second->fname);
    }
    bool operator() (const Poet &first, const Poet &second)
    {
        return (first.lname < second.lname) && (first.fname < second.fname);
    }
};
 
void main()
{
    std::list<Poet*> listPoet;
 
    // создаём 4 поэтов
    Poet poet0, poet1, poet2, poet3;
 
    // заполняем
    poet0.lname = "Beta";
    poet0.fname = "Beta";
 
    poet1.lname = "Alpha";
    poet1.fname = "Alpha";
 
    poet2.lname = "Alpha";
    poet2.fname = "Beta";
 
    poet3.lname = "Beta";
    poet3.fname = "Alpha";
 
    // добавляем поэтов в список
    listPoet.push_back(&poet0);
    listPoet.push_back(&poet1);
    listPoet.push_back(&poet2);
    listPoet.push_back(&poet3);
 
    listPoet.sort(Sort());
 
    // показать всех 
    for(std::list<Poet*>::iterator it = listPoet.begin(); it != listPoet.end(); ++it)
        std::cout << (*it)->lname << " " << (*it)->fname << std::endl;
 
    std::cin.get();
}
Всё тоже самое. Не правильно сортирует
Вывод:
HTML5
1
2
3
4
Alpha Alpha 
Beta Beta
Alpha Beta
Beta Alpha
А должен:
HTML5
1
2
3
4
Alpha Alpha
Alpha Beta
Beta Alpha 
Beta Beta
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.01.2012, 23:16     std::sort. Как сортировать список? (список указателей на объект)
Еще ссылки по теме:

C++ 3 класса: список, стек(как список), очередь(как список)
C++ связный список указателей С++
Отличие std::sort От std::qsort C++

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

Или воспользуйтесь поиском по форуму:
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
12.01.2012, 23:16     std::sort. Как сортировать список? (список указателей на объект) #15
Потому что условие сортировки не правильно.

Добавлено через 15 минут
C++
1
return (first->lname < second->lname) || (first->lname == second->lname && first->fname < second->fname);
Yandex
Объявления
12.01.2012, 23:16     std::sort. Как сортировать список? (список указателей на объект)
Ответ Создать тему
Опции темы

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