С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.93/15: Рейтинг темы: голосов - 15, средняя оценка - 4.93
0 / 0 / 0
Регистрация: 15.05.2012
Сообщений: 200

перегрузка оператора operator< для сортировки

20.01.2020, 18:08. Показов 3148. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Никак не могу понять почему он не может отсортировать map (строка 123) правильно.
operator< на строке 60



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
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include <exception>
#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <sstream>
#include <string>
 
using namespace std;
 
class Date {
public:
    int getYear() const { return year; }
    int getMonth() const { return month; }
    int getDay() const { return day; }
    Date() {}
    Date(int yy, int mm, int dd)
    {
        if (mm < 1 || mm > 12)
            throw runtime_error("Month value is invalid: " + to_string(mm));
        if (dd < 1 || dd > 31)
            throw runtime_error("Day value is invalid: " + to_string(dd));
        year = yy;
        month = mm;
        day = dd;
    }
 
private:
    int year;
    int month;
    int day;
};
 
istream& operator>>(istream& ist, Date& date)
{
    if (ist)
        if (!ist.eof()) {
            string DATE;
            ist >> DATE;
            stringstream ss(DATE);
            int yy, mm, dd;
            char ch0 = '.', ch1 = '.';
            ss >> yy >> ch0 >> mm >> ch1 >> dd;
            if (ch0 != '-' || ch1 != '-' || !ss.eof())
                throw runtime_error("Wrong date format: " + DATE);
            else
                date = { yy, mm, dd };
        }
    return ist;
}
 
ostream& operator<<(ostream& ost, const Date& date)
{
    ost << setw(4) << setfill('0') << date.getYear() << '-'
        << setw(2) << date.getMonth() << '-'
        << setw(2) << date.getDay();
    return ost;
}
 
bool operator<(const Date& lhs, const Date& rhs)
{
    if (lhs.getYear() < rhs.getYear())
        return true;
    else if (lhs.getMonth() < rhs.getMonth())
        return true;
    else if (lhs.getDay() < rhs.getDay())
        return true;
    return false;
}
 
bool operator>(const Date& lhs, const Date& rhs)
{
    return !(lhs < rhs);
}
 
bool operator==(const Date& lhs, const Date& rhs)
{
    if (lhs.getYear() == rhs.getYear() && lhs.getMonth() == rhs.getMonth() && lhs.getDay() == rhs.getDay())
        return true;
    return false;
}
 
void PrintSet(const Date& date, const set<string> events)
{
    for (const auto& item : events)
        cout << date << " " << item << endl;
}
 
class Database {
public:
    Database() {}
    void AddEvent(const Date& date, const string& event)
    {
        db[date].insert(event);
    }
    bool DeleteEvent(const Date& date, const string& event)
    {
        bool check = db[date].find(event) != db[date].end();
        if (check == true) {
            db[date].erase(db[date].find(event));
            return true;
        }
        return false;
    }
    int DeleteDate(const Date& date)
    {
        int events = db[date].size();
        db[date].clear();
        return events;
    }
    void Find(const Date& date)
    {
        for (auto& item : db[date])
            cout << item << endl;
    }
    void Print()
    {
        for (const auto& item : db)
            PrintSet(item.first, item.second);
    }
 
private:
    map<Date, set<string>> db;
};
 
int main()
{
    Database db;
    string command;
    while (getline(cin, command)) {
        try {
            stringstream ss(command);
            string order, event;
            Date date;
            ss >> order >> date >> event;
            if (order == "Add")
                db.AddEvent(date, event);
            else if (order == "Find")
                db.Find(date);
            else if (order == "Del" && event.size() > 0) {
                bool check = db.DeleteEvent(date, event);
                if (check == true)
                    cout << "Deleted successfully" << endl;
                else
                    cout << "Event not found" << endl;
            } else if (order == "Del") {
                int N = db.DeleteDate(date);
                cout << "Deleted " << N << " events" << endl;
            } else if (order == "Print")
                db.Print();
            else if (command.size() > 0)
                throw runtime_error("Unknown command: " + order);
 
        } catch (exception& e) {
            cout << e.what() << endl;
        }
    }
    return 0;
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
20.01.2020, 18:08
Ответы с готовыми решениями:

Перегрузить operator<<() для шаблонного класса (перегрузка оператора вывода)
Здравствуйте. Перегружаю оператор вывода для шаблонного класса. using namespace std; template &lt;class Element&gt; class List { ...

Перегрузка оператора operator+
для того , чтобы перегрузить унарный оператор + в примере obj1=obj2+10 для обьектов myclass возможно использовать а)френд функцию,...

Перегрузка оператора сравнения ( no match for 'operator==' )
Приветствую! У меня было задание в институте реализовать класс &quot;Вектор &quot; с соответствующими перегрузками операторов. Все шло по маслу до...

20
20.01.2020, 18:10

Не по теме:

Цитата Сообщение от EvilingDark Посмотреть сообщение
Никак не могу понять почему он не может отсортировать map
самое бесполезное занятие сортировать ассоциативный контейнер

0
0 / 0 / 0
Регистрация: 15.05.2012
Сообщений: 200
20.01.2020, 18:14  [ТС]
Цитата Сообщение от AndryS1 Посмотреть сообщение
самое бесполезное занятие сортировать ассоциативный контейнер
Что-то я не понял, map это же бинарное дерево? Оно должно автоматически сортировать при добавлении элементов
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
20.01.2020, 18:21
EvilingDark, попробуй добавить const для this:
C++
1
bool operator<(const Date& lhs, const Date& rhs) const;
0
0 / 0 / 0
Регистрация: 15.05.2012
Сообщений: 200
20.01.2020, 18:32  [ТС]
Цитата Сообщение от _stanislav Посмотреть сообщение
bool operator<(const Date& lhs, const Date& rhs) const;
Не работает
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
20.01.2020, 18:47
Цитата Сообщение от EvilingDark Посмотреть сообщение
Не работает
точку останова поставь внутрь него. Как ты узнал что у тебя не сортирует map?

Добавлено через 42 секунды
походи отладчиком по коду.
0
0 / 0 / 0
Регистрация: 15.05.2012
Сообщений: 200
20.01.2020, 18:47  [ТС]
Цитата Сообщение от _stanislav Посмотреть сообщение
Как ты узнал что у тебя не сортирует map?
Ну по выводу. Печать на 116 строке и 83
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
20.01.2020, 18:49
EvilingDark,

C++
1
#include <tuple>
C++
1
2
3
4
bool operator<(const Date& lhs, const Date& rhs)
{
    return std::tie(lhs.getYear(), lhs.getMonth(), lhs.getDay()) < std::tie(rhs.getYear(), rhs.getMonth(), rhs.getDay());
}
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
20.01.2020, 18:54
Цитата Сообщение от EvilingDark Посмотреть сообщение
Ну по выводу
сортирует же. или тебе нужно в другую сторону? тогда больше и меньше поменяй местами в operator<
0
0 / 0 / 0
Регистрация: 15.05.2012
Сообщений: 200
20.01.2020, 19:05  [ТС]
Цитата Сообщение от _stanislav Посмотреть сообщение
сортирует же?
Я вижу что сортирует, но он сортирует неправильно


Цитата Сообщение от DrOffset Посмотреть сообщение
return std::tie(lhs.getYear(), lhs.getMonth(), lhs.getDay()) < std::tie(rhs.getYear(), rhs.getMonth(), rhs.getDay());
Не работает
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
20.01.2020, 19:14
Цитата Сообщение от EvilingDark Посмотреть сообщение
Я вижу что сортирует, но он сортирует неправильно
а как правильно, по возрастанию?
C++
1
2
3
4
5
6
7
8
9
10
bool operator<(const Date& lhs, const Date& rhs)
{
    if (lhs.getYear() > rhs.getYear())
        return true;
    else if (lhs.getMonth() > rhs.getMonth())
        return true;
    else if (lhs.getDay() > rhs.getDay())
        return true;
    return false;
}
Добавлено через 45 секунд
C++
1
return std::tie(lhs.getYear(), lhs.getMonth(), lhs.getDay()) > std::tie(rhs.getYear(), rhs.getMonth(), rhs.getDay());
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
20.01.2020, 19:17
Цитата Сообщение от EvilingDark Посмотреть сообщение
Не работает
Не верю
А вообще: критерии сортировки в студию.
0
0 / 0 / 0
Регистрация: 15.05.2012
Сообщений: 200
20.01.2020, 19:19  [ТС]
Цитата Сообщение от _stanislav Посмотреть сообщение
а как правильно, по возрастанию?
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
//вывод
0001-03-10 ev13
0001-04-10 ev14
0001-05-10 ev15
0-10-10-10 ev10 //неправильно
0001-07-10 ev17
0004-10-10 ev4
0005-10-10 ev10
0005-10-10 ev5
0006-10-10 ev6
0008-10-10 ev8
0010-10-10 ev10
0010-10-11 ev10
0011-10-10 ev10 //неправильно
0010-11-10 ev10
 
//должно быть
0-10-10-10 ev10
0001-03-10 ev13
0001-04-10 ev14
0001-05-10 ev15
0001-07-10 ev17
0004-10-10 ev4
0005-10-10 ev10
0005-10-10 ev5
0006-10-10 ev6
0008-10-10 ev8
0010-10-10 ev10
0010-10-11 ev10
0010-11-10 ev10
0011-10-10 ev10
Добавлено через 39 секунд
Цитата Сообщение от DrOffset Посмотреть сообщение
Не верю
А вообще: критерии сортировки в студию.
Посмотрите последний мой скриншот
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12931 / 6799 / 1820
Регистрация: 18.10.2014
Сообщений: 17,211
20.01.2020, 19:19
Цитата Сообщение от EvilingDark Посмотреть сообщение
Никак не могу понять
Операторы сравнения для std::map должны удовлетворять требованиям strict weak ordering. Ваш оператор

Цитата Сообщение от EvilingDark Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
bool operator<(const Date& lhs, const Date& rhs)
{
    if (lhs.getYear() < rhs.getYear())
        return true;
    else if (lhs.getMonth() < rhs.getMonth())
        return true;
    else if (lhs.getDay() < rhs.getDay())
        return true;
    return false;
}
этим требованиям не удовлетворяет.

А частности, если (a < b) == true, то (b < a) должно быть заведомо равно false. Смотрим на вашу функцию сравнения. Берем a = { 1999, 12, 1 }, b = { 2000, 10, 1 }. Получаем (a < b) == true и (b < a) == true. Это уже явная чушь.

Даже вот это

Цитата Сообщение от EvilingDark Посмотреть сообщение
C++
1
2
3
4
bool operator>(const Date& lhs, const Date& rhs)
{
    return !(lhs < rhs);
}
уже грубое нарушение этих требований. С каких это пор оператор > стал отрицанием оператора <???
0
0 / 0 / 0
Регистрация: 15.05.2012
Сообщений: 200
20.01.2020, 19:22  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
уже грубое нарушение этих требований. С каких это пор оператор > стал отрицанием оператора <???
Это все Страуструп, это из его учебника. А почему так нельзя?

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
strict weak ordering
А есть на русском прочитать об этом?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12931 / 6799 / 1820
Регистрация: 18.10.2014
Сообщений: 17,211
20.01.2020, 19:25
Цитата Сообщение от EvilingDark Посмотреть сообщение
А почему так нельзя?
"Так нельзя" уже очевидно потому, что (a < b) == true и (b < a) == true противоречит элементарной логике.

Также, отрицанием оператора < очевидно является оператор >=, а не оператор >.
0
0 / 0 / 0
Регистрация: 15.05.2012
Сообщений: 200
20.01.2020, 19:28  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
"Так нельзя" уже очевидно потому, что (a < b) == true и (b < a) == true противоречит элементарной логике.
Не понял если a<b == false, то тогда !(a<b) == true, где тут противоречия?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12931 / 6799 / 1820
Регистрация: 18.10.2014
Сообщений: 17,211
20.01.2020, 19:31
См. "строгое отношение частичного порядка" например здесь: https://neerc.ifmo.ru/wiki/ind... 0%BA%D0%B0

Добавлено через 1 минуту
Цитата Сообщение от EvilingDark Посмотреть сообщение
Не понял если a<b == false, то тогда !(a<b) == true, где тут противоречия?
(5 < 5) == false. Из этого вы делаете вывод, что (5 > 5) == true? Вы не видите здесь противоречия?
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
20.01.2020, 19:32
Цитата Сообщение от EvilingDark Посмотреть сообщение
Не работает
Да, действительно так не будет работать. Подумал у вас там ссылки.
Но вы могли бы написать, что у вас ошибка компиляции, а не обезличенное "не работает".

Попробуйте так:
C++
1
2
3
4
bool operator<(const Date& lhs, const Date& rhs)
{
    return make_tuple(lhs.getYear(), lhs.getMonth(), lhs.getDay()) < make_tuple(rhs.getYear(), rhs.getMonth(), rhs.getDay());
}
1
0 / 0 / 0
Регистрация: 15.05.2012
Сообщений: 200
20.01.2020, 19:46  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
return make_tuple(lhs.getYear(), lhs.getMonth(), lhs.getDay()) < make_tuple(rhs.getYear(), rhs.getMonth(), rhs.getDay());
Классная штука, теперь правильно сортирует
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.01.2020, 19:46
Помогаю со студенческими работами здесь

Перегрузка оператора operator+() в пользовательском классе (сложение строк)
Хотел научить класс складывать строки, но на моменте освобождения памяти temp происходит ошибка. Поля класса: char* Str, int length...

Составить программы для пузырьковой сортировки и сортировки посредством выбора с применением оператора while
Доброго времени суток, очень нужна ваша помощь в решении данной проблемы, буду бесконечно благодарен. Составить программы для пузырьковой...

Перегрузка operator= для очереди
Надо присвоить очереди i2 значения i, не пойму, вообще правильно ли делаю? template&lt;class T&gt; queue&lt;T&gt;&amp;...

Перегрузка operator+ для массивов
Здравствуйте. Мне надо решить следующую задачу: сложить два массива в один, используя перегрузку операторов(перегрузить operator+). У...

Перегрузка operator* для векторов
Подскажите пожалуйста, как перегрузить * − умножение векторов (a*b для всех i)?


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru