Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove same element array in delphi

Tags:

delphi

I'm trying to remove the same element of array in delphi. For examples :
R[1] := 33332111111111111111111111323333333334378777433333344333333333277

I want to make it become 32132343787434327. and saved in the new array.
Could you give some idea?

I already tried to make each of R[1] element to Array. And tried some code.

  for i:=1 to length(NR) do
  begin
    found:=false;
    for k:=i+1 to length(NR) do
    begin
        if (NR[i]=NR[k]) then
        begin
          found:=true;
        end;
    end;
    if (not found) then
    begin
      Memo1.Lines.Add(NR[i]);
    end;
  end;

But the result is 184327.
could you guys help me? thanks a lot. I'm so desperate to do this.

like image 778
Then Theresia Avatar asked Apr 09 '14 19:04

Then Theresia


1 Answers

You appear to be working with strings rather than arrays. In which case you need this function:

function RemoveAdjacentDuplicates(const X: string): string;
var
  i, j: Integer;
begin
  SetLength(Result, Length(X));
  j := 0;
  for i := 1 to Length(Result) do
    if (i=1) or (X[i]<>X[i-1]) then
    begin
      inc(j);
      Result[j] := X[i];
    end;
  SetLength(Result, j);
end;

Let's work through this.

First of all I allocate the result variable. This is likely to be an over allocation. We know that the result cannot be larger than the input.

We use two indexing local variables, the rather weakly named i and j. We could give them descriptive names but for such a short function one might decide that it was not necessary. Do feel free to come up with other names if you prefer. You might choose idxIn and idxOut for instance.

One variable indexes the input, the other indexes the output. The input index is used in a simple for loop. The output index is incremented every time we find a unique item.

The if condition tests whether the input index refers to a character that differs from the previous one. The first element has no previous element so we always include it.

Once the loop completes we know how long the output is and can perform the final allocation.

Adapting this for an array is simple. You just need to account for arrays using zero-based indexes. For a bit of fun, here's a generic version for arrays:

type
  TMyArrayHelper = class
    class function RemoveAdjacentDuplicates<T>(const X: array of T): TArray<T>; 
      static;
  end;

class function TMyArrayHelper.RemoveAdjacentDuplicates<T>
  (const X: array of T): TArray<T>;
var
  i, j: Integer;
  Comparer: IEqualityComparer<T>;
begin
  Comparer := TEqualityComparer<T>.Default;
  SetLength(Result, Length(X));
  j := 0;
  for i := 0 to high(Result) do
    if (i=0) or not Comparer.Equals(X[i], X[i-1]) then
    begin
      Result[j] := X[i];
      inc(j);
    end;
  SetLength(Result, j);
end;

Note the subtly different placement of inc(j). This is necessitated by the switch to zero-based indexing.

A slightly more complex alternative with fewer tests would be:

class function TMyArrayHelper.RemoveAdjacentDuplicates<T>
  (const X: array of T): TArray<T>;
var
  i, j, len: Integer;
  Comparer: IEqualityComparer<T>;
begin
  Comparer := TEqualityComparer<T>.Default;
  len := Length(X);
  SetLength(Result, len);
  if len=0 then
    exit;

  Result[0] := X[0];
  j := 1;
  for i := 1 to len-1 do
    if not Comparer.Equals(X[i], X[i-1]) then
    begin
      Result[j] := X[i];
      inc(j);
    end;
  SetLength(Result, j);
end;
like image 80
David Heffernan Avatar answered Oct 16 '22 17:10

David Heffernan