AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Monatskürzel "Jan".."Dec" in 01..12 umwandeln
Thema durchsuchen
Ansicht
Themen-Optionen

Monatskürzel "Jan".."Dec" in 01..12 umwandeln

Ein Thema von Steffen · begonnen am 28. Jan 2004 · letzter Beitrag vom 2. Feb 2004
Antwort Antwort
Seite 2 von 4     12 34      
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#11

Re: Monatskürzel "Jan".."Dec" in 01..12

  Alt 29. Jan 2004, 02:29
Delphi-Quellcode:
function IndexOfMonth(const Name: String): Integer;
begin
  Result := Pos('.' + AnsiUpperCase(Name) + '.', '.JAN.FEB.MAR.APR.MAY.JUN.JUL.AUG.SEP.OCT.NOV.DEC.');
  if Result > 0 then Result := (Result -1) div 4 +1;
end;
Gruß Hagen
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#12

Re: Monatskürzel "Jan".."Dec" in 01..12

  Alt 29. Jan 2004, 08:32
Hallo Leuselator hallo Steffen,

falls ihr Euch für eine Variante mit case entscheiden solltest, wäre es von Vorteil, wenn Ihr in Euren Schleifen von oben nach unten iteriert. Es wird so nicht nur etwas übersichtlicher
Delphi-Quellcode:
function IndexOfArrayItem(const AnArray : array of string;
  const AnItem : string):Integer;
begin
  Result := High(TheArray);
  while (Result >= Low(AnArray)) and (AnArray[Result] <> AnItem)
    do Dec(Result);
end;
sondern bei großen Arrays ggf schneller, weil
Result >= Low(AnArray) lediglich Result gegen null testet, wohingegen ggf (sofern zB nicht mit const gearbeitet wird, wie von Leuselator gezeigt)
Result <= High(AnArray) jedesmal einen Speicherzugriff verursacht...

Wenn ich das ich richtig sehe, Steffen, besitzt Du D7E. Dort sollte es eine überladene Variante von StrToDate geben, die mit eigenen Format-Einstellungen arbeiten kann. Für eine solche Verwendung könntest Du Dir mit GetLocaleFormatSettings die entsprechenden US-Einstellungen in einer Variablen halten und Deine Umformung, durch eine Funktion gewrappt wie folgt gestalten:
Delphi-Quellcode:
function MyStringToDate(const AString: string): TDate;
begin
  Result:= StringToDate(AString, MyStoredSettings);
end;
gruß, choose
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#13

Re: Monatskürzel "Jan".."Dec" in 01..12

  Alt 29. Jan 2004, 08:47
BTW, in der Unit StrUtils gibt es bereits die beiden Funktionen AnsiMatchStr und AnsiMatchStr:
Zitat von OH:
Mit ~ können Sie ermitteln, ob der String AText im Array AValues enthalten ist [und dessen Index ermitteln]
gruß, choose
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#14

Re: Monatskürzel "Jan".."Dec" in 01..12

  Alt 30. Jan 2004, 05:41
@choose, deine Annahme das das Runterzählen schneller ist ist einfach falsch.

1.) Da du Result als Zählervariable benutzt verhinderst du das der Compiler den Code besser optimieren kann
2.) WENN der Compiler optimieren kann dann würde er schnelleren Code mit einer simplen for to Schleife erzeugen. In diesem Beispiel würde er Assemblercode erzeugen der auch gegen Null überprüft
3.) Eine BottomUp Schleife ist Cache-unfreundlich

besser ist folgender Code
Delphi-Quellcode:
var
  I: Integer;
begin
  for I := Low() to High() do
    if Data[I] = XYZ then
    begin
      Result := I;
      Exit;
    end;
end;
Gruß Hagen
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#15

Re: Monatskürzel "Jan".."Dec" in 01..12

  Alt 30. Jan 2004, 08:41
Hallo Hagen,

im Vordergrund stand bei meiner Antwort die Übersichtlichkeit des Quellcodes
Zitat:
Es wird so nicht nur etwas übersichtlicher, sondern ggf auch etwas schneller
ich wollte somit keinesfalls "die performanteste Lösung" aufzeigen, sondern einen brauchbaren Kompromiss.
Zitat von negaH:
Da du Result als Zählervariable benutzt verhinderst du das der Compiler den Code besser optimieren kann
Das stimmt und dient der Übersichtlichkeit. Es ist wahr, dass auch die Speicherung von Zwischenwerten in Result als umstritten gilt, ich persönlich finde jedoch ein Kontrukt der Art
Delphi-Quellcode:
function MyProc: Integer;
begin
  Result:= 0;
  while SomeCriteria do
    Inc(Result);
end;
übersichtlicher als
Delphi-Quellcode:
function MyProc: Integer;
var
  myExtension: Integer;
begin
  myExtension:= 0;
  while SomeCriteria do
    Inc(myExtension);
  Result:= myExtension;
end;
Zitat von negaH:
der Compiler [..] würde [..] schnelleren Code mit einer simplen for to Schleife erzeugen.
Das stimmt, auch hier wirkt eine Lösung mit Exit oder Break eher als Kunstgriff und dient als Hauptzweck der Performancesteigerung. Ich möchte keine Diskussion über Ästhetik anzetteln, aber nach der Klassischen Auffassung sollten For-Schleifen genau dann eingesetzt werden, wenn die Anzahl der Iterationen bekannt ist, was hier nicht der Fall ist. Break und Exit eignen sich häufig in komplexeren Fällen, um Kontrollstrukturen zu verlassen, die Abbruchbedingung dieser Schleife hingegen lässt sich "sauber" definieren, so dass die Veränderung der Ablaufsteuerung ausschließlich der Performancesteigerung dient.
Tatsächlich ist die For-Schleife nicht nur bei der Abbruchbedingung genauso performant wie die TopDown lösung, sich arbeitet sogar direkt mit einem Index im array, so dass die Errechnung selbigens bei der While-Schleife entfält.
Code:
[b]DoSthWithStr(AnArray[myIndex])[/b]
  mov EAX, [EBX]
  call DoSthWithStr
  add EBX, $04
innerhalb der For-Schleife und dagegen die errechnung des Indexes innerhalb der Whileschleife:
Code:
[b]DoSthWithStr(AnArray[myIndex])[/b]
  mov EAX, [EBP-$04]
  mov EAX, [EAX+EBX*4]
  call DoSthWithStr
  inc EBX
Zitat von negaH:
Eine BottomUp Schleife ist Cache-unfreundlich
Ich simmte Dir iA zu, allerdings arbeiten wir hier mit Strings, die idR wahllos auf dem Heap platziert sind, so dass bei der Verarbeitung der Strings ohnehin ungeordnet Speicherzugriffe stattfinden. Lediglich die Referenzen nicht aber der im Verhätnis zu ihnen große Speicherbereich zur tatsächlichen Verarbeitung (vergleichen, verlängern, kürzen, etc) könnte somit cache-freundlich Bearbeitet werden.


Für performancekritische Lösungen des ursprünglichen Problems von Steffen würde ich ebenfalls eine Lösung der von Dir vorgeschlagenen Art verwenden, jedoch mit einem besseren Match-Algorithmus als der in Pos implementierte, bspw einer modifizierte Version des Boyer-Moore-Algorithmus oder einer Form des Hashings...
gruß, choose
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#16

Re: Monatskürzel "Jan".."Dec" in 01..12

  Alt 30. Jan 2004, 08:57
Zitat:
Für performancekritische Lösungen des ursprünglichen Problems von Steffen würde ich ebenfalls eine Lösung der von Dir vorgeschlagenen Art verwenden, jedoch mit einem besseren Match-Algorithmus als der in Pos implementierte, bspw einer modifizierte Version des Boyer-Moore-Algorithmus oder einer Form des Hashings...
Wie ? um mal eben 12 Monatsnamen in eine Zahl umzuwandeln ? Alleine der Overhead um den Boyer-More zu initialisieren dauert länger als eine Pos() Funktion die sequentiell in 49 Bytes sucht.

Zitat:
..wenn die Anzahl der Iterationen bekannt ist, was hier nicht der Fall ist..
Wieso ? Es sind exakt 12 Iteration maximal. Damit ist es also auch sinnvoll eine for I := 1 to 12 Schleife zu benutzen und bei Übereinstimmung abzubrechen.

Ich verstehe deine Motive saubern Code zu produzieren sehr gut, bin ja selber ein Pedant , ABER ich kann dir nicht zustimmen in dem Punkt das bedingte Schleifen wie while do/repeat until einfachere Schleifen sind als normale Zählschleifen.

Gruß Hagen
  Mit Zitat antworten Zitat
Benutzerbild von Leuselator
Leuselator

Registriert seit: 18. Mär 2003
Ort: Berlin
589 Beiträge
 
Delphi 8 Architect
 
#17

Re: Monatskürzel "Jan".."Dec" in 01..12

  Alt 30. Jan 2004, 09:32
*räusper*
Ehm - ich bin schuld !

Habe das Problem von Mücke zum Elefanten aufgeblasen, weil ich eine allgemeinere Funktion wie IndexOf bei TList für Arrays anbieten wollte. Der Code stimmt ziemlich genau mit dem der VCL zu TList.IndexOf überein. Nicht ganz klar ist mir in der losgetretenen Disskusion die Sache mit dem Prüfen gegen Null, da Low(AnArray) doch nicht zwangsläufig 0 sein muß?

Ich finde es allemal interessant, wie viele verschiedene Wege nach Rom es doch gibt - dieser Thread kann als gutes Beispiel dienen, wenn man einem Nichtprogrammierer erklären möchte, warum Softwareentwicklung immer auch stark die individuellen Denkstrukturen der beteiligten Programmierer widerspiegelt.

Also bitte nicht mehr streiten
Gruß
Tim Leuschner
Programmierer = moderner Sysiphos: stets wenn er meint, den Stein seiner Dummheit auf den Berg des Wissens gewuchtet zu haben, erblickt er einen völlig neuen Aspekt und der Dummfels poltert mit Getöse zurück ins Tal der Unwissenheit...
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#18

Re: Monatskürzel "Jan".."Dec" in 01..12

  Alt 30. Jan 2004, 09:36
Zitat von negaH:
Alleine der Overhead um den Boyer-More zu initialisieren dauert länger
Für das Problem der kurzen konstanten Elemente gleicher Länge und geringer Anzahl hat Du mit Sicherheit Recht. Vielleicht doch ein Hashing, in dem konkreten Fall kann der gesamte String sogar auf ein DWord gemappt werden, so dass das Hashing eineindeutig und trivial zu errechnen ist, ohne dass die Übersichtlichkeit verloren geht (die Klammerung soll denjenigen Helfen, die sich bei der Priorität der Operatoren nicht sicher fühlen):
Delphi-Quellcode:
function IndexOfMonth(const AName: String): Integer;
const
  Hash_Jan = (Ord('J') shl 16) or (Ord('A') shl 8) or Ord('N');
  Hash_Feb = (Ord('F') shl 16) or (Ord('E') shl 8) or Ord('B');
  Hash_Mar = (Ord('M') shl 16) or (Ord('A') shl 8) or Ord('R');
  Hash_Apr = (Ord('A') shl 16) or (Ord('P') shl 8) or Ord('R');
  Hash_May = (Ord('M') shl 16) or (Ord('A') shl 8) or Ord('Y');
  Hash_Jun = (Ord('J') shl 16) or (Ord('U') shl 8) or Ord('N');
  Hash_Jul = (Ord('J') shl 16) or (Ord('U') shl 8) or Ord('L');
  Hash_Aug = (Ord('A') shl 16) or (Ord('U') shl 8) or Ord('G');
  Hash_Sep = (Ord('S') shl 16) or (Ord('E') shl 8) or Ord('P');
  Hash_Oct = (Ord('O') shl 16) or (Ord('C') shl 8) or Ord('T');
  Hash_Nov = (Ord('N') shl 16) or (Ord('O') shl 8) or Ord('V');
  Hash_Dec = (Ord('D') shl 16) or (Ord('E') shl 8) or Ord('C');

begin
  if Length(AName)<>3 then
    Result:= 0
  else
    case (Ord(UpCase(AName[1])) shl 16) or
         (Ord(UpCase(AName[2])) shl 8 ) or
          Ord(UpCase(AName[3])) of
      Hash_Jan: Result:= 1;
      Hash_Feb: Result:= 2;
      Hash_Mar: Result:= 3;
      Hash_Apr: Result:= 4;
      Hash_May: Result:= 5;
      Hash_Jun: Result:= 6;
      Hash_Jul: Result:= 7;
      Hash_Aug: Result:= 8;
      Hash_Sep: Result:= 9;
      Hash_Oct: Result:= 10;
      Hash_Nov: Result:= 11;
      Hash_Dec: Result:= 12;
    else
      Result:= 0;
  end;
end;
Zitat von negaH:
Wieso [die anzahl der Iterationen ist doch bekannt]? Es sind exakt 12 Iteration maximal.
Die Formulierungen "exakt p" und "genau p" sind nach meinem (mathematischen) Empfinden synonym zu "p und nur p" zu verwenden und sind nicht äquivalent zu "p oder maximal p". Um genau zu sein, entspricht die Aussage "p oder maximal p" der Aussage "maximal p"
Formal:
Code:
 x=p v x<=p <=> x<=p != x=p
und damit ist die Anzahl der Iterationen nicht bekannt.

Zitat von negaH:
ich kann dir nicht zustimmen [..] das bedingte Schleifen [..] einfachere Schleifen sind als [..] Zählschleifen.
Das habe ich auch nicht behauptet. In Deinem Fall allerdings verwendest Du zu eine Schleife mit einer nach Definition genauen Anzahl von Iterationen mit einer zusätzlichen Fallunterscheidung und einem Konstrukt, dass noch nicht einmal in jeder Programmiersprache vorgesehen ist, dazu, etwas zu tun, wofür eine andere Schleifenform definiert worden ist, nämlich dem Iterieren bis eine bei jeder Iteration zu berechnenen Abbruchbedingung erfüllt ist.
gruß, choose
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#19

Re: Monatskürzel "Jan".."Dec" in 01..12

  Alt 30. Jan 2004, 09:41
Hallo Leuselator,
Zitat von Leuselator:
Nicht ganz klar ist mir [..] die Sache mit dem Prüfen gegen Null, da Low(AnArray) doch nicht zwangsläufig 0 sein muß?
es handelt sich um einen offenen Array-Parameter zu der in der OH folgendes zu lesen ist:
Zitat von OH:
Sie sind stets nullbasiert. Das erste Element trägt immer die Indexnummer 0, das zweite die 1 usw. Die Standardfunktionen Low und High geben 0 bzw. Length - 1 zurück. Die Funktion SizeOf gibt die Größe des Arrays zurück, das an die Routine übergeben wird.
Zitat von Leuselator:
Also bitte nicht mehr streiten
Ich empfinde die Beiträge eher als ansprechende Diskussion (nein, das ist nicht euphemistisch gefärbt) und freue mich immer zu neuen Ansätzen angeregt zu werden
gruß, choose
  Mit Zitat antworten Zitat
Steffen

Registriert seit: 19. Mär 2003
Ort: Hamburg
111 Beiträge
 
Delphi 7 Enterprise
 
#20

Re: Monatskürzel "Jan".."Dec" in 01..12

  Alt 2. Feb 2004, 13:04
Danke für die Zahlreichen Antworten...!

Nun weiß ich aber nicht, welcher Lösungsansatz nun wirklich der einfachste, beste und schnellste weg zur Lösung ist.
Wie soll ich wissen was ich denke, bevor ich höre was ich sage?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 4     12 34      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:25 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz