Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
611 / 416 / 151
Регистрация: 11.01.2019
Сообщений: 1,746

std::sort и nan

21.02.2021, 10:16. Показов 1552. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Согласно стандарту nan не сравнимо ни с чем. Как лучше поступить при сортировке массива, где могут быть nan? Тупо скидывать nan в один конец контейнера? Или просто оставлять на месте? Формально это не UB (по крайней мере, прямых указаний я не видел).
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
21.02.2021, 10:16
Ответы с готовыми решениями:

Отличие std::sort От std::qsort
Пишу доклад по программированию, собственно выбрал тему сортировок. вот сейчас хочу расписать отлчиие + и - двух сортировок. но инфу...

std::sort + std::lower_bound
тема такая: есть класс person: class Person{ private: string name_; string adress_; long phone_; есть вектор объектов...

std::sort
Достоинства и недостатки делаю таблицу, достоинств и недостатков std::Sort. собственно, не нащёл нечего про это в википедии

19
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
21.02.2021, 10:26
Цитата Сообщение от jugu Посмотреть сообщение
Тупо скидывать nan в один конец контейнера?
ага, и потом удалить

Добавлено через 4 минуты
nan это же вообще некорректные данные, исключительная ситуация, как они вообще могут появиться в массиве с данными?
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
21.02.2021, 11:00
Цитата Сообщение от jugu Посмотреть сообщение
Согласно стандарту nan не сравнимо ни с чем. Как лучше поступить при сортировке массива, где могут быть nan? Тупо скидывать nan в один конец контейнера? Или просто оставлять на месте? Формально это не UB (по крайней мере, прямых указаний я не видел).
jugu, когда вы сортируете массив, вы получаете упорядоченную последовательность в соответствии с некоторым предикатом. А теперь скажите, как вы назовёте последовательность, которая содержит элементы, значение которых:
Цитата Сообщение от jugu Посмотреть сообщение
не сравнимо ни с чем
?
Информация к размышлению:
/*попытка написать предикат учитывающий присутствие NAN приведёт к развалу предиката*/
1
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
21.02.2021, 13:42
Цитата Сообщение от jugu Посмотреть сообщение
Как лучше поступить при сортировке массива, где могут быть nan? Тупо скидывать nan в один конец контейнера? Или просто оставлять на месте? Формально это не UB (по крайней мере, прямых указаний я не видел).
Тупо скидывай в один конец контейнера, в любой. NaN - это одинаковые числа, просто принимаешь решение - будут они у тебя считаться самыми маленькими, либо самыми большими.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
21.02.2021, 14:36
jugu, NaN не поддерживает корректного сравнения на равенство (являясь частью того или иного типа! - Классический пример сломанной абстракции)) ). А это значит, что контейнер необутых в класс чисел с плавающей точкой станет проблемой для стандартных алгоритмов и контейнеров поддерживающих упорядочивание. Возможно я и ошибаюсь, но не советую связываться с такими структурами. Тут я полностью согласен с _stanislav.
1
611 / 416 / 151
Регистрация: 11.01.2019
Сообщений: 1,746
21.02.2021, 16:58  [ТС]
Ну вот я пока что делаю, как рекомендовал oleg-m1973. Сложность в том, что ситуация рантаймовая.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12943 / 6810 / 1821
Регистрация: 18.10.2014
Сообщений: 17,234
21.02.2021, 20:35
Цитата Сообщение от IGPIGP Посмотреть сообщение
Информация к размышлению:
/*попытка написать предикат учитывающий присутствие NAN приведёт к развалу предиката*/
Верно с точностью "до наоборот".

Предикат не учитывающий присутствие NAN будет вести себя неправильно (не соответствует требованиям Strict Weak Ordering). При этом всегда можно написать предикат, учитывающий присутствие NAN, и все будет в порядке.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
21.02.2021, 23:04
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Верно с точностью "до наоборот".
Но ведь:
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Предикат не учитывающий присутствие NAN будет вести себя неправильно (не соответствует требованиям Strict Weak Ordering). При этом всегда можно написать предикат, учитывающий присутствие NAN, и все будет в порядке.
Это не аргумент. Покажите какой предикат вы напишете для посотроения, скажем, std::set и std::unordered_set.
Моё мнение вполне сходится с:
Цитата Сообщение от _stanislav Посмотреть сообщение
nan это же вообще некорректные данные, исключительная ситуация, как они вообще могут появиться в массиве с данными?
Если нужно зачем-то сохранить количество ошибок пришедших с каким-то потоком или алгоритмом то лучше, создать класс который содержит контейнер нормальных данных и счётчик ошибок.
0
Заблокирован
21.02.2021, 23:46
Цитата Сообщение от IGPIGP Посмотреть сообщение
Но ведь:

Это не аргумент. Покажите какой предикат вы напишете для посотроения, скажем, std::set и std::unordered_set.
Моё мнение вполне сходится с:

Если нужно зачем-то сохранить количество ошибок пришедших с каким-то потоком или алгоритмом то лучше, создать класс который содержит контейнер нормальных данных и счётчик ошибок.
> Покажите какой предикат вы напишете для посотроения, скажем, std::set

C++
1
[](auto l, auto r) noexcept { return std::isnan(l) || (!std::isnan(r) && l < r); }
Теперь покажи в каком месте оно не работает. Вперёд.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.02.2021, 01:27
Цитата Сообщение от cloun1902 Посмотреть сообщение
Вперёд.
cloun1902, не припомню вас в числе своих любимых женщин. Поэтому не повторяйте таких выражений в мой адрес.
Цитата Сообщение от cloun1902 Посмотреть сообщение
Теперь покажи в каком месте оно не работает.
Код ниже показывает как создаётся множество с 11-ю элементами, два из которых nan
Карта чуть получше (8 штук), но тоже выбрала 2 nan из всех. Это логически не консистентное поведение.
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
#include <iostream>
#include <cmath>
#include <algorithm>
#include <set>
#include <map>
using namespace std;
 
int main()
{
    double source[]={nan(""),1,nan(""),2,nan(""), 3,4,nan(""),5,nan(""),0 };
    auto sz=sizeof(source)/sizeof(*source);
 
    auto pred=[](double l, double r) noexcept { return std::isnan(l) || (!std::isnan(r) && l < r); };
    vector<double> vd{source,source+sz};
    cout<<vd.size();
    cout<<endl;
    //pred pr;
    std::sort(vd.begin(),vd.end(), pred );
    for(auto el:vd)cout<<el<<' ';
    cout<<endl;
    set<double, decltype(pred)> sd(vd.begin(),vd.end(),pred);
    cout<<endl;
    for(auto el:sd)cout<<el<<' ';
    cout<<endl;
    cout<<sd.size();
    map<double, int, decltype(pred)> md( pred);
    cout<<"\nmap\n";
    int i(0);
    for(auto el:sd) md[el]=++i ;
    for(auto el:md) cout<<el.first<<' '<<el.second<<endl;
    cout<<endl;
    cout<<md.size();
return 0;
}
Возможно мой MinGW лажает. Но факт есть факт я не искал чего-то днём с огнём.
cloun1902, я высказал своё мнение предварив его словами:
Цитата Сообщение от IGPIGP Посмотреть сообщение
Возможно я и ошибаюсь, но не советую связываться с такими структурами.
Поэтому, я изначально не собирался спорить с кем бы то ни было. Особенно с теми кто привык что-то делать по команде
Цитата Сообщение от cloun1902 Посмотреть сообщение
Вперёд.
полученного не от любимой.

Добавлено через 23 минуты
Кстати если и карту наполнять из вектора (а не из множества)
C++
1
2
3
4
5
int i(0);
for(auto el:vd) md[el]=++i ;
for(auto el:md) cout<<el.first<<' '<<el.second<<endl;
cout<<endl;
cout<<md.size();
то в ней тоже 11 элементов. Но она как и множество показывает лишь 8. Это похоже на срыв итерации но без крэша. Что особенно гадко в качестве глюка. Я проверяю код, но не вижу, где я ошибся. Буду рад, если кто-то покажет.
0
Заблокирован
22.02.2021, 01:30
> cloun1902, не припомню вас в числе своих любимых женщин. Поэтому не повторяйте таких выражений в мой адрес.

Эти нелепые потуги изображать из себя пуританина. К тому же, подкаблучник, ты сейчас тотально спалился.

Но я смотрю, ты хотя бы что-то пытаешься по теме сказать, в отличии от многих других местных. Ok, давай более нейтральные выражения использовать.

> Карта чуть получше (8 штук), но тоже выбрала 2 nan из всех

> Возможно мой MinGW лажает

Это я с равенством лажанул, но суть не меняется:
C++
1
[](double l, double r) noexcept { return !std::isnan(r) && (std::isnan(l) || l < r); };
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
11
nan nan nan nan nan 0 1 2 3 4 5 
 
nan 0 1 2 3 4 5 
7
map
nan 1
0 2
1 3
2 4
3 5
4 6
5 7
 
7
> я изначально не собирался спорить с кем бы то ни было

Ну это отговорки. Не хочешь - не спорь, заставлять кого-то я не желаю.

Я предполагаю, что человеку интересно узнать чужое мнение по вопросам, которые он освещает в своих постах, например. И если моё мнение отличается, я задаю вопрос или возражаю. Всё просто.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.02.2021, 01:41
Цитата Сообщение от cloun1902 Посмотреть сообщение
Я предполагаю, что человеку интересно узнать чужое мнение по вопросам, которые он освещает в своих постах, например. И если моё мнение отличается, я задаю вопрос или возражаю. Всё просто.
Ну у меня тут есть некоторая история. Вы можете почитать, если хотите. Когда человек выражает мнение, а не командует куда ему лучше вперед или взад и не даёт оценок типа
Цитата Сообщение от cloun1902 Посмотреть сообщение
Эти нелепые потуги изображать из себя пуританина. К тому же, подкаблучник, ты сейчас тотально спалился.
демонстрирующие воспитание, я обсуждаю. Как видите на собственном примере, я не так уж подвержен рвотному рефлексу.
Цитата Сообщение от cloun1902 Посмотреть сообщение
Это я с равенством лажанул
Не только. NaN не поддерживает сравнение на равенство одного и того же объекта. То есть:
C++
1
2
double nana(nan(""));
cout<<(nana == nana);//напечатает ноль
Поэтому вам и всем другим, кто желает работать с этим объектом под флагом любого плавающего типа, желаю успеха. Я бы не стал.
0
Заблокирован
22.02.2021, 02:01
Цитата Сообщение от IGPIGP Посмотреть сообщение
double nana(nan(""));
cout<<(nana == nana);//напечатает ноль
Ну нафиг ты опять старую песню запеваешь? Речь была про сравнение предикатом и возможность его написания. Факт, что можно облажаться на этом, никто не отрицал.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.02.2021, 02:09
cloun1902, я своё мнение высказал. Написать можно всё. Ваш первый вариант ведь работает? Другой вопрос как. Но для меня одно неотделимо от другого.
Цитата Сообщение от старый советский анекдот
Одна из лысенко подобных лабораторий выбила ассигнования на превращение дерьма в сливочное масло. Через год бурной деятельности голос с грузинским акцентом в трубке спрашивает: "-Ну как продвигаются исследования, товарищ?". Вспотевший завлаб вскакивает по стойке смирно и заикаясь отвечает. "-Результаты обнадёживают: - На хлеб уже мажется. Осталось устранить запах..."
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12943 / 6810 / 1821
Регистрация: 18.10.2014
Сообщений: 17,234
22.02.2021, 03:36
Цитата Сообщение от IGPIGP Посмотреть сообщение
Покажите какой предикат вы напишете для посотроения, скажем, std::set и std::unordered_set.
На этот вопрос уже ответил oleg-m1973 в сообщении #4. Распознаем NaN путем вызова функции std::isnan, после чего интерпретируем все NaN так, как нам больше нравится. Например, скидываем в любое место диапазона.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.02.2021, 04:07
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
На этот вопрос уже ответил oleg-m1973 в сообщении #4.
??
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Распознаем NaN путем вызова функции std::isnan, после чего интерпретируем все NaN так, как нам больше нравится. Например, скидываем в любое место диапазона.
Предикат, это не алгоритм работы с последовательностью (придуманный для себя). Это способ сравнения. Его нужно выразить и передать потребителю. Вы не сможете объяснить библиотечной функции как ей быть, а шефу, что вы хотели как лучше. Повторяю: покажите предикат. Может и есть решение. Просто я его не знаю.
Сортировка обычно делается для дальнейшей передачи в алгоритмы сокращающие асимптотику до логарифмической за счёт применения бинарной логики. Поэтому я и задал вопрос. Недавно была тема о циклическом сдвиге где удобно было применить std::equal. Вы тогда назвали его "тяжелым.".
Является ли одна строка циклическим сдвигом другой?
А мне он таковым не кажется.
C++
1
2
3
4
5
6
7
8
9
10
11
///vector : nan, nan, nan, nan, nan, 0, 1, 2, 3, 4, 5
 
cout<<"\nequal "<<equal(vd.begin(), vd.begin()+2, vd.begin(), pred);// равны а предикат неверен см выше))
 
//сортируем с новым предикатом
auto pred2=[](double l, double r) noexcept { return !std::isnan(r) && (std::isnan(l) || l < r); };
std::sort(vd.begin(),vd.end(), pred2 );
cout<<"\nvector\n";
for(auto el:vd)cout<<el<<' ';
cout<<endl;
cout<<"\nequal "<<equal(vd.begin(), vd.begin()+2, vd.begin(), pred2);//не равны а предикат "верен"
Если это то что ожидается от сортированной ( в кавычках, в данном разе ) последовательности, то это мне непонятно. Но предиката я так и не увидел.
Ладно. Иду спать. А то много ошибок уже. Завтра если будет желание - продолжим. Я у себя не предвижу)
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.02.2021, 13:23
Да) Ночью надо спать. Предикат на равенство нужно же. Если как-то так:
C++
1
     auto pred_eq=[](double l, double r) noexcept { return (std::isnan(r) && std::isnan(l)) || (l==r); };
то, вроде, работает. Нужно ещё поглядеть варианты. Если, что найду напишу)
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38180 / 21115 / 4307
Регистрация: 12.02.2012
Сообщений: 34,722
Записей в блоге: 14
22.02.2021, 13:51
cloun1902, предупреждаю: добьешься полной блокировки. Не надо хамить.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.02.2021, 16:26
Вот кое-что:
C++
1
2
3
4
5
dead_it=lower_bound(vd.begin(), vd.end(), nan(""), pred);//старый предикат
cout<<"\ndead_lb "<<( dead_it-vd.begin() )<<' '<<*dead_it ; //5 0 - "старый" отрабатывает верно 
 
dead_it=lower_bound(vd.begin(), vd.end(),  nan(""), pred2);//
cout<<"\ndead_lb "<<( dead_it-vd.begin() )<<' '<<*dead_it ;// 0 nan- новый, который работает c set и map лажает
Добавлено через 2 часа 4 минуты
Н-нет) Второй работает таки верно. Первый ошибается. Может второй вариант предиката, это и есть решение. Нужно ещё по проверять. И всё же не стал бы я рисковать.
0
611 / 416 / 151
Регистрация: 11.01.2019
Сообщений: 1,746
22.02.2021, 22:25  [ТС]
del.. Устал после рабочего дня, уже не вижу разницы между r и l ))
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
22.02.2021, 22:25
Помогаю со студенческими работами здесь

std::sort()
Доброго времени суток! Есть некая структура: struct member { int latency; std::vector&lt;int&gt;child; };

std::sort
1. в std::sort реализован introsort? 2. почему std::sort работает во много раз быстрей в сборке Release чем в Debug. С чем это связано? ...

std::sort и компаратор
Доброго времени суток. Есть два массива: Struct Model { float x; float y; }; std::vector &lt;Model&gt; models;

algorithm std::sort
Почему так делать нельзя? #include &lt;algorithm&gt; using namespace std; class T { private: int arr;

std::sort с лямбдой
Здравствуйте! Есть такая структура: struct FNote // Falling note { enum class Type { Non, // никакой или Accord, ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru