Название: Как сделать кратко/красиво Отправлено: Igors от Март 15, 2011, 16:24 Добрый день
Есть структура Код
Теперь надо написать ф-цию Код которая создает из элементов входного mesh вектора CShape * и помещает их в выходной вектор shape. но с одним условием: входные элементы с одинаковым mFriction должны быть "слиты" (с помощью методов Append и Clear) и только одно CShape создано для таких. Примеры: все элементы mesh имеют одинаковый mFriction - значит всего 1 новый элемент добавлен в shape. И наоборот - все mFriction разные - значит для каждого надо создать CShape. Вопрос в том как это сделать красиво/элегантно - у меня получается коряво :) Спасибо Название: Re: Как сделать кратко/красиво Отправлено: m_ax от Март 15, 2011, 17:05 Я бы посмотрел в сторону алгоритма find_if, в сочетании с count_if
Или вот, пожалуй, лучше всего подходит под это дело: http://www.cplusplus.com/reference/algorithm/unique_copy/ Название: Re: Как сделать кратко/красиво Отправлено: Igors от Март 15, 2011, 19:38 Я бы посмотрел в сторону алгоритма find_if, в сочетании с count_if Хммм... "прошу исполнить" :)Или вот, пожалуй, лучше всего подходит под это дело: http://www.cplusplus.com/reference/algorithm/unique_copy/ Название: Re: Как сделать кратко/красиво Отправлено: m_ax от Март 15, 2011, 20:17 Ну вот, например:
Код
Хотя я это не проверял) Название: Re: Как сделать кратко/красиво Отправлено: Igors от Март 15, 2011, 20:42 Хотя я это не проверял) Та вижу что нет :)Пусть первые 2 элемента имеют одинаковый ключ (mFriction). Тогда, если я правильно понимаю, unique_copy поместит в выходной вектор лишь первый из них, второй не будет долит к первому - а должен Название: Re: Как сделать кратко/красиво Отправлено: m_ax от Март 15, 2011, 20:47 Хотя я это не проверял) Та вижу что нет :)Пусть первые 2 элемента имеют одинаковый ключ (mFriction). Тогда, если я правильно понимаю, unique_copy поместит в выходной вектор лишь первый из них, второй не будет долит к первому - а должен Если я правильно понимаю, то доливание одного вектора в другой, если у них одинаковые mFriction можно произвести в myBinaryPredicate... Название: Re: Как сделать кратко/красиво Отправлено: Igors от Март 15, 2011, 20:55 В смысле долит? Этот код создаёт только вектор с указателями на уникальные mFriction.. Он ничё никуда не доливает) Ну а зачем такой вектор нужен? Ведь задача объединить (с помощью Append) подходящие элементы и создать для них одну CShape.Кстати о птичках: если уж создавать вектор уникальных, то не лучше ли сначала отсортировать, а затем один раз вызвать unique_copy (а то увлеклись списыванием :)) Название: Re: Как сделать кратко/красиво Отправлено: m_ax от Март 15, 2011, 21:05 В смысле долит? Этот код создаёт только вектор с указателями на уникальные mFriction.. Он ничё никуда не доливает) Ну а зачем такой вектор нужен? Ведь задача объединить (с помощью Append) подходящие элементы и создать для них одну CShape.Цитировать Кстати о птичках: если уж создавать вектор уникальных, то не лучше ли сначала отсортировать, а затем один раз вызвать unique_copy (а то увлеклись списыванием Улыбающийся) Можно, конечно) Я просто Вашу бдительность проверял)) Название: Re: Как сделать кратко/красиво Отправлено: Igors от Март 15, 2011, 21:26 Можно непосредственно в функции myBinaryPredicate "сливать" данные из одного (a) в другой (b) (с помощью Append), если они равны. Может даже это и будет работать (не знаю), но делать такие "масштабные" действия в ф-ции предназначенной просто для сравнения - никак не гуд. Да и копирование вектора (с последующим resize) хорошего впечатления не производит. Нельзя сделать как-то "через голову", не слишком привлекая мутность STL? Название: Re: Как сделать кратко/красиво Отправлено: m_ax от Март 15, 2011, 21:44 Можно непосредственно в функции myBinaryPredicate "сливать" данные из одного (a) в другой (b) (с помощью Append), если они равны. Может даже это и будет работать (не знаю), но делать такие "масштабные" действия в ф-ции предназначенной просто для сравнения - никак не гуд. Правильно, для большей гибкости. Цитировать Да и копирование вектора (с последующим resize) хорошего впечатления не производит. Нельзя сделать как-то "через голову", не слишком привлекая мутность STL? Да он всё равно локален и разрушится при выходе из функции. Сколько там (в mesh) в среднем элементов планируется держать? Если без этого временного вектора v, то тогда лучше использовать find_if, но это будет медленее и так кратко не думаю что получится. Название: Re: Как сделать кратко/красиво Отправлено: Igors от Март 15, 2011, 22:02 Почему эт? Это всё равно придётся делать) Кстати, зачем тогда придумали ещё и объекты функций? Мда, шансы убедить равны нулю :) Лучше расскажу как я сделалПравильно, для большей гибкости. Код
Название: Re: Как сделать кратко/красиво Отправлено: m_ax от Март 15, 2011, 22:35 Тогда как вариант:
Код
Название: Re: Как сделать кратко/красиво Отправлено: Igors от Март 15, 2011, 23:11 Тогда как вариант: Не въехал с сынтаксысом. Вроде "начальное значение" для accumulate обязательно, значит такКод
Код Но тогда последующая проверка на NULL теряет смысл, cm == *it Название: Re: Как сделать кратко/красиво Отправлено: m_ax от Март 15, 2011, 23:17 Цитировать Не въехал с сынтаксысом. Вроде "начальное значение" для accumulate обязательно, Да, попутал))Вот окончательно: Код
Название: Re: Как сделать кратко/красиво Отправлено: m_ax от Март 15, 2011, 23:25 Это должно быть по быстрее ;)
Название: Re: Как сделать кратко/красиво Отправлено: _govorilka от Март 16, 2011, 07:43 А так:
Код
Это тоже самое, что у тебя но через QHash кода меньше. Можно оптимизировать. Если добавить указатель на CMesh в класс CShape, то второй QHash будет не нужен. Название: Re: Как сделать кратко/красиво Отправлено: Igors от Март 16, 2011, 12:56 Я бы добавил в класс CMesh функцию: Так по задаче нельзя - все Append должны быть применены к CMesh ДО вызова CreateShape (т.е. созданная CShape представляет все слитые данные, изменить их в CShape уже нельзя)Код
Тогда можно написать, что типа этого: Название: Re: Как сделать кратко/красиво Отправлено: _govorilka от Март 16, 2011, 13:24 А так:
Код
Это тоже самое, что у тебя но через QHash кода меньше. Название: Re: Как сделать кратко/красиво Отправлено: Igors от Март 16, 2011, 14:11 А так: А так согласен, намного короче. Там правда mFriction float и после Append надо делать Clear - но не суть. Проходят и др ассоциативные контейнеры, для полноты вариант с std::mapКод Правда запрягается контейнер, но это допустимо/нормально. По ходу дела (конечно это др. задача, но интересно): а если "нечеткое" совпадение ключа? Например нужно сливать CMesh если их mFriction отличается не более чем на заданный epsilon (напр 1.0e-5) Спасибо Название: Re: Как сделать кратко/красиво Отправлено: _govorilka от Март 16, 2011, 14:41 По ходу дела (конечно это др. задача, но интересно): а если "нечеткое" совпадение ключа? Например нужно сливать CMesh если их mFriction отличается не более чем на заданный epsilon (напр 1.0e-5) Насколько я помню у std::map третий параметр в шаблоне - функция, которая она вызывает для сравнения элементов. В STL не силен, точно сказать не могу. В Qt для сравнения двух float есть функция: Код
|