Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.51 MB
Время: 0.051 c
2-1158414145
olevacho_
2006-09-16 17:42
2006.10.08
последовательность вывода band-ов


15-1158251137
Чародей
2006-09-14 20:25
2006.10.08
OpenGL® SuperBible, Third Edition


1-1156495349
DelphiLexx
2006-08-25 12:42
2006.10.08
CopyRect не работает для TMetaFileCanvas


15-1158300245
Ega23
2006-09-15 10:04
2006.10.08
Специалисты по MySQL, отзовитесь!


4-1148829120
Plotnick
2006-05-28 19:12
2006.10.08
Ресурсные строки