Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.07.12;
Скачать: CL | DM;

Вниз

Как реализовать сортировку по приоритетам?   Найти похожие ветки 

 
@!!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;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.013 c
15-1241901005
Юрий
2009-05-10 00:30
2009.07.12
С днем рождения ! 10 мая 2009 воскресенье


15-1242160207
Юрий
2009-05-13 00:30
2009.07.12
С днем рождения ! 13 мая 2009 среда


15-1241988585
Petr V. Abramov
2009-05-11 00:49
2009.07.12
Лето неотвратимо, как оздоровление мировой экономики :)


3-1223555595
abhtr
2008-10-09 16:33
2009.07.12
Нужен файл dbExpress.pas


4-1212458021
kroenen
2008-06-03 05:53
2009.07.12
Народ если кто в теме помогите плз найти хэндл АдресБара в Опере