![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
убрать повторы из массива [D7]
q-p © (2006-09-17 09:44:00)Господа, есть такая задача: у меня задан массив (t1: TRawList)
TFNRaw = array [0..5] of Byte;
TRawList = array of TFNRaw;
в конечном итоге t1: TRawList - заполняется и может содержать повторяющиеся значения, так вот необходимо посчитать количество повторов для каждого элемента и исключить повторяющиеся, ну чтоб потом переделанная структура была вида TFNRaw - данные, ну и TFNRawCount - их кол-во повторов, ну т.е. если без повторов то 1...
Я бы сам начал реализовывать, но главная необходимость - это быстро осуществить данную операцию, а значит надо корректно реализовать, что я со своими кривыми руками не умею. Спасибо!
default (2006-09-17 20:12:00) [1]"else begin
Inc(Pos);
Result[Pos].Bytes := Src[i];
end;
"
-->
else begin
Inc(Pos);
Result[Pos].Bytes := Src[i];
Result[Pos].Count := 1; end;
больше ошибок вроде нет
default (2006-09-17 19:46:00) [2]
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;
вот сделай хотя бы так, это не так быстро зато прозрачно
код не проверял
q-p (2006-09-17 19:22:00) [3]Неужели без вариантов? Помогите пожалуйста!
q-p (2006-09-17 17:01:00) [4]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;
Подскажите что-нибудь, пожалуйста.
default (2006-09-17 15:56:00) [5]ну если вручную париться не охота можешь закинуть адреса элементов типа TFNRaw в список типа TList(методом Add), потом его отсортировать методом Sort и пробежаться по сортированному списку для формирования массива элементов типа TRawResult
q-p (2006-09-17 15:00:00) [6]
> указатель на этот массив.
В смысле указатель? @?
Ну куда-же все мастера пропали? Ну не знаю, я что мне делать, честное слово, запутался окончательно, помогите!
TUser (2006-09-17 13:38:00) [7]Не надо копировать все элементы TFNRaw, котпруй только указатель на этот массив.
q-p (2006-09-17 13:00:00) [8]Да вроде идею немножко понимаю, но запутался в дебрях реализации. Почему же я такой дурак. Вот сочинил код, который даже скомпилировать не могу.
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;
Desdechado (2006-09-17 12:46:00) [9]и что? поиск дублей в массиве настолько трудный?
цикл по исходному массиву
если текущий элемент в новом массиве есть, то увеличить счетчик для него
если нет, добавить текущий элемент в новый массив
конец цикла
q-p (2006-09-17 12:44:00) [10]Вообще результирующие данные в соответствии с моим примером должны быть такие:
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;
Anatoly Podgoretsky (2006-09-17 12:44:00) [11]Код не соответсвует приведеной постановке и почему именно RResult := (0, 1, 2 ,3 ,4);, а не 0, $ff, 2 ,3 ,4);
q-p (2006-09-17 12:41:00) [12]Ой, ну т.е. ResultData: TRawResult; - это на самом деле ResultData: array of TRawResult;
q-p (2006-09-17 12:40:00) [13]
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;
Zeqfreed (2006-09-17 12:28:00) [14]> ну и TFNRawCount - их кол-во повторов, ну т.е. если без
> повторов то 1...
Почему один? А если будет один повтор, то вернуть должно 2?
TUser (2006-09-17 12:25:00) [15]Напиши пример исходных данных и результата. А то я не понял задачи, и думаю, не только я.
q-p (2006-09-17 12:16:00) [16]Нет, не в институте.
Может все же поможете алгоритмом, я просто запутался.
Anatoly Podgoretsky (2006-09-17 10:52:00) [17]Такой необходимости нет, поскольку самый тупой алгоритм будет работать настолько быстро, что это просто никак не заметить, не может человек оперировать микросекундами.
Неужели такие тупые задачки задают в институте.