Текущий архив: 2006.10.08;
Скачать: CL | DM;
Внизубрать повторы из массива Найти похожие ветки
← →
q-p (2006-09-17 09:44) [0]Господа, есть такая задача: у меня задан массив (t1: TRawList)
TFNRaw = array [0..5] of Byte;
TRawList = array of TFNRaw;
в конечном итоге t1: TRawList - заполняется и может содержать повторяющиеся значения, так вот необходимо посчитать количество повторов для каждого элемента и исключить повторяющиеся, ну чтоб потом переделанная структура была вида TFNRaw - данные, ну и TFNRawCount - их кол-во повторов, ну т.е. если без повторов то 1...
Я бы сам начал реализовывать, но главная необходимость - это быстро осуществить данную операцию, а значит надо корректно реализовать, что я со своими кривыми руками не умею. Спасибо!
← →
Anatoly Podgoretsky © (2006-09-17 10:52) [1]Такой необходимости нет, поскольку самый тупой алгоритм будет работать настолько быстро, что это просто никак не заметить, не может человек оперировать микросекундами.
Неужели такие тупые задачки задают в институте.
← →
q-p (2006-09-17 12:16) [2]Нет, не в институте.
Может все же поможете алгоритмом, я просто запутался.
← →
TUser © (2006-09-17 12:25) [3]Напиши пример исходных данных и результата. А то я не понял задачи, и думаю, не только я.
← →
Zeqfreed © (2006-09-17 12:28) [4]> ну и TFNRawCount - их кол-во повторов, ну т.е. если без
> повторов то 1...
Почему один? А если будет один повтор, то вернуть должно 2?
← →
q-p (2006-09-17 12:40) [5]
type
TFNRaw = array [0..5] of Byte;
TRawList = array of TFNRaw;
TRawResult = record
RResult: TFNRaw;
Count: Byte;
end;
var
RawData: TRawList;
ResultData: TRawResult;
RawData - это изначальное значение, ну т.е. там например может быть такоеRawData[0] = (0, 1, 2 ,3 ,4);
RawData[1] = ($ff, 1, 2 ,3 ,4);
RawData[2] = (0, $ff, 2 ,3 ,4);
RawData[3] = (0, 1, 2 ,$ff ,4);
RawData[4] = (0, 1, 2 ,3 ,4);
RawData[5] = (0, $ff, 2 ,3 ,4);
RawData[6] = (0, $ff, 2 ,3 ,$ff);
RawData[7] = (0, 1, 2 ,3 ,4);
Видите, в: [0], [4], [7] - одинаковые значения. И в [2] и [5] - тоже одинаковые. Теперь необходимо сформировать ResultData (TRawResult), где будут все данные без повторов, а в Count будет кол-во в изначальном листе. Например в случае [0], [4], [7] - там будет:
RResult := (0, 1, 2 ,3 ,4);
Count := 3;
← →
q-p (2006-09-17 12:41) [6]Ой, ну т.е. ResultData: TRawResult; - это на самом деле ResultData: array of TRawResult;
← →
Anatoly Podgoretsky © (2006-09-17 12:44) [7]Код не соответсвует приведеной постановке и почему именно RResult := (0, 1, 2 ,3 ,4);, а не 0, $ff, 2 ,3 ,4);
← →
q-p (2006-09-17 12:44) [8]Вообще результирующие данные в соответствии с моим примером должны быть такие:
ResultData[0].Result = (0, 1, 2 ,3 ,4);
ResultData[0].Count = 3;
ResultData[1].Result = ($ff, 1, 2 ,3 ,4);
ResultData[1].Count = 1;
ResultData[2].Result = (0, $ff, 2 ,3 ,4);
ResultData[2].Count = 2;
ResultData[3].Result = (0, 1, 2 ,$ff ,4);
ResultData[3].Count = 1;
ResultData[4].Result = (0, $ff, 2 ,3 ,$ff);
ResultData[4].Count = 1;
← →
Desdechado © (2006-09-17 12:46) [9]и что? поиск дублей в массиве настолько трудный?
цикл по исходному массиву
если текущий элемент в новом массиве есть, то увеличить счетчик для него
если нет, добавить текущий элемент в новый массив
конец цикла
← →
q-p (2006-09-17 13:00) [10]Да вроде идею немножко понимаю, но запутался в дебрях реализации. Почему же я такой дурак. Вот сочинил код, который даже скомпилировать не могу.
TFNRaw = array [0..2] of Byte;
TRawList = array of TFNRaw;
TRawResult = record
RawResult: TFNRaw;
Count: Byte;
end;
var
Tmp: TRawList;
Tmp2: array of TRawResult;
procedure TForm1.FormCreate(Sender: TObject);
var
t1: TFNRaw;
i: Byte;
begin
SetLength(Tmp, 4);
for i := 0 to 2 do
t1[i] := Random($fe); //do random items for test
tmp[0] := t1;
t1[0] := 1;
t1[1] := 2;
t1[2] := 3;
tmp[1] := t1;
t1[0] := 1;
t1[1] := 2;
t1[2] := 3;
tmp[2] := t1;
t1[0] := 1;
t1[1] := $ff;
t1[2] := 3;
tmp[3] := t1;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
w, w2: Byte;
procedure PseudoDeleteElement(var Tmp3: TRawList; ElementNumb: Byte);
var
i: Byte;
begin
for i := ElementNumb + 1 to Length(Tmp3) do
Tmp3[i] := Tmp[i - 1];
SetLength(Tmp3, Length(Tmp3) - 1);
end;
begin
while w < Length(Tmp) do
begin
Inc(w);
SetLength(Tmp2, Length(Tmp2) + 1);
Tmp2[High(Tmp2) + 1].RawResult := Tmp[w];
for w2 := w to Length(Tmp) do
if Tmp2[w2].RawResult = Tmp[w2].Raw then
begin
PseudoDeleteElement(Tmp, w2);
Inc(Tmp2[w].Count);
end;
end;
end;
← →
TUser © (2006-09-17 13:38) [11]Не надо копировать все элементы TFNRaw, котпруй только указатель на этот массив.
← →
q-p (2006-09-17 15:00) [12]
> указатель на этот массив.
В смысле указатель? @?
Ну куда-же все мастера пропали? Ну не знаю, я что мне делать, честное слово, запутался окончательно, помогите!
← →
default © (2006-09-17 15:56) [13]ну если вручную париться не охота можешь закинуть адреса элементов типа TFNRaw в список типа TList(методом Add), потом его отсортировать методом Sort и пробежаться по сортированному списку для формирования массива элементов типа TRawResult
← →
q-p (2006-09-17 17:01) [14]default, спасибо за совет. Я не понимаю, зачем его потом необходимо отсортировать методом sort? к слову говоря, ме необходимо сохранить порядок следования элементов (ну за исключением повторяющихся).
И ещё, как сравнивать элементы из двух списков? они же, как pointer идут.
Вот мой переделанный основной кусок кода, с использованием TList.var
List, List2: TList;
i, k, k2: Byte;
LastIndex: Integer;
begin
List := TList.Create;
List2 := TList.Create;
for i := Low(RawList) to High(RawList) do
List.Add(@RawList[i]);
k := 0;
while k < List.Count do
begin
Inc(k);
LastIndex := List2.Add(List.Items[k-1]);
for k2 := k to List.Count do
if List2.Items[LastIndex] = List.Items[k2 - 1] then
begin
ShowMessage("debug: __"+IntToStr(k2 - 1));
// List.Delete(k2);
end;
end;
end;
Подскажите что-нибудь, пожалуйста.
← →
q-p (2006-09-17 19:22) [15]Неужели без вариантов? Помогите пожалуйста!
← →
default © (2006-09-17 19:46) [16]
TBytes = Array[0..5] of Byte;
TArrBytes = Array of TBytes;
TPackBytes = record
Bytes: TBytes;
Count: Byte;
end;
TArrPackBytes = Array of TPackBytes;
var
Form1: TForm1;
implementation
{$R *.dfm}
function PackBytesList(const Src: TArrBytes): TArrPackBytes;
var
i, Ind, Pos: Integer;
function GetIndex(const Src: TArrPackBytes; const Bytes: TBytes): Integer;
var
i: Integer;
begin
Result := -1;
for i := Low(Src) to High(Src) do begin
if CompareMem(@Src[i].Bytes, @Bytes, SizeOf(TBytes)) then begin
Result := i;
Break;
end;
end;
end;
begin
SetLength(Result, Length(Src));
Pos := -1;
for i := Low(Src) to High(Src) do begin
Ind := GetIndex(Result, Src[i]);
if Ind <> -1 then
Inc(Result[Ind].Count)
else begin
Inc(Pos);
Result[Pos].Bytes := Src[i];
end;
end;
SetLength(Result, Pos+1);
end;
вот сделай хотя бы так, это не так быстро зато прозрачно
код не проверял
← →
default © (2006-09-17 20:12) [17]"else begin
Inc(Pos);
Result[Pos].Bytes := Src[i];
end;
"
-->
else begin
Inc(Pos);
Result[Pos].Bytes := Src[i];
Result[Pos].Count := 1; end;
больше ошибок вроде нет
Страницы: 1 вся ветка
Текущий архив: 2006.10.08;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.04 c