Entwickler-Ecke

Algorithmen, Optimierung und Assembler - Jeden n-ten Eintrag etwas machen


Calculon - Mi 21.11.07 13:08
Titel: Jeden n-ten Eintrag etwas machen
Hi,

ich stehe oft vor dem Problem aus einer Liste von numerischen oder String Einträgen (z.B. in arrays oder Stringlist), die ein bestimmtes Format haben, bestimmte zu extrahieren. Mein Ansatz dauert immer ewig und ist nie zufriedenstellend:

Bsp.:
Textdatei:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
0
0
0
-0.54262
0
0
0
-0.00011072
0.00011851
-0.55537
0
0
.
.
.

Das Format:
1. Wert: x-Translation
2. Wert: y-Translation
3. Wert: z-Translation
4. Wert: Rotation um x
5. Wert: Rotation um y
6. Wert: Rotation um z

alles pro best. Timestep.

Jetzt brauche ich aber nur jeweils die ersten vier zur Weiterverarbeitung. Zunächst würde es mir langen diese vier in ein Memo zu schreiben.

Mein Ansatz sieht so aus:

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:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
function TForm1.AddToMemo(Title: string): string;
begin
  memo1.Lines.Add(Title + ': ' + first.Strings[0]); // in first stehen die Werte aus der Textdatei
  first.Delete(0);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
i: integer;
begin
  memo1.Lines.BeginUpdate;
  repeat
    for i := 0 to 5 do
      begin
        case i of
          0begin
               AddToMemo('xTra');
               continue;
             end;
          1begin
               AddToMemo('yTra');
               continue;
             end;
          2begin
               AddToMemo('zTra');
               continue;
             end;
          3begin
               AddToMemo('xRot');
               continue;
             end;
          4begin
               //AddToMemo('yRot');
               continue;
             end;
          5begin
               //AddToMemo('zRot');
               continue;
             end;
        end;
      end;
  until first.Count = 0;
  memo1.Lines.EndUpdate;
end;


Mal ganz davon abgesehen, dass ich ein 'Listindex überschreitet das Maximum'-Fehler bekomme gefällt mir mein Ansatz auch sonst überhaupt nicht. Gibt's da geschickte Algorithmen oder sonst. Lösungen für diese Geschichte.

Gruß

Calculon
--


Narses - Mi 21.11.07 13:23

Moin!

Wozu die Werte überhaupt durch die Gegend kopieren... :gruebel:

Wenn die Liste homogen aufgebaut ist, dann reicht es doch per Indexarithmetik direkt die Werte daraus zu lesen. :idea: :nixweiss:

cu
Narses


AXMD - Mi 21.11.07 13:25

Hallo!

Lass doch einfach eine Schleife von 0 bis Zeilenanzahl minus 1 laufen und extrahier dir die benötigte Information so:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
for i := 0 to first.Count - 1 do
begin
  if (i mod 6 = 0//Jede 6. Zeile, beginnend mit der ersten...
    ... //in first.Strings[i] ist der Inhalt

  if (i mod 6 = 1//Jede 6. Zeile, beginnend mit der zweiten...

  //... usw.
end;


Ich hoffe, das Prinzip ist klar. Die Modulo-Operation sollte für deine Zwecke das Richtige sein.

AXMD


ene - Mi 21.11.07 13:34

@AMXD Und was machst du, wenn du bei Mod 2 was anderes machen willst als bei Mod 6? Denn beider ergeben 0.


AXMD - Mi 21.11.07 14:09

Seiner Frage nach ist für ihn nur modulo 6 interessant, von dem her habe ich diese Tatsache einfach mal außen vor gelassen ;)

AXMD


Calculon - Mi 21.11.07 14:21

@AXMD: Mit dem modulo-Operator hab' ich in dieser Hinsicht auch schlechte Erfahrungen gemacht aus eben von ene genanntem Grund. Da komm' ich auch immer total durcheinander. Ich suche eine Möglichkeit wie ich solche Probleme ein für alle mal bewältigen kann.

@Narses: Wie funktioniert das mit der Indexarithmetik. Auch mit Schleifen? Hast du ein paar keywords oder Beispiele?

Gruß

Calculon
--


Narses - Mi 21.11.07 14:27

Moin!

user profile iconCalculon hat folgendes geschrieben:
@AXMD: Mit dem modulo-Operator hab' ich in dieser Hinsicht auch schlechte Erfahrungen gemacht aus eben von ene genanntem Grund. Da komm' ich auch immer total durcheinander. Ich suche eine Möglichkeit wie ich solche Probleme ein für alle mal bewältigen kann.
:| :gruebel:

user profile iconCalculon hat folgendes geschrieben:
@Narses: Wie funktioniert das mit der Indexarithmetik. Auch mit Schleifen? Hast du ein paar keywords oder Beispiele?
Wenn du immer Gruppen aus 6 Zeilen in der Liste hast, dann kannst du doch die Indices der einzelnen Elemente einer Gruppe berechnen:

Delphi-Quelltext
1:
2:
3:
4:
5:
for i := 0 to (ListLen div 6) -1 do begin
  ShowMessage(List.Strings[i*6 +0]);
  ShowMessage(List.Strings[i*6 +1]);
  ShowMessage(List.Strings[i*6 +2]);
...

cu
Narses


Calculon - Mi 21.11.07 14:41

Also, vielen Dank. Die entscheidende Info, die mir gefehlt hat (oder ich mir nicht selbst zusammenreimen konnte) ist folgende: for i := 0 to (ListLen div 6) -1 do begin

Ich habe es jetzt so und es funktioniert wunderbar:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
  for i := 0 to (first.Count div 6) - 1 do
    begin
      memo1.Lines.Add('xTra:' + first.Strings[i*6 + 0]);
      memo1.Lines.Add('yTra:' + first.Strings[i*6 + 1]);
      memo1.Lines.Add('zTra:' + first.Strings[i*6 + 2]);
      memo1.Lines.Add('xRot:' + first.Strings[i*6 + 3]);
      //memo1.Lines.Add('yRot:' + first.Strings[i*6 + 4]);
      //memo1.Lines.Add('zRot:' + first.Strings[i*6 + 5]);
    end;


Thx @all!

Gruß

Calculon
--