2014-04-09 4 views
6

Ich versuche, das gleiche Element des Arrays in Delphi zu entfernen. Beispiele:
R[1] := 33332111111111111111111111323333333334378777433333344333333333277Entfernen Sie dasselbe Element Array in Delphi

Ich mag es 32132343787434327. und in dem neuen Array gespeichert machen werden.
Können Sie eine Idee geben?

Ich habe bereits versucht, jedes von R [1] -Element zu Array zu machen. Und versuchte etwas 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; 

Aber das Ergebnis ist 184327.
könnten ihr mir helfen? Danke vielmals. Ich bin so verzweifelt, das zu tun.

Antwort

14

Sie scheinen mit Zeichenfolgen anstelle von Arrays zu arbeiten. In diesem Fall benötigen Sie diese Funktion:

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; 

Lassen Sie uns das durcharbeiten.

Zuallererst weise ich die Ergebnisvariable zu. Dies ist wahrscheinlich eine Überzuteilung. Wir wissen, dass das Ergebnis nicht größer als die Eingabe sein kann.

Wir verwenden zwei indexierende lokale Variablen, die eher schwach i und j genannt werden. Wir könnten ihnen beschreibende Namen geben, aber für solch eine kurze Funktion könnte man entscheiden, dass es nicht notwendig war. Fühlen Sie sich frei, andere Namen zu finden, wenn Sie bevorzugen. Sie könnten zum Beispiel idxIn und idxOut wählen.

Eine Variable indiziert den Eingang, der andere indiziert den Ausgang. Der Eingangsindex wird in einer einfachen for-Schleife verwendet. Der Ausgabe-Index wird jedes Mal erhöht, wenn wir ein eindeutiges Element finden.

Die if Bedingung testet, ob sich der Eingangsindex auf ein Zeichen bezieht, das sich von dem vorherigen unterscheidet. Das erste Element hat kein vorheriges Element, also schließen wir es immer ein.

Sobald die Schleife abgeschlossen ist, wissen wir, wie lange die Ausgabe ist und die endgültige Zuordnung durchführen können.

Die Anpassung für ein Array ist einfach. Sie müssen nur Arrays mit nullbasierten Indizes berücksichtigen. Für ein bisschen Spaß, hier ist eine generische Version für 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; 

Notiere die auf subtile Weise anders Platzierung von inc(j). Dies wird durch den Wechsel zur nullbasierten Indizierung notwendig.

Eine etwas komplexere Alternative mit weniger Tests wäre:

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; 
+2

Ich würde den '(i = 0)' Vergleich aus der Schleife bewegen. Das erste Element kann blind hinzugefügt werden, nur diejenigen für 'i> 0' müssen verglichen werden (was für * jeden * Nachfolger gilt). Wenn wir die erste hinzufügen und die Schleife bei Index 1 beginnen lassen, müssen wir diese Überprüfung genau einmal durchführen, anstatt "High (Result)" mal. – JensG

+1

@JensG Danke dafür. Es ist effizienter, als ich zustimme. Aber es ist einfacher, meinen Weg zu lesen. Was ich angestrebt habe angesichts der Erfahrung des Fragestellers. Aber ich nehme deinen Standpunkt mit Sicherheit. –

Verwandte Themen