Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - TStringlist optimieren (Rekursiv)


trm - Fr 14.07.17 21:20
Titel: TStringlist optimieren (Rekursiv)
Guten Abend,

seit langer Zeit habe ich mal wieder ein sicherlich sehr triviales Problem, auf dessen Lösung ich jedoch nicht komme.

In einer TStringList stehen zeilenweise Dateipfade. Diese möchte ich gerne optimieren.

Beispiel:

Quelltext
1:
2:
3:
c:\test\1\
c:\test\
c:\test\test\


Nun sind die beiden Zeilen (1 und 3) für mich in der weiteren Ablaufbehandlung uninteressant, da diese dem Pfad (c:\test\) untergeordnet sind. Also weg damit aus der TStringlist. Aber bei einer rekursiven Behandlung stehe ich vor dem Problem, dass durch einen Vergleich (Pos) dies nicht machbar ist.

Oder doch?



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
  Exclude_SL := TStringList.Create;
  Exclude_SL.Clear;
  Exclude_SL.Sorted := True;
  Exclude_SL.Duplicates := dupIgnore;
  Exclude_SL.BeginUpdate;

  Exclude_SL_tmp := TStringList.Create;
  Exclude_SL_tmp.Clear;
  Exclude_SL_tmp.Sorted := True;
  Exclude_SL_tmp.Duplicates := dupIgnore;
  Exclude_SL_tmp.BeginUpdate;

{ .. Exclude_SL wird nun gefüllt, alle Elemente wie oben beschrieben, sind enthalten }

{ Ab hier der problematische Code, welcher mir Kopfschmerzen bereitet }
  for X := 0 to Exclude_SL.Count - 1 do
    for Y := 0 to Exclude_SL.Count - 1 do
    begin
      Dummy_String := Exclude_SL[X];
      Dummy_String2 := Exclude_SL[Y];
      if X = Y then
        next;
      if Pos(Dummy_String, Dummy_String2) > 0 then
        Exclude_SL_tmp.Add(Dummy_String);
    end;


Exclude_SL ist eine Stringlist
Exclude_SL_tmp ebenso, hier sollen nur die Elemente rein, die brauchbar sind, also in meinem Fall sollte es c:\test\ sein.




EDIT:

1. Erst einmal einen Fehler beheben: NEXT ist ja hier überhaupt nicht zulässig für die Schleife. (Zuviel PHP..)
2. Ich komme der Sache näher:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
  Exclude_SL_tmp.Assign(Exclude_SL);
  Exclude_SL_tmp.Sorted := False;

  for X := 0 to Exclude_SL.Count - 1 do
    for Y := 0 to Exclude_SL_tmp.Count - 1 do
    begin
      Dummy_String := Exclude_SL[X];
      Dummy_String2 := Exclude_SL_tmp[Y];
      if Dummy_String <> Dummy_String2 then
        if Pos(Dummy_String, Dummy_String2) > 0 then
          Exclude_SL_tmp[Y] := '';
    end;


Somit sind die Einträge, die überflüssig sind, aus der TStringlist schon einmal raus. Die Leezeilen werden dann einfach gelöscht, damit das wieder schön zusammenhängt.. :-)


Delphi-Quelltext
1:
2:
3:
  for X := Exclude_SL_tmp.Count - 1 downto 0 do
    if Trim(Exclude_SL_tmp[X]) = '' then
      Exclude_SL_tmp.Delete(X);




Und nun die Frage: geht das ganze auch einfacher?


mandras - Fr 14.07.17 23:55

Meine Idee auf die schnelle (nicht weiter geprüft jetzt um diese Zeit :)

- sortiere Liste alphabetisch

Falls nun gilt:

if pos (Eintrag[i],Eintrag[i+1])=1 then ... <- wahr wenn Eintrag i+1 ein Unterordner von/Datei in Eintrag i ist

das dann noch passend mit dem Laufindex hinbekommen.