Форум: "Начинающим";
Текущий архив: 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