Здравствуйте!
Столкнулся с такой проблемой при сортировке списка. %-)
Есть структура:
struct PackObject
{
bool Placed; // Помещен ли на карту текстур
string SceneAlias; // Имя сцены
string TexFile;
int TexWidth;
int TexHeight;
bool TexMipMap;
bool TexGray;
bool TexJpeg;
string ObjAlias; // Имя родительского объекта
TRect ObjRect;
int AniFrameNumber; // Порядковый номер кадра
int AniFrames;
int AniFramesPerLine;
};
А также контейнер list, элемент которого задан соответсвующей структурой.
Требуется отсортировать данный контейнер наполненый некой информацией по
1) Имени сцены "SceneAlias"
2) Аттрибутам текстуры TexMipMap;TexGray;TexJpeg;
3) По размерам текстуры TexWidth; TexHeight;
ЭТО НЕ ОЗНАЧЕТ СДЕЛАТЬ 3 РАЗНЫХ СОРТИРОВКИ!!! ЭТО ЗНАЧИТ ЧТОБЫ СВЕРХУ ВНИХ ОБЪЕКТЫ БЫЛИ ОТСОРТИРОВАННЫ ПО ДАННЫМ КРИТЕРИЯМ!
Т.е. номера пунктов 3-ех аттрибутов являются как бы приоритетами (важностью) 1) 2) 3)
[size=4]НО ПРОБЛЕМА НЕ В ТОМ КАК ОТСОРТИРОВАТЬ!!!!!![/size]
Проблема заключается в том что функция PREDICATE для списка LIST отказывается сортировать корректно его элементы!
Вот один из испробованных мною вариантов PREDICATE функции (до этого я пытался делать эту функцию разными способами в том числе перегрузкой скобок () и перегрузкой знака ">" )
bool PackPred(PackObject &obj1, PackObject &obj2)
{
bool result = false;
if (sortmem_apartscenes)
{
// Cортируем по имени сцены в алфавитном порядке
string str1 = obj1.SceneAlias;
string str2 = obj2.SceneAlias;
size_t minlen = (str1.length() > str2.length()) ? str2.length() : str1.length();
for (size_t i = 0; i < minlen; i++)
{
if (str1[i] > str2[i])
{
result = true;
break;
}
}
if (str1.length() > str2.length()) result = true;
}
// Объекты одной сцены сортируем по параметрам текстуры
if (sortmem_apartjpeg)
{
if ((obj1.TexJpeg) && (!obj2.TexJpeg)) result = true;
}
if ((obj1.TexMipMap) && (!obj2.TexMipMap)) result = true;
if ((obj1.TexGray) && (!obj2.TexGray)) result = true;
// Возвращаем результат сравнения размеров
int width1 = obj1.TexWidth;
int height1 = obj1.TexHeight;
int width2 = obj2.TexWidth;
int height2 = obj2.TexHeight;
// Хотябы один размер был больше
if ( ((width1 > width2) && (width1 > height2)) ||
((height1 > width2) && (height1 > height2)) ) result = true;*/
return result;
};
Пояснения!
1) Переменные bool sortmem_apartscenes и bool sortmem_apartjpeg являются глобальными. Увы от них избавится не вышло а добавлять еще 3 варианта сортировки было бы некрасиво. Перед сортировкой эти переменные устанавливаются в нужное значение.
2) Переменные TexJpeg TexMipMap и TexGray пробывал сравнивать знаком > но все равно безрезультатно.
3) bool result — это якобы варинт написания функции как в Дельфи. Просто во время отладки я заметил очень странную весчь. Оказывается в PREDICATE функции при к примеру "return true" не происходит выход из функции а продолжает обрабатывать всею последующие команды =-O Я не понимать что это за баг?
4) Если проверять по отдельности то разделив на 3-и блока всю функцию сортировки
— мы получим что 1-ый блок с сортировкой по алфавиту, не выполняется (хотя список элементов string успешно сортирует имена файлов но только в другом участке в другом контейнере в моей работе)
— 2 блок кода выполняется только отдельно к примеру только сортировка по JPEG аттрибуту.
— 3 блок сортироки по размерам блестяще выполняется.
ПРИТОМ! Если по всем 3 блокам одновременно я пытаюсь сортировать данный список то у меня получается что
1) По именам сцен сортирует но имена сцен и без того изначально были уже в отсортированном виде еще при добавлении в список элементов (отсортировать в обратном порядке при изменении знака > на знак < ничего не меняется но если блок убрать то порядок теряется)
2) Также сортирует по именьшению сверху вниз размеров текстур.
Аттрибуты же текстур остаются в произвольном порядке....
Как это можно вылечить. Может кто уже сталкивался со сложными сортировками?
Re: (STL LIST SORT) Сортировка по некольким критериям
Здравствуйте, tatsu, Вы писали:
T>ЭТО НЕ ОЗНАЧЕТ СДЕЛАТЬ 3 РАЗНЫХ СОРТИРОВКИ!!! ЭТО ЗНАЧИТ ЧТОБЫ СВЕРХУ ВНИХ ОБЪЕКТЫ БЫЛИ ОТСОРТИРОВАННЫ ПО ДАННЫМ КРИТЕРИЯМ!
T>Т.е. T>1) Scene1 JPEG MIPMAP GRAY 1000x900 T>2) Scene1 JPEG MIPMAP GRAY 800x900 T>3) Scene1 JPEG MIPMAP 1000x900 T>4) Scene1 JPEG MIPMAP 700x700 T>5) Scene1 JPEG GRAY 1500x1500 T>6) Scene1 JPEG GRAY 700x700 T>7) Scene1 JPEG 2000x700 T>8) Scene1 JPEG 1000x700 T>8 ) Scene1 100x100 T>9 ) Scene1 100x50 T>10) Scene2 .......
T>Т.е. номера пунктов 3-ех аттрибутов являются как бы приоритетами (важностью) 1) 2) 3)
В вашей функции есть ошибка. Продолжать проверку по след. приоритетному атрибуту стоит только если предидущик атрибуты были равны.
Попробуйте так:
bool PackPred(PackObject &obj1, PackObject &obj2)
{
if (sortmem_apartscenes)
{
string str1 = obj1.SceneAlias;
string str2 = obj2.SceneAlias;
if (str1 > str2) {
return true; //немедленый выход, если больше
}
if (str1 < str2) {
return false; //немедленый выход, если меньше
}
}
//если равно то делаем проверку по след. параметруif (sortmem_apartjpeg)
{
// Объекты одной сцены сортируем по параметрам текстурыif ((obj1.TexJpeg) && (!obj2.TexJpeg)) {
return true; //немедленый выход, если больше
}
if ((!obj1.TexJpeg) && (obj2.TexJpeg)) {
return false; //немедленый выход, если меньше
}
}
//если равно то делаем проверку по след. параметруif ((obj1.TexMipMap) && (!obj2.TexMipMap)) {
return true; //немедленый выход, если больше
}
if ((!obj1.TexMipMap) && (obj2.TexMipMap)) {
return false; //немедленый выход, если меньше
}
//если равно то делаем проверку по след. параметруif ((obj1.TexGray) && (!obj2.TexGray)) {
return true; //немедленый выход, если больше
}
if ((!obj1.TexGray) && (obj2.TexGray)) {
return false; //немедленый выход, если меньше
}
//если равно то делаем проверку по след. параметру
// Возвращаем результат сравнения размеровint width1 = obj1.TexWidth;
int height1 = obj1.TexHeight;
int width2 = obj2.TexWidth;
int height2 = obj2.TexHeight;
// Хотябы один размер был большеif ( ((width1 > width2) && (width1 > height2)) ||
((height1 > width2) && (height1 > height2)) )
return true; //немедленый выход, если больше
//и т.д.return false;
};
Re: (STL LIST SORT) Сортировка по некольким критериям
T>Требуется отсортировать данный контейнер наполненый некой информацией по T>1) Имени сцены "SceneAlias" T>2) Аттрибутам текстуры TexMipMap;TexGray;TexJpeg; T>3) По размерам текстуры TexWidth; TexHeight;
А оно потом удобно будет такой код сопровождать? Отлаживать? Попробуй KISS.
Здравствуйте, VoidEx, Вы писали:
VE>Здравствуйте, tatsu, Вы писали:
VE>Вам таки надо написать правильно предикат и всё, если я правильно понял. VE>Что-то типа: VE>
Кажется это то что именно нужно. Я еще не пробывал но по реакции своего мозга на ваш ответ дкмаю что именно это и было пакой в спицах велосипеда
Преогромнейшие благодарности в Ваш адрес! Вы бог! Спасибо! Пойду исправляться.
И единственный вопрос который тут же возник..
Я уже в сообщении писал что "return" при отладке почемуто не вызывал мгновенный выход из функции сравнения PREDICATE
Вы же привели код где как разтаки и используются return для мгновенного выхода.. Как быть.. Это глюк отладки или особенности использования PREDICATE функции может быть вы подскажите? Огромное спасибо еще раз!
Re[2]: (STL LIST SORT) Сортировка по некольким критериям
Спасибо но кажется ошибку уже нашли.
А насчет новейших технологий мне пока еще рано..
Мне пока еще учить и учить основы STL и расти расти большим))
Boost обязательно буду постигать а пока для меня это матерные слова Х))
Все равно большое спасибо за направление и советы.. буду учится
Re[2]: (STL LIST SORT) Сортировка по некольким критериям
Здравствуйте, tatsu, Вы писали:
T>Кажется это то что именно нужно. Я еще не пробывал но по реакции своего мозга на ваш ответ дкмаю что именно это и было пакой в спицах велосипеда
T>Преогромнейшие благодарности в Ваш адрес! Вы бог! Спасибо! Пойду исправляться.
T>И единственный вопрос который тут же возник.. T>Я уже в сообщении писал что "return" при отладке почемуто не вызывал мгновенный выход из функции сравнения PREDICATE T>Вы же привели код где как разтаки и используются return для мгновенного выхода.. Как быть.. Это глюк отладки или
особенности использования PREDICATE функции может быть вы подскажите? Огромное спасибо еще раз!
Рад помочь.
А на счёт return — вообще, философия програмирования не любит таких "немедленных" return-ов, но если же он используется, то работать будет всегда =). Данная задача это позволяет, и даже приветствует, но надо стараться писать код с одним выходом и одним входом =)
Удачи!
Re[3]: (STL LIST SORT) Сортировка по некольким критериям
Здравствуйте, tatsu, Вы писали:
T>Кажется это то что именно нужно. Я еще не пробывал но по реакции своего мозга на ваш ответ дкмаю что именно это и было пакой в спицах велосипеда
T>Преогромнейшие благодарности в Ваш адрес! Вы бог! Спасибо! Пойду исправляться.
T>И единственный вопрос который тут же возник.. T>Я уже в сообщении писал что "return" при отладке почемуто не вызывал мгновенный выход из функции сравнения PREDICATE T>Вы же привели код где как разтаки и используются return для мгновенного выхода.. Как быть.. Это глюк отладки или особенности использования PREDICATE функции может быть вы подскажите? Огромное спасибо еще раз!
return вызывает деструкторы всех инициализированных локальных объектов.