![]() |
|
Модераторы: Snowy, MetalFan, bems, Poseidon |
![]()
|
|
| Keeper89 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2580 Регистрация: 26.2.2009 Репутация: 9 Всего: 58 |
Доброго времени суток.
Имеется динамический массив целых чисел достаточно большой размерности (например, 100 столбцов х 100 строк). Как грамотнее реализовать сортировку по выбранному столбцу по убыванию или возрастанию? Это сообщение отредактировал(а) Keeper89 - 4.2.2010, 17:11 |
|||
|
||||
| ~FoX~ |
|
|||
![]() НЕ рыжий!!! ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2819 Регистрация: 8.10.2003 Где: Зеленоград Репутация: 5 Всего: 68 |
Keeper89, Ну на таких величинах прекрасно работает быстрый сорт (быстродействие O(n log n)) ... http://algolist.ru/sort/quick_sort.php
|
|||
|
||||
| Keeper89 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2580 Регистрация: 26.2.2009 Репутация: 9 Всего: 58 |
~FoX~, а что если использовать встроенные классы типа TList или TObjectList? В них уже есть реализация быстрой сортировки.
|
|||
|
||||
| Keeper89 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2580 Регистрация: 26.2.2009 Репутация: 9 Всего: 58 |
Да, и получается нужно во внутреннем цикле соответственно менять элементы столбцов, которые не сортируются?
|
|||
|
||||
| ~FoX~ |
|
||||
![]() НЕ рыжий!!! ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2819 Регистрация: 8.10.2003 Где: Зеленоград Репутация: 5 Всего: 68 |
На счет Tlist и TObjectList не припомню что бы там сортировка хоть какая то была, А вот TStringList именно быстрым сортится... Только критерий там один - по первому символу.... Т.е. в твоем случае только по первому столбцу
Придется, но это не накладно... Ну относительно алгоритма сортировки по крайней мере |
||||
|
|||||
| Frees |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2233 Регистрация: 2.12.2005 Где: Екатеринбург Репутация: 16 Всего: 54 |
Функцию сравнения можно свою написать и сортировать как захочешь.. -------------------- Кольцов Виктор Владимирович |
|||
|
||||
| artsb |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2280 Регистрация: 17.7.2007 Где: центр Вселенной Репутация: 1 Всего: 64 |
Можно сделать так: Загнать первый столбец, например в TStringList. Написать свою функцию сравнения, которая возвращает -1 если нужно поменять местами объекты и 1 или 0 в противном случае. Помимо этого, сделать проверку: если возвращается -1, тогда "вручную" поменять местами элементы всех столбцов. Конечно, нельзя сказать, что всё это будет работать очень быстро. Но зато удовлетворяет твоим требованиям
Это сообщение отредактировал(а) artsb - 5.2.2010, 09:07 -------------------- Чем отличается умный человек от мудрого? Умный - выпутается из любой ситуации. Мудрый - просто в неё не попадёт. |
||||
|
|||||
| bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 18 Всего: 88 |
-------------------- Обижено школьников: 8 |
|||
|
||||
| artsb |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2280 Регистрация: 17.7.2007 Где: центр Вселенной Репутация: 1 Всего: 64 |
Keeper89, прикрепляю пример. Посмотри и скажи, правильно ли я тебя понял.
Это сообщение отредактировал(а) artsb - 5.2.2010, 22:32 Присоединённый файл ( Кол-во скачиваний: 6 )
sort.exe 627,00 Kb-------------------- Чем отличается умный человек от мудрого? Умный - выпутается из любой ситуации. Мудрый - просто в неё не попадёт. |
|||
|
||||
| Keeper89 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2580 Регистрация: 26.2.2009 Репутация: 9 Всего: 58 |
artsb, абсолютно правильно.
bems, спасибо, решение с дженериками - супер! Единственное добавил еще одну вещь:
|
|||
|
||||
| artsb |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2280 Регистрация: 17.7.2007 Где: центр Вселенной Репутация: 1 Всего: 64 |
А этот вариант случаем не сортирует всё подряд? Вроде как нужно было по конкретному столбцу. Просто я в Делфи не силён... Добавлено через 2 минуты и 51 секунду Всё. Кажись понял -------------------- Чем отличается умный человек от мудрого? Умный - выпутается из любой ситуации. Мудрый - просто в неё не попадёт. |
|||
|
||||
| artsb |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2280 Регистрация: 17.7.2007 Где: центр Вселенной Репутация: 1 Всего: 64 |
Выкладываю своё решение (правда на С++). Мало ли, кому-нибудь пригодится.
Выкладываю на С++, т.к. плохо знаком с Делфи. Хотя и могу перевести код и он даже будет работать, но скорее всего, будет не эффективен. И к тому же, могут быть скрытые ошибки.
Алгоритм стащил из реализации в classes.pas Объясню почему я написал так:
, а не оставил так как это было реализовано в classes.pas: Дело в том, что там было написано приблизительно так:
Здесь получается, что когда индексы совпадают, т.е. I==J происходит перестановка элементов с этими индексами, но это бессмысленно как вы понимаете ЗЫ профи поправьте меня если что -------------------- Чем отличается умный человек от мудрого? Умный - выпутается из любой ситуации. Мудрый - просто в неё не попадёт. |
||||||
|
|||||||
| bems |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 18 Всего: 88 |
Keeper89, попросить пояснений ты мог бы прямо в этой теме. Итак:
Класс Generics.Collections.TArray умеет искать двоичным поиском и сортировать методом быстрой сортировки. Это объеденино в класс, потому что невозможно создать обобщенную функцию, не член класса/объекта. Это ограничение языка. Все методы это методы класса, поэтому не нужно создавать экземпляр TArray. Метод Generics.Collections.TArray.Sort<T> выполняет быструю сортировку массива элементов типа, указанного в Т.
Values - собственно массив. В моем примере я объявляю типы
Это нужно только для того чтобы объявление параметра Data не воспринималось как открытый массив, это приводит к несоответствию типов. Это ограничение данного конкретного случая, а не класса TArray или дженериков в целом. Я имею в виду, что в T можно прямо указать array of Integer не объявляя промежуточного типа. Если Index и Count не указаны, то сортируется весь массив. Comparer, это объект, реализующий интерфейс IComparer. Если не указан, то используется компаратор по умолчанию. Я еще не вник, что же это за сравнение по умолчанию для разных типов, но случаи с целыми числами и строками очевидны. Класс Generics.Defaults.TComparer<T> это абстактный компаратор двух величин типа, указанного в T. Его метод Compare абстрактен, поэтому не стоит напрямую создавать экземпляры этого класса. Метод Generics.Defaults.TComparer<T>.Construct создает объект класса, унаследованного от TComparer<T>, а значит также поддерживающего интерфейс IComparer<T> Реально создается экземпляр TDelegatedComparer<T>, у которого метод Compare уже реализован. Эта реализация просто вызывает функцию по ссылке, переданной при вызове Construct. Анонимные методы это отдельная тема, погугли это сам. Благодаря тому, что Construct возвращает не сам свежесозданный объект, а его интерфейс, и тому что TComparer<T> унаследован от TInterfacedObject, ты можешь сразу передать интерфейс в TArray.Sort<T>, не заботясь о сохранении ссылки с целью освобождения. Объект будет разрушен автоматически при обнулении счетчика ссылок (в моем примере это происходит сразу после вызова Sort<T>). Это сообщение отредактировал(а) bems - 5.2.2010, 23:38 -------------------- Обижено школьников: 8 |
||||
|
|||||
| Keeper89 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2580 Регистрация: 26.2.2009 Репутация: 9 Всего: 58 |
bems, все прояснилось, спасибо!
З.Ы. Я просто думал не засорять тему нужными только мне пояснениями, поэтому отправил ЛС. |
|||
|
||||
| Keeper89 |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2580 Регистрация: 26.2.2009 Репутация: 9 Всего: 58 |
bems,
Возник вопрос. Возможно ли заменить
на другой тип, например
Или даже не Real, а свой собственный? Это сообщение отредактировал(а) Keeper89 - 21.2.2010, 16:08 |
||||
|
|||||
| bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 18 Всего: 88 |
Keeper89, можно, но тогда замени тип и в
TArray.Sort<TDoubleArr> и в TComparer<TDoubleArr>.Construct -------------------- Обижено школьников: 8 |
|||
|
||||
| Keeper89 |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2580 Регистрация: 26.2.2009 Репутация: 9 Всего: 58 |
Сделал так:
И выскакивает ошибка (в 15 строке, где end):
Это сообщение отредактировал(а) Keeper89 - 21.2.2010, 20:12 |
||||
|
|||||
| bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 18 Всего: 88 |
Не нужно возвращать TCoefficient.
Независимо от типа сравниваемых величин, возвращается целое. <0 если меньше, 0 если равно, >0 если больше -------------------- Обижено школьников: 8 |
|||
|
||||
![]()
|
| Правила форума "Delphi: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |