Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

убрать повторы из массива [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]

Такой необходимости нет, поскольку самый тупой алгоритм будет работать настолько быстро, что это просто никак не заметить, не может человек оперировать микросекундами.
Неужели такие тупые задачки задают в институте.


Наверх

Титульная страница Поиск, карта сайта Написать письмо