Einzelnen Beitrag anzeigen

Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#6

Re: Rekursive Struktur iterativ abfragen

  Alt 22. Mär 2010, 16:28
Hallo Matze,

sowas habe ich vor kurzem bei meinem Brainfuck-Compiler auch gebraucht. Hat mich auch etwas Hirnschmalz und Papier gekostet - der Algorithmus, der schließlich herausgekommen ist, ist folgender (hab mal ein paar Kommentare hinzugefügt):
Delphi-Quellcode:
  TElement = class
  private
    {...}
    FParent: TElementList;
    FChildren: TElementList;
    procedure SetParent(const Value: TElementList);
  public
    {...}
    property Parent: TElementList read FParent write SetParent;
    property Children: TElementList read FChildren;
    {...}
  end;

function TBrainFuckCompiler.GetNextElement(Element: TElement): TElement;
var
  Index: integer;
begin
  Result := nil;
  if Element.Children.Count > 0 then
    // Erstes Kindelement zurückliefern, falls vorhanden
    Result := Element.Children[0]
  else while Assigned(Element.Parent) and not Assigned(Result) do
  begin
    Index := Element.Parent.IndexOf(Element);
    // Folgen auf das aktuelle Element in der gleichen Ebene noch weitere Elemente?
    if Element.Parent.Count > Index+1 then
      Result := Element.Parent.Items[Index+1];
    // Eine Ebene höher springen
    Element := Element.Parent.Parent;
  end;
end;

function TBrainFuckCompiler.GetPreviousElement(Element: TElement): TElement;
var
  Index: integer;
begin
  Result := nil;
  if Assigned(Element.Parent) then
  begin
    Index := Element.Parent.IndexOf(Element);
    if Index >= 1 then
    begin
      // Vorgänger in gleicher Ebene
      Result := Element.Parent.Items[Index-1];
      // Von dort aus zum untersten Kind-Element vorarbeiten
      while Result.Children.Count >= 1 do
        Result := Result.Children.Last;
    end
    else
      // eine Ebene nach oben springen
      Result := Element.Parent.Parent;
  end;
end;
Das Laufzeitverhalten ließe sich sicherlich noch verbessern, indem man IndexOf umgeht (z.B. durch Cachen des Index in den jeweilen Elementen oder durch Verwendung einer verketteten Liste).
  Mit Zitat antworten Zitat