Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

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


Страницы:   1 2

@!!ex ©   (2009-05-19 21:50:00) 

Есть массив структур с полями Name, Map, Id, Locked, TTL.
Нужно сделать сортировку по приоритетам.
Тоесть пользователь кликает на Name, список сортируется по Name, после чего кликает на Locked, список сортируется с учетом Locked, но там где Locked равный сотрируется уже по имени.

Как такое проще всего реализовать? Может есть примеры?


@!!ex   (2009-05-20 07:43:00) [21]

Сделал вчера так:
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;


MBo   (2009-05-20 05:41:00) [22]

> но там где Locked равный сотрируется уже по имени.

1 способ:
Многокритериальная функция сравнения (если по первому полю равенство, сравниваем второе и т.д.)

2 способ:
Устойчивый метод сортировки (например, MergeSort).
Такие сортировки не меняют имеющийся порядок элементов с равными ключами.


DVM   (2009-05-19 22:07:00) [23]


> @!!ex ©   (19.05.09 21:56) [4]

Да все просто. На вход алгоритма подается множество критериев сортировки.
Алгоритм (точнее уже упомянутая в CustomSort функция) на вход получает два элемента и сравнивает их используя последовательно критерии из множества.
Если по первому критерию равны, используем второй и т.д. Результат возвращаем в виде да/нет/равно


Сергей М.   (2009-05-19 21:58:00) [24]


> @!!ex ©   (19.05.09 21:56) [4]


Что тебя улыбнуло ?)


@!!ex   (2009-05-19 21:56:00) [25]

> [2] Сергей М. ©   (19.05.09 21:54)

:)


> [3] DVM ©   (19.05.09 21:54)

5


DVM   (2009-05-19 21:54:00) [26]

И сколько критериев может быть одновременно?


Сергей М.   (2009-05-19 21:54:00) [27]


> Как такое проще всего реализовать?


TList.CustomSort


@!!ex   (2009-05-19 21:50:00) [28]

P.S.
Меня не сам алгоритм сортировки интересует. А метод сравнения элементов с учетом приоритетов.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо