Форум: "Начинающим";
Текущий архив: 2009.07.12;
Скачать: [xml.tar.bz2];
ВнизКак реализовать сортировку по приоритетам? Найти похожие ветки
← →
@!!ex © (2009-05-19 21:50) [0]Есть массив структур с полями Name, Map, Id, Locked, TTL.
Нужно сделать сортировку по приоритетам.
Тоесть пользователь кликает на Name, список сортируется по Name, после чего кликает на Locked, список сортируется с учетом Locked, но там где Locked равный сотрируется уже по имени.
Как такое проще всего реализовать? Может есть примеры?
← →
@!!ex © (2009-05-19 21:50) [1]P.S.
Меня не сам алгоритм сортировки интересует. А метод сравнения элементов с учетом приоритетов.
← →
Сергей М. © (2009-05-19 21:54) [2]
> Как такое проще всего реализовать?
TList.CustomSort
← →
DVM © (2009-05-19 21:54) [3]И сколько критериев может быть одновременно?
← →
@!!ex © (2009-05-19 21:56) [4]> [2] Сергей М. © (19.05.09 21:54)
:)
> [3] DVM © (19.05.09 21:54)
5
← →
Сергей М. © (2009-05-19 21:58) [5]
> @!!ex © (19.05.09 21:56) [4]
Что тебя улыбнуло ?)
← →
DVM © (2009-05-19 22:07) [6]
> @!!ex © (19.05.09 21:56) [4]
Да все просто. На вход алгоритма подается множество критериев сортировки.
Алгоритм (точнее уже упомянутая в CustomSort функция) на вход получает два элемента и сравнивает их используя последовательно критерии из множества.
Если по первому критерию равны, используем второй и т.д. Результат возвращаем в виде да/нет/равно
← →
MBo © (2009-05-20 05:41) [7]> но там где Locked равный сотрируется уже по имени.
1 способ:
Многокритериальная функция сравнения (если по первому полю равенство, сравниваем второе и т.д.)
2 способ:
Устойчивый метод сортировки (например, MergeSort).
Такие сортировки не меняют имеющийся порядок элементов с равными ключами.
← →
@!!ex © (2009-05-20 07:43) [8]Сделал вчера так:
const
CP_ID = 0;
CP_LOCKED = 1;
CP_TTL = 2;
CP_NAME = 3;
CP_MAP = 4;
var
Compare_Priority:array[0..4] of integer = (CP_ID, CP_LOCKED,CP_TTL,CP_NAME,CP_MAP);
Compare_Invert:array[0..4] of boolean = (false,false,false,false,false);
function TMainForm.CompareItemByPriority(iproperty,id1,id2:integer):integer;
begin
case iproperty of
CP_ID:begin
if Servers[id1].ID>Servers[id2].ID then
Result:=1
else
if Servers[id1].ID<Servers[id2].ID then
Result:=-1
else
Result:=0;
end;
CP_LOCKED:begin
if Servers[id1].Locked and not Servers[id2].Locked then
Result:=1
else
if not Servers[id1].Locked and Servers[id2].Locked then
Result:=-1
else
Result:=0;
end;
CP_TTL:begin
if Servers[id1].TTL>Servers[id2].TTL then
Result:=1
else
if Servers[id1].TTL<Servers[id2].TTL then
Result:=-1
else
Result:=0;
end;
CP_NAME:begin
if Servers[id1].Name>Servers[id2].Name then
Result:=1
else
if Servers[id1].Name<Servers[id2].Name then
Result:=-1
else
Result:=0;
end;
CP_MAP:begin
if Servers[id1].Map>Servers[id2].Map then
Result:=1
else
if Servers[id1].Map<Servers[id2].Map then
Result:=-1
else
Result:=0;
end;
end;
if Compare_Invert[iproperty] then
Result:=-Result;
end;
function TMainForm.CompareItem(id1,id2:integer):integer;
begin
Result:=CompareItemByPriority(Compare_Priority[0],id1,id2);
if Result<>0 then
Exit;
Result:=CompareItemByPriority(Compare_Priority[1],id1,id2);
if Result<>0 then
Exit;
Result:=CompareItemByPriority(Compare_Priority[2],id1,id2);
if Result<>0 then
Exit;
Result:=CompareItemByPriority(Compare_Priority[3],id1,id2);
if Result<>0 then
Exit;
Result:=CompareItemByPriority(Compare_Priority[4],id1,id2);
end;
procedure TMainForm.Sort;
var
i,j:integer;
HaveChanges:boolean;
SortTmp:TCommanderServer;
begin
for i := 0 to Length(Servers) - 2 do begin
HaveChanges:=false;
for j := 0 to Length(Servers) - 2 do begin
if CompareItem(j,j+1)>0 then begin
SortTmp:=Servers[j];
Servers[j]:=Servers[j+1];
Servers[j+1]:=SortTmp;
HaveChanges:=true;
end;
end;
if not HaveChanges then
Break;
end;
FillList();
end;
procedure TMainForm.SetSort(id: integer);
var
i:integer;
oldpos:integer;
begin
if Compare_Priority[0]=id then begin
Compare_Invert[id]:=not Compare_Invert[id];
end
else begin
oldpos:=1;
for I := 1 to 4 do
if Compare_Priority[i]=id then
oldpos:=I;
for i := oldpos-1 downto 0 do
Compare_Priority[i+1]:=Compare_Priority[i];
Compare_Priority[0]:=id;
end;
Sort();
end;
← →
Palladin © (2009-05-20 08:46) [9]
> function TMainForm.CompareItem(id1,id2:integer):integer;
For i:=0 to Length(Compare_Priority)-1 Do
Begin
Result:=CompareItemByPriority(Compare_Priority[i],id1,id2);
If Not Result Then Break;
End;
← →
@!!ex © (2009-05-20 09:33) [10]> [9] Palladin © (20.05.09 08:46)
Согласен. Развернутый для прозрачности теста сделал.
← →
@!!ex © (2009-05-20 09:34) [11]еще в пузырьке j:=i, а не j:=0
← →
sniknik © (2009-05-20 10:26) [12]да научись уже работать с базами, или частный случай хотя бы с рекордсетом...
← →
Palladin © (2009-05-20 10:40) [13]
> sniknik © (20.05.09 10:26) [12]
предлагаешь ради сортировки 10 record"ов составом в 4 поля содавать рекордсет? :)
← →
DVM © (2009-05-20 10:42) [14]
> Palladin ©
Погоди, щас еще фанатики XML набегут.
← →
sniknik © (2009-05-20 10:45) [15]почему нет? ничуть не сложнее чем создать
> массив структур с полями Name, Map, Id, Locked, TTL.
+ в том, что там готовые методы по обработке данных, в том числе и фильтр с сортировкой, что тут как раз и пытаются совместить.
← →
Плохиш © (2009-05-20 10:59) [16]
> Нужно сделать сортировку по приоритетам.
> Тоесть пользователь кликает на Name, список сортируется
> по Name, после чего кликает на Locked, список сортируется
> с учетом Locked, но там где Locked равный сотрируется уже
> по имени.
Я вот, честно, не понял. В чём проблема? В отсутствии программиста?
← →
@!!ex © (2009-05-20 13:43) [17]
> [15] sniknik © (20.05.09 10:45)
> + в том, что там готовые методы по обработке данных, в том
> числе и фильтр с сортировкой, что тут как раз и пытаются
> совместить.
отличная идея. :) таскать с приложением в 100 килобайт еще и СУБД для массива из 10 записей...
> [16] Плохиш © (20.05.09 10:59)
Реализация выше, если вы не обратили внимание. Просто не хотелось изобретать велосипед.
← →
Вариант (2009-05-20 14:09) [18]
> @!!ex © (20.05.09 13:43) [17]
> отличная идея. :) таскать с приложением в 100 килобайт еще
> и СУБД для массива из 10 записей...
Зачем СУБД, есть другие варианты. Достаточно midas.dll или вообще без нее, если подключить RxLib -> TRxMemoryData (или любую другую библиотеку с "отсоединенным" датасетом) к проекту - это если есть желание воспользоваться готовым и не изобретать велосипед.
PS:Правда считаю, что время от времени "изобретение велосипедов" необходимо, для понимания тех или иных вещей.
← →
sniknik © (2009-05-20 14:10) [19]> отличная идея. :) таскать с приложением в 100 килобайт еще и СУБД для массива из 10 записей...
100 килобайт несущественны, СУБД необязательна, 10 записей все и так "на виду" сортировать не нужно.
← →
antonn © (2009-05-20 14:38) [20]а если ему нужна максимальное быстродействие в его задаче - то всякие косыли с субд и "сетами" идут лесом.
← →
Вариант (2009-05-20 14:54) [21]
> antonn © (20.05.09 14:38) [20]
Я конечно не скажу, что вариант с применением TRxMemoryData будет оптимальным и самым быстродействующим, но тем не менее для сортировки он использует QuickSort, что вовсе не так уже и плохо.
← →
sniknik © (2009-05-20 15:05) [22]> Достаточно midas.dll или вообще без нее
ага. я предпочитаю ADODataSet.
> то всякие косыли с субд и "сетами" идут лесом.
так называемые костыли это профессиональные компоненты по обработке данных, вряд ли он, или ты (да и вообще, подавляющее большинство здесь) напишет быстрее.
серьезно, уже были желающие "померятся", и мерялись с компонентом написанным здесь товарищем уровня мастера, т.е. очень хорошим и быстрым (он на это и ориентировался) и по большинству параметров он проиграл... нет, собственно сама сортировка у него была очень быстрая, чуть ли не в 2-3раза по числовому полю, но повторная по тому же полу у него занимала то же время, а время датасета за счет построенного в первый раз индекса стремилась к 0, + не было фильтров, и т.д. ну в общем "по очкам" он проиграл.
у вас же, гарантирую, не будет даже одного преимущества.
← →
@!!ex © (2009-05-20 15:10) [23]Господа, вы не о том спорите.
Использование СУБд здесь не актуально и никогда не будет. Нет смысла.
Проигрыш из-за скорости на <100 элементах не актуален, а на 100+ в любом случае архитектуру переделывать, чтобы пользователь не путался.
← →
sniknik © (2009-05-20 15:14) [24]> Использование СУБд здесь не актуально и никогда не будет. Нет смысла.
СУБд никто и не предлагал, предлагали компонент для данных... дели мух и котлеты.
но в общем то колхоз дело добровольное.
← →
DVM © (2009-05-20 15:14) [25]
> @!!ex © (20.05.09 15:10) [23]
Я понял что ты сортируешь! Сервера вероятно игровые!
← →
@!!ex © (2009-05-20 15:31) [26]> [25] DVM © (20.05.09 15:14)
Да.
← →
antonn © (2009-05-20 16:20) [27]
> так называемые костыли это профессиональные компоненты по
> обработке данных, вряд ли он, или ты (да и вообще, подавляющее
> большинство здесь) напишет быстрее.
речь не о выполняемых ими функциях, а об подготовке к их выполнению.
← →
sniknik © (2009-05-20 16:48) [28]> а об подготовке к их выполнению.
не намного медленнее или неудобнее чем заполнение того же массива рекордов. а уж если данные нужно сохранять/загружать так и наоборот намного удобнее/быстрее.
но вообще разговор ни о чем, автор топика уже отказался от этого варианта.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.07.12;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.004 c