Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2011.04.24;
Скачать: [xml.tar.bz2];

Вниз

выделить из списка цепочки   Найти похожие ветки 

 
LDV   (2011-01-21 13:36) [0]

Есть отсортированный список пакетов обновления:

upd_1_to_2.zip
upd_2_to_3.zip
upd_3_to_4.zip
upd_7_to_11.zip
upd_11_to_12.zip
................

Задача: разбить список на цепочки (подсписки). т.е.

1-я цепочка
upd_1_to_2.zip
upd_2_to_3.zip
upd_3_to_4.zip

2-я цепочка
upd_7_to_11.zip
upd_11_to_12.zip

Делаю так:

1. Формирую TList<TPoint> (чтобы было удобней сравнивать), где

X - 1-е значение в имени пакета обновления
Y - 2-е значение в имени пакета обновления

2. Передаю TList<TPoint> в написанную процедуру split

Вот что я написал, помогите довести код до ума, может что-то можно сделать более грамотно. Как-то все громозко получается


procedure Split(const Afile_vers: TList<TPoint>;
 ASplitted: TObjectList<TList<TPoint>>);
var
 Cur: TPoint;
 I, N, J: Integer;
 Ok, Added: TList<TPoint>;
begin
 Ok := TList<TPoint>.Create(TComparer<TPoint>.Construct(

     function (const AVal1, AVal2: TPoint): Integer
     begin
       Result := CompareValue(AVal1.X, AVal2.Y)

     end
 ));
 for I := 0 to Afile_vers.Count - 1 do
 begin
   Cur := Afile_vers[I];
   try
     Ok.BinarySearch(Cur, N);
     { 1-е значение в имени текущего пакета обновления должно совпадать со
       2-значением в имени предшаствующего пакета, если текущй пакет не
       будет 1-м в списке (N <> 0)}
     if N <> 0 then

       Assert(Ok[N - 1].Y = Cur.X);

     {2-е значение в имени текущего пакета обновления должно совпадать с
       1-м значением в имени следующего пакета, если текущий пакет не будет
       последним в списке (N <> Ok.Count)}

     if N <> Ok.Count then

       Assert(Cur.Y = Ok[N].X);

     Ok.Insert(N, Cur);
   except
     Added := TList<TPoint>.Create;
     try
       for J := 0 to Ok.Count - 1 do
         Added.Add(Ok[J]);
       ASplitted.Add(Added);
       Ok.Clear;
       Ok.Add(Cur);
     except
       Added.Free;
       raise;
     end;
   end;

 end;
 Added := TList<TPoint>.Create;
 try
   for J := 0 to Ok.Count - 1 do
     Added.Add(Ok[J]);
   ASplitted.Add(Added);
 except
   Added.Free;
   raise;
 end;

end;

procedure TForm3.FormCreate(Sender: TObject);
var
 file_vers: TList<TPoint>;
 Splitted: TObjectList<TList<TPoint>>;
begin
 file_vers := TList<TPoint>.Create;
 try
   Splitted := TObjectList<TList<TPoint>>.Create;
   try
     { ... test }
     file_vers.Add(Point(1, 2)); // upd_1_to_2.zip
     file_vers.Add(Point(2, 3)); // upd_2_to_3.zip
     file_vers.Add(Point(3, 4)); // upd_3_to_4.zip
     file_vers.Add(Point(7, 11)); // upd_7_to_11.zip
     file_vers.Add(Point(11, 12)); // upd_11_to_12.zip

     Split(file_vers, Splitted);

     ShowMessage("Цепочек: " + IntToStr(Splitted.Count));
     { ... }
   finally
     Splitted.Free;
   end;
 finally
   file_vers.Free;
 end;

end;


 
Ega23 ©   (2011-01-21 13:49) [1]


> 1. Формирую TList<TPoint> (чтобы было удобней сравнивать)

Это нехорошо. Можно, но нехорошо. Напиши свой тип, используй его.


 
MBo ©   (2011-01-21 13:49) [2]


цикл
 Взяли i-ю строку.
 Выделили из нее X и Y.
 Если X не совпадает с OldY, то
     Получили цепочку от Start до i-1, выдаем ее в результат
     Start = i
 OldY = Y
конец цикла, выдаем последнюю цепочку


 
han_malign   (2011-01-21 16:21) [3]


>  Взяли i-ю строку.
>  Выделили из нее X и Y.

- для не последовательного ввода и/или кэширования "звеньев":
const
  RANGE_BEGIN = $80000000;
  RANGE_END   = $40000000;
  RANGE_VALUE = $3FFFFFFF;

  function compare(x1, x2: LongWord): integer;
  begin
       Result:= LongInt(x1 and RANGE_VALUE) - LongInt(x2 and RANGE_VALUE);
  end;

procedure AddRange(X, Y: longword);
var i: integer;
begin  
  i:= FindOrInsert(rgdwRanges, X, compare);
  rgdwRanges[i]:= rgdwRanges[i] or RANGE_BEGIN;
  i:= FindOrInsert(rgdwRanges, Y, compare);
  rgdwRanges[i]:= rgdwRanges[i] or RANGE_END;
end;

function ProcessRanges: integer;//return count of Continuous chains
var rangeStart: integer;
begin
  Result:= 0; rangeStart:= -1;
  for i:= Low(rgdwRanges) to High(rgdwRanges) do begin
     case(rgdwRanges[i] and (RANGE_BEGIN or RANGE_END))of
     0: Assert(false);
     RANGE_BEGIN: rangeStart:= rgdwRanges[i] and RANGE_VALUE;
     RANGE_END: begin
         Assert((i > Low(rgdwRanges)) and (integer(rangeStart) >= 0));
         ProcessFile(format("upd_%u_to_%u.zip", [rgdwRanges[i-1] and RANGE_VALUE, rgdwRanges[i] and RANGE_VALUE]));
         FlushContinuousRange(rangeStart, rgdwRanges[i] and RANGE_VALUE);
         inc(Result);
     end;
     else //(RANGE_BEGIN or RANGE_END) - intermediate joint
         Assert(i > Low(rgdwRanges));
         ProcessFile(format("upd_%u_to_%u.zip", [rgdwRanges[i-1] and RANGE_VALUE, rgdwRanges[i] and RANGE_VALUE]));
     end{case};
  end;
end;



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2011.04.24;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.46 MB
Время: 0.004 c
15-1294985178
Медвежонок ХМЛ
2011-01-14 09:06
2011.04.24
УЭК


2-1240595519
Артем
2009-04-24 21:51
2011.04.24
открыт ли порт?


15-1294859352
Внук
2011-01-12 22:09
2011.04.24
Исправления в DOA


15-1294781400
Юрий
2011-01-12 00:30
2011.04.24
С днем рождения ! 12 января 2011 среда


2-1295537929
Айнур
2011-01-20 18:38
2011.04.24
Вопрос по Edit





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский