Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Erstellung einer Funktion (https://www.delphipraxis.net/208065-erstellung-einer-funktion.html)

Mo53 6. Jun 2021 12:37

AW: Erstellung einer Funktion
 
Kann man das denn so regeln das die längste Ziffernfolge auf Basis des Strings bestimmt wird aber ein word-Wert zurückgegeben wird also z.B. wenn die längste Ziffernfolge 012 ist wird eine 12 zurückgegeben ?

Delphi.Narium 6. Jun 2021 13:10

AW: Erstellung einer Funktion
 
Ja, aber die hier genannten führenden Nullen gehen dabei verloren:
Zitat:

Die längste Ziffernfolge muß nicht unbedingt die größte Zahl in s sein! Eine so gefundene Ziffernfolge darf auch mit einer oder mehreren '0' beginnen.
Man könnte aus dem String die führenden Nullen entfernen, man könnte den String in eine Zahl umwandeln.

Nur: Soll die längste Ziffernfolge zurückgegeben werden oder ihr nummericher Wert?

Die Frage ist also: Was ist jetzt bitteschön die Aufgabenstellung und welche Syntaxelemente wurden bisher im Lehrstoff vermittelt und welche Syntaxelemente dürfen für die Lösung der Aufgabe verwendet werden?

Soll das Problem mit while, for, repeat, if und / oder case gelöst werden, dürfen Arrays genutzt werden, ist die Nutzung von Zeigern erlaubt? Dürfen alle delphiseitig möglichen Datentypen genutzt werden oder nur die bisher im Lehrstoff vermittelten? Sind Typkonvertierungen (beliebiger Form) Teil des Unterrichtsstoffes, ...?

Sprich: Darf alles genutzt werden, was mit Delphi möglich ist oder gibt es irgendwelche klar definierten Vorgaben?
Delphi-Quellcode:
// function longestNumber(s : string) : byte;
// Rückgabetype der Funktion ändern, da ja eine Zeichenfolge zurückgegeben werden soll.
function longestNumber(s : string) : String;
var
  run, number, longNum : byte;
  NumberStr, longNumStr : String; // zwei zusätzliche Variabeln.
  begin
    // Zu Beginn alle Variabeln initialisieren, um definierte Ausgangswerte zu haben.
    longNum := 0;
    longNumStr := '';
    number := 0;
    NumberStr := '';
    for run := 1 to length(s) do
    begin
      case s[run] of
       '0'..'9' : begin
                    inc(number);
                    NumberStr := NumberStr + s[run]; // Zusätzlich die Ziffer an den String anfügen.
                  end;
      else
        begin
          if number > longNum then
          begin
            longNum := number;
            LongNumStr := NumberStr; // zusätzlich den bisher längsten String speichern.
          end;        
          number := 0;
          NumberStr := ''; // zusätzlich den String leeren.
        end;
      end;
    end;
    if number > longNum then
    begin
      longNum := number;
      LongNumStr := NumberStr; // zusätzlich den bisher längsten String speichern.
    end;
    // longestNumber := longNum;
    // Da eine Zeichenfolge zurückgegeben werden soll und der Typ der Funktion
    // entsprechend geändert wurde, geben wir hier die Zeichenfolge zurück.
    longestNumber := longNumStr;
  end;
Und ja: Unter Performanzgesichtspunkten mag das eventuell (messbar?) langsamer sein. Und mit PChar und Zeigern geht es eventuell auch eleganter, ...

Frage ist nur: Was bitte wurde bisher im Unterricht vermittelt und kann von daher für die Lösungssuche zur Anwendung kommen?

Mo53 6. Jun 2021 14:05

AW: Erstellung einer Funktion
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1490756)
Was ist jetzt bitteschön die Aufgabenstellung und welche Syntaxelemente wurden bisher im Lehrstoff vermittelt und welche Syntaxelemente dürfen für die Lösung der Aufgabe verwendet werden?

Es sind verschiedene Prozeduren und Funktionen samt zugehörigen Testfällen zu erstellen, die mit Strings arbeiten. Diese sollen sich wo immer möglich auch gegenseitig aufrufen, um den zu erstellenden Code kurz zu halten (Codeverdopplung ist zu vermeiden!).
Beachtet bei der Entwicklung die vorgesehene Reihenfolge (s.u.): Erstellt ERST die Testfälle und DANN die eigentlichen Funktionen und Prozeduren! Somit macht Ihr Euch rechtzeitig vorab Gedanken, was genau eine Funktion/Prozedur können soll und schreibt nicht unnötig viel Quellcode.

Zusätzlich zum Hauptprogramm sind mehrere Prozeduren und Funktionen zu erstellen

Eine davon ist

''function longestNumber(s : string) : word;
Sucht die längste Ziffernfolge (aus Ziffern von '0' bis '9') im String s. Gibt es mehrere gleich lange, wird davon die erste zurückgegeben. Sind keine Ziffern enthalten, gibt die Funktion den Wert 0 zurück.
Hinweis: Die längste Ziffernfolge muß nicht unbedingt die größte Zahl in s sein! Eine so gefundene Ziffernfolge darf auch mit einer oder mehreren '0' beginnen.''

bei der ich Probleme habe, das restliche Programm und die restlichen sechs Funktionen/Prozeduren sind fertig.

Arrays dürfen nicht verwendet werden und die vorgegebene Funktion ''function longestNumber(s : string) : word'' darf nicht verändert werden also der Datentyp word muss word bleiben.
Ansonsten ist es uns überlassen was wir verwenden.

:)

Michael II 6. Jun 2021 14:10

AW: Erstellung einer Funktion
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1490756)
Die Frage ist also: Was ist jetzt bitteschön die Aufgabenstellung und welche Syntaxelemente wurden bisher im Lehrstoff vermittelt und welche Syntaxelemente dürfen für die Lösung der Aufgabe verwendet werden?

Es geht hier doch nicht um echte Aufgaben; mo will lediglich eine kleine Untermenge von DP Menschen unterhalten ;-).

Zitat:

Und ja: Unter Performanzgesichtspunkten mag das eventuell (messbar?) langsamer sein. Und mit PChar und Zeigern geht es eventuell auch eleganter, ...
Ich hatte auch an Pointer gedacht, vermutete aber, dass diese wohl noch nicht Teil von mos Delphi-Welt sein dürfen und habe keine verwendet. Punkto Performance gewinnst du hier kaum was oder gar nix.

Zur Performance: Deine Lösung hängt v.a. wegen NumberStr := NumberStr + s[run]; erheblich vom Eingabewert ab und ist v.a. wegen dieser Zeile etwas komplexer: Wenn in den 1000 x "1Mio-Strings Aufrufen" die Eingabe gar keine Ziffern enthält liegt meine bei 990ms und deine bei 4400ms. Bei 60% Ziffern 4,3sec, deine 31sec. Wenn nur Ziffern vorkommen, dann liegt meine bei 1.6sec und deine bei (erwartet hohen) 40sec.

NumberStr := NumberStr + s[run]; ist unnötig und langsam. mo soll sich nur Start und Länge des jeweiligen Maximums merken. Das reicht um am Ende der Suche die längste Ziffernfolge zu "berechnen" (entweder mit Copy oder wenn Copy nicht erlaubt ist mit for i:= start to ...) und auszugeben.

Nebenbei: Wegen run: Byte kann deine Routine nur kurze Strings verarbeiten.

Zitat:

Zitat von Mo53 (Beitrag 1490757)
Hinweis: Die längste Ziffernfolge muß nicht unbedingt die größte Zahl in s sein! Eine so gefundene Ziffernfolge darf auch mit einer oder mehreren '0' beginnen.''

mo, du wolltest die Strings in Zahlen umwandeln. Das geht mit Standard-Integer Typen nur gut, wenn der numerische Wert der gefundenen Folge nicht allzu gross ist: WORD zum Beispiel ist 16 Bit breit und kann nur Werte 0..65535 aufnehmen. Für die Umwandlung: Suche im Help von Delphi nach strtoint(), strtointdef() oder schreib dir als Übung eine Funktion, welche dies tut.

Ich bin hier raus. Viel Spass bei den weiteren Hausaufgaben. Ich freue mich bereits aufs nächste Wochenende.

Delphi.Narium 6. Jun 2021 14:50

AW: Erstellung einer Funktion
 
Zitat:

''function longestNumber(s : string) : word;
Sucht die längste Ziffernfolge (aus Ziffern von '0' bis '9') im String s. Gibt es mehrere gleich lange, wird davon die erste zurückgegeben. Sind keine Ziffern enthalten, gibt die Funktion den Wert 0 zurück.
Hinweis: Die längste Ziffernfolge muß nicht unbedingt die größte Zahl in s sein! Eine so gefundene Ziffernfolge darf auch mit einer oder mehreren '0' beginnen.''
Das verstehe ich nicht:

Eine Ziffernfolge darf mit Nullen beginnen, gut und schön.

Wenn ich als Rückgabewert Word verwende, so gehen führende Nullen verloren. Es kann somit als Word also nur der nummerische Wert der längsten Ziffernfolge zurückgegeben werden. Dabei muss es sich dann aber nicht zwingend um den größten Wert aus allen Ziffernfolgen handeln.
Delphi-Quellcode:
a00000000001b65535c4812
gäbe dann 1 zurück, auch wenn die zweite Ziffernfolge einen größeren Wert repräsentiert.

Wenn der Rückgabewert 0 sein soll, sofern keine Ziffernfolge im String enthalten ist, wäre das Ergebnis der Funktion bei dem String
Delphi-Quellcode:
a00000000000b0000c00
aber nicht mehr eindeutig, da hier ja die Ziffernfolgen alle (als numerische Werte dargestellt) 0 ergeben. Eine Unterscheidung zwischen "Keine Ziffernfolge im String enthalten." und "Die längste Ziffernfolge besteht nur aus Nullen.", wäre nicht mehr möglich.

Da der Rückgabewert der Funktion Word sein soll, würde die Routine bei der Zeichenfolge
Delphi-Quellcode:
a1b99999
scheitern, da 99999 mehr ist, als mit dem Datentyp Word dargestellt werden kann.

Irgendwie ist mir die Aufgabenstellung zu unpräzise, bzw. fehlt zuviel Wissen über den Umfang des bisher vermittelten Stoffes.

Eine Möglichkeit als Ergebnis ein Word zu liefern und gleichzeitig die längste Ziffernfolge zu liefern ginge über Var-Parameter (aber da weiß ich nun garnichtmehr, ob Ihr das schon hattet und ich mit dem folgendem Lösungsvorschlag nunmehr für absolute Verwirrung sorge):
Delphi-Quellcode:
function longestNumber(s : string; var longNumStr : String) : word;
var
  run, number, longNum : Word;
  NumberStr : String;
  begin
    // Zu Beginn alle Variabeln initialisieren, um definierte Ausgangswerte zu haben.
    longNum := 0;
    longNumStr := '';
    number := 0;
    NumberStr := '';
    for run := 1 to length(s) do
    begin
      case s[run] of
       '0'..'9' : begin
                    inc(number);
                    NumberStr := NumberStr + s[run]; // Zusätzlich die Ziffer an den String anfügen.
                  end;
      else
        begin
          if number > longNum then
          begin
            longNum := number;
            LongNumStr := NumberStr; // den bisher längsten String speichern.
          end;
          number := 0;
          NumberStr := ''; // den String leeren.
        end;
      end;
    end;
    if number > longNum then
    begin
      longNum := number;
      LongNumStr := NumberStr; // den bisher längsten String speichern.
    end;
    longestNumber := longNum; // Länge der längsten Ziffernfolge zurückgeben.
  end;
Die Funktion benötigt beim Aufruf also zwei Parameter vom Typ String. Eine Ausgabe des Funktionsergebnisses über WriteLn wäre damit dann aber nichtmehr zielführend.
Delphi-Quellcode:
procedure printInfos(s: string);
var
  LongNum : Word;
  LongNumStr : String;
begin
  LongNum := longestnumber(s, LongNumStr);
  writeln('String: ', s, ' Ziffern: ', countDigits(s), ' Gerade: ',
    countEvenDigits(s), ' Ungerade: ', countOddDigits(s), ' Andere: ', countNonDigits(s),
    ' Längste: ',LongNumStr,' ist ',LongNum, ' Zeichen lang, Ohne: ',deleteDigits(s));
end;
Aber ist das jetzt wirklich noch im Umfang des bisher vermittelten Stoffes?
Und ist es überhaupt noch eine akzeptable Lösung?

Mo53 6. Jun 2021 16:14

AW: Erstellung einer Funktion
 
var parameter hatten wir, dürfen wir auch verwenden, wir hatten so gut wie alles außer arrays.
Nur das Problem ist das wir die Funktion nicht verändern dürfen, also auch keinen neuen Parameter rein.

Amateurprofi 6. Jun 2021 16:37

AW: Erstellung einer Funktion
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Michael II (Beitrag 1490745)
Zitat:

Zitat von Amateurprofi (Beitrag 1490743)
Oder so:

Nicht "oder so", sondern nur so wie Profi ;-).
Es gibt allerdings einen Unterschied: #37 liefert wie in #26 verlangt den String, #38 die Position.
Zeitlich bewegen wir uns im gleichen Rahmen. Profi nutzt aus, dass Strings Null-terminiert sind, muss aber die =#0 Abfrage bei jedem Zeichen ausführen, #37 "einmal" am Schluss *.

Hallo Michael,
Zu "#37 liefert wie in #26 verlangt den String, #38 die Position"
Nee, #28 liefert die Länge der Ziffernfolge
Um die Ziffernfolge selbst zu liefern, bedarf es einiger kleiner Änderungen.
Hier die Funktion, die die Ziffernfolge liefert
Delphi-Quellcode:
FUNCTION LongestCipherSequence(const S:String):String;
var MaxLen:Integer; P,PS,PSMax,PStart:PChar;
begin
   MaxLen:=0;
   PStart:=PChar(S);
   P:=PStart;
   if P<>Nil then
      repeat
         case P^ of
            #0       : Break;
            '0'..'9' : begin
                           PS:=P;
                           Inc(P);
                           while P^ in ['0'..'9'] do Inc(P);
                           if P-PS>MaxLen then begin
                              MaxLen:=P-PS;
                              PSMax:=PS;
                           end;
                        end;
            else       Inc(P);
         end;
      until False;
   if MaxLen=0 then Result:=''
      else Result:=Copy(S,PSMax-PStart+1,MaxLen);
end;
Zu "muss aber die =#0 Abfrage bei jedem Zeichen ausführen, #37 "einmal" am Schluss"
Nee, stimmt nicht.
Beim While wird ebenfalls bei jedem Zeichen geprüft, ob I >= len_s ist.
Vom Zeitaufwand her macht das keinen Unterschied.

Ich habe mal kurz das Zeitverhalten getestet. Gleiche Größenordung bei beiden Funktionen.
Ergebnis siehe Anhang:

Man könnte das Zeitverhalten noch optimieren:
Wenn bereits eine Ziffernfolge gefunden wurde, kann man beim Finden der nächsten Ziffer prüfen, ob das Zeichen an P+Maxlen eine Ziffer ist.
Wenn nicht, kann die Ziffernfolge nicht länger sein, als die bisher längste.
Dann kann man P = P+MaxLen setzen, muss also nicht jedes Zeichen separat prüfen.
Das lohnt sich aber nur, wenn wirklich lange Strings mit vielen Ziffern geprüft werden sollen, ansonsten wird das eher zu einem höheren Zeitbedarf führen.


Delphi-Quellcode:
PROCEDURE TMain.Test;
const Lines=10000; MaxLen=200; Rnd=12; Count=1000;
var I,J,Len:Integer; T0,T1,T2:Cardinal; S:String; List:TStrings;
begin
   List:=TStringList.Create;
   for I:=1 to Lines do begin
      Len:=Random(MaxLen);
      SetLength(S,Len);
      for J:=1 to Len do
         S[J]:=Char(Random(Rnd)+Ord('0'));
      List.Add(S)
   end;
   T0:=GetTickCount;
   for I:=1 to Count do
      for J:=0 to List.Count-1 do
         LongestCipherSequence(List[J]);
   T1:=GetTickCount;
   for I:=1 to Count do
      for J:=0 to List.Count-1 do
      LaengsteZiffernFolgeDerWelt(List[J]);
   T2:=GetTickCount;
   ShowMessage(IntToStr(T1-T0)+' LongestCipherSequence'#13+
               IntToStr(T2-T1)+' LaengsteZiffernFolgeDerWelt');
   List.Free;
end;

Delphi.Narium 6. Jun 2021 16:40

AW: Erstellung einer Funktion
 
Dann fällt mir nurnoch dashier ein:
Delphi-Quellcode:
function longestNumber(s : string) : word;
var
  run, number, longNum : Word;
  NumberStr : String;
  longNumStr : String
  begin
    // Zu Beginn alle Variabeln initialisieren, um definierte Ausgangswerte zu haben.
    longNum := 0;
    longNumStr := '';
    number := 0;
    NumberStr := '';
    for run := 1 to length(s) do
    begin
      case s[run] of
       '0'..'9' : begin
                    inc(number);
                    NumberStr := NumberStr + s[run]; // Zusätzlich die Ziffer an den String anfügen.
                  end;
      else
        begin
          if number > longNum then
          begin
            longNum := number;
            LongNumStr := NumberStr; // den bisher längsten String speichern.
          end;
          number := 0;
          NumberStr := ''; // den String leeren.
        end;
      end;
    end;
    if number > longNum then
    begin
      LongNumStr := NumberStr; // den bisher längsten String speichern.
    end;
    longestNumber := StrToInt(longNumStr); // längste Ziffernfolge als Zahl zurückgeben.
  end;

Amateurprofi 7. Jun 2021 01:09

AW: Erstellung einer Funktion
 
Zitat:

Zitat von Mo53 (Beitrag 1490757)
Zitat:

Zitat von Delphi.Narium (Beitrag 1490756)
Was ist jetzt bitteschön die Aufgabenstellung und welche Syntaxelemente wurden bisher im Lehrstoff vermittelt und welche Syntaxelemente dürfen für die Lösung der Aufgabe verwendet werden?

Es sind verschiedene Prozeduren und Funktionen samt zugehörigen Testfällen zu erstellen, die mit Strings arbeiten. Diese sollen sich wo immer möglich auch gegenseitig aufrufen, um den zu erstellenden Code kurz zu halten (Codeverdopplung ist zu vermeiden!).
Beachtet bei der Entwicklung die vorgesehene Reihenfolge (s.u.): Erstellt ERST die Testfälle und DANN die eigentlichen Funktionen und Prozeduren! Somit macht Ihr Euch rechtzeitig vorab Gedanken, was genau eine Funktion/Prozedur können soll und schreibt nicht unnötig viel Quellcode.

Zusätzlich zum Hauptprogramm sind mehrere Prozeduren und Funktionen zu erstellen

Eine davon ist

''function longestNumber(s : string) : word;
Sucht die längste Ziffernfolge (aus Ziffern von '0' bis '9') im String s. Gibt es mehrere gleich lange, wird davon die erste zurückgegeben. Sind keine Ziffern enthalten, gibt die Funktion den Wert 0 zurück.
Hinweis: Die längste Ziffernfolge muß nicht unbedingt die größte Zahl in s sein! Eine so gefundene Ziffernfolge darf auch mit einer oder mehreren '0' beginnen.''

bei der ich Probleme habe, das restliche Programm und die restlichen sechs Funktionen/Prozeduren sind fertig.

Arrays dürfen nicht verwendet werden und die vorgegebene Funktion ''function longestNumber(s : string) : word'' darf nicht verändert werden also der Datentyp word muss word bleiben.
Ansonsten ist es uns überlassen was wir verwenden.

:)

Die beiden in #38 gezeigten Funktionen machen genau das, geben also die Länge der längsten Ziffernfolge zurück.
Also nimm eine der beiden Funktionen (besser die untere), ändere den Namen auf "longestNumber", beim Parameter entferne das "const" und ändere das Funktionsergebnis auf "Word".
Stellt sich mir die Frage, was passiert, wenn du einen String übergibst, bei dem die längste Ziffernfolge mehr als 65535 Ziffern hat.
Und so etwas im Fach Informatik.

Blup 7. Jun 2021 14:55

AW: Erstellung einer Funktion
 
Noch eine Variante zur Denksportaufgabe:
Delphi-Quellcode:
function longestNumber(s : string) : word;
var
  L1, L2, N: Word;
  c: Char;
  i: Integer;
begin
  Result := 0;
  L1 := 0;
  L2 := 0;
  N := 0;

  for c in s do
  begin
    {Zeichen in Ziffern-Wert umwandeln}
    i := Ord(c) - Ord('0');
    if (i >= 0) and (i <= 9) then
    begin
      {c enthält eine Ziffer, an dieser Stelle eventuell Ergenisüberlauf prüfen}
      N := N * 10 + i;
      L2 := L2 + 1;
      {Länge des Zwischenergebnis vergleichen und eventuell als Endergebnis übernehmen}
      if L2 > L1 then
      begin
        Result := N;
        L1 := L2;
      end;
    end
    else
    begin
      {c enthält keine Ziffer}
      N := 0;
      L2 := 0;
    end;
  end;
end;

Delphi.Narium 7. Jun 2021 16:11

AW: Erstellung einer Funktion
 
Zitat:

Zitat von Amateurprofi (Beitrag 1490782)
Stellt sich mir die Frage, was passiert, wenn du einen String übergibst, bei dem die längste Ziffernfolge mehr als 65535 Ziffern hat.
Und so etwas im Fach Informatik.

Es geht aber darum den nummerischen Wert der längsten Ziffernfolge in einem beliebig langen String zurückzugeben. Und da scheitern wir dann bei dem Rückgabewert 0 für keine Ziffernfolge enthalten und der nummerische Wert der längsten Ziffernfolge ist gleich 0. Das nächste Problem wäre dann noch, das Word bei Werten über 65535 nicht mehr unbedingt was verwertbares zurückgibt ;-)

Und: Aus meine Zeit, als es ums Programmierenlernen ging, war die Korrektheit der Ergebnisse nicht so wichtig. Unsere Programme wurden nicht mal kompiliert. Es ging darum zu lernen, wie man an eine Problemlösung herangeht. Und ein mögliches Ergebnis konnte durchaus auch sein: Die gestellte Aufgabe ist, unter vollständiger Beachtung der Vorgaben, nicht zu lösen.

Als Informatiker muss man eben auch sowas erkennen können. Und auch das will gelernt sein.

Und deshalb auch:
Zitat:

Zitat von Amateurprofi (Beitrag 1490782)
Und so etwas im Fach Informatik.


Michael II 7. Jun 2021 16:54

AW: Erstellung einer Funktion
 
Zitat:

Zitat von Amateurprofi (Beitrag 1490764)
Um die Ziffernfolge selbst zu liefern, bedarf es einiger kleiner Änderungen.
Hier die Funktion, die die Ziffernfolge liefert
Delphi-Quellcode:
FUNCTION LongestCipherSequence(const S:String):String;
Ich habe mal kurz das Zeitverhalten getestet. Gleiche Größenordung bei beiden Funktionen.

Apfel Birnen Vergleich wegen deinem const Aufruf:
Mit const, also so
Delphi-Quellcode:
function LaengsteZiffernFolgeDerWelt( const s : string ) : string;
ist's natürlich auch schneller.

Bei etwa 80% pseudozufällig verteilten Ziffern sind beide gleich schnell. Bei mehr als 80% Ziffernanteil deine, bei weniger meine.

Die Idee mit vorausschauender Prüfung ist schön.

Amateurprofi 8. Jun 2021 00:07

AW: Erstellung einer Funktion
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1490810)
Zitat:

Zitat von Amateurprofi (Beitrag 1490782)
Stellt sich mir die Frage, was passiert, wenn du einen String übergibst, bei dem die längste Ziffernfolge mehr als 65535 Ziffern hat.
Und so etwas im Fach Informatik.

Es geht aber darum den nummerischen Wert der längsten Ziffernfolge in einem beliebig langen String zurückzugeben. Und da scheitern wir dann bei dem Rückgabewert 0 für keine Ziffernfolge enthalten und der nummerische Wert der längsten Ziffernfolge ist gleich 0. Das nächste Problem wäre dann noch, das Word bei Werten über 65535 nicht mehr unbedingt was verwertbares zurückgibt ;-)

Da habe ich die Aufgabenstellung anders verstanden.
Mein Verständnis war dass die Länge der längsten Ziffernfolge zurückgegeben werden soll.

Michael II 8. Jun 2021 19:20

AW: Erstellung einer Funktion
 
Sehr schnelle Lösung zur Suche gelöscht.
Da dies nie gebraucht werden wird (siehe #55).
Ich will ja keinen DP Platz verschwenden.

freimatz 9. Jun 2021 07:34

AW: Erstellung einer Funktion
 
Zitat:

Zitat von Michael II (Beitrag 1490857)
Vielleicht benötigt jemand mal eine schnelle solche Suche (es müssen ja nicht Ziffern sein)... wenn's schnellere Lösungen gibt (ganz sicher ;-)), dann wäre es schön, wenn diese gepostet würden...

Ich bezweifle, dass man eine solche jemals benötigt, es sei denn zur Lösung von Hausaufgaben. ;-)
Und selbst wenn bezweifle ich dass die Geschwindigkeit eine Rolle spielt.

Ansonsten gibt es hier etliche Ideen:
https://de.wikipedia.org/wiki/String...ng-Algorithmus

TomyN 9. Jun 2021 10:03

AW: Erstellung einer Funktion
 
Hi

Ich meine, erstmal müsste man einen Testcase haben. Ich vermute, dass die Frage, was genau zurückgegeben werden soll, sich durch den Kontext der anderen Funktionen ergibt.

Dann ist ja s[x] eigentlich ein Array-Zugriff. Da wäre die Frage ist er erlaubt, oder sollte der Student (m/w/d) lernen über Zeiger auf Strings zuzugreifen?
Ich würde wahrscheinlich mit Copy und TryStrToInt (oder gehen auch Rationale Zahlen?) arbeiten.

Tomy

Delphi.Narium 9. Jun 2021 10:17

AW: Erstellung einer Funktion
 
Geht mal davon aus, dass bei Studierenden, die gerade erst Programmieren lernen, nur die einfachsten Wege beschritten werden sollen und nicht die abgefahrensten und performantesten.

Was hätten wir alle, nachdem wir so gerade mal 4 Wochen mit Pascal programmiert haben, wohl so an Lösungansätzen genutzt?
Delphi-Quellcode:
if
case
while
for
repeat
Mehr geben die momentanen Anforderungen einfach nicht her.

Selbst bei StrToInt, StrToIntDef, TryStrToInt ... hätte ich da (in Bezug auf den Lehrstand und die Anforderungen) schon meine Zweifel. Man könnte es aber auch mal mit Val und Copy versuchen ;-)

Vermutlich wird an der Hochschule Pascal gelehrt (und die einzigen(?) Entwicklungsumgebungen dazu sind halt Delphi und Lazarus / FreePascal).

So interessant, wie die "Fortgeschrittenen" Lösungsansätze auch sein mögen, sie dürften für den Beginn des Programmierenlernens doch eher eine leichte bis mittelstarke Überforderung darstellen bzw. eher für Verwirrung sorgen.

Amateurprofi 9. Jun 2021 11:27

AW: Erstellung einer Funktion
 
Zitat:

Zitat von Michael II (Beitrag 1490857)
Sehr schnelle Lösung zur Suche gelöscht.
Da dies nie gebraucht werden wird (siehe #55).
Ich will ja keinen DP Platz verschwenden.

Schade, ich hätte mich gerne bei Gelegenheit damit befasst.

Amateurprofi 10. Jun 2021 02:16

AW: Erstellung einer Funktion
 
Mich hat die Funktion "longestNumber" aus #42 interessiert.
Wegen des Kommentars
Zitat:

Unter Performanzgesichtspunkten mag das eventuell (messbar?) langsamer sein.
wollte ich das mal testen.
Hierfür habe ich mit von www.geonames.org die Datei "allCountries.txt" herunter geladen.
Das ist eine UTF8-codierte Datei (ohne BOM), die ca. 12 Mio LF-terminierte Zeilen enthält.
Die Dateigröße ist 1,563,600,457 Bytes.
Die habe ich in einen AnsiString geladen, auf den ich die Funktionen aus #37, #42 und #47 losgelassen habe.
Da die Funktionen mit Strings arbeiten, habe ich folgende Änderungen vorgenommen:
Bei #37 Parameter auf const S:AnsiString und Result auf AnsiString geändert.
Bei #42 dto und zusätzlich die lokalen Variablen "NumberStr" und "longNumStr" :auf AnsiString geändert.
Bei #47 Parameter und das Result auf AnsiString geändert und die PChars auf PAnsiChar.
Das Ergebnis:
Code:
Länge von S = 1563600457 
Zeit: 2683 ms "0020120010067" LaengsteZiffernFolgeDerWelt (Michael II #37)
Zeit:   0 ms "2986043"       longestNumber (Delphi.Narium #42)
Zeit: 2137 ms "0020120010067" LongestCipherSequence (Amateurprofi #47)
#42 braucht 0 ms was deutlich schneller ist als #37 und #47, liefert aber ein anderes Ergebnis als die beiden anderen Funktionen, die wiederum identische Ergebnisse liefern.
Hat mich na klar interessiert warum die so schnell ist.
Grund: die Variable "run" ist als Byte deklariert, was bei der Länge von S = 1563600457 ($5D32A649) bedeutet, dass nur die ersten $49 (73) Zeichen geprüft werden.
Also habe ich die Deklaration von "run" auf Integer geändert.
Ein erneuter Testlauf brachte dann
Code:
Länge von S = 1563600457
Zeit: 2699 ms "0020120010067" LaengsteZiffernFolgeDerWelt (Michael II #37)
Zeit: 21076 ms "0020120010067" longestNumber (Delphi.Narium #42)
Zeit: 2262 ms "0020120010067" LongestCipherSequence (Amateurprofi #47)
Jetzt liefern alle Funktion das gleiche Ergebnis aber #42 braucht 8 bis 9 mal so viel Zeit wie die beiden anderen Funktionen, was den Kommentar
Zitat:

Unter Performanzgesichtspunkten mag das eventuell (messbar?) langsamer sein.
bestätigte.

Die Testprozedur
Delphi-Quellcode:
PROCEDURE TMain.Test;
FUNCTION NStr(V:Cardinal; L:Integer):String;
begin
   Result:=IntToStr(V);
   Result:=StringOfChar(#$2007,L-Length(Result))+Result;
end;
FUNCTION SStr(const S:AnsiString; L:Integer):String;
begin
   Result:='"'+S+'"'+StringOfChar(#$2007,L-Length(S));
end;
const
   F1='LaengsteZiffernFolgeDerWelt (Michael II #37)';
   F2='longestNumber (Delphi.Narium #42)';
   F3='LongestCipherSequence (Amateurprofi #47)';
var NL,SL,SLen:Integer;
    T0,T1,T2,T3:Cardinal;
    Size:Int64;
    Dsn:String;
    S,S1,S2,S3:AnsiString;
    Stream:TFileStream;
begin
   Stream:=Nil;
   try
      try
         Dsn:=FilePath(BaseFilesPath,AllCountriesDsn,True);
         Stream:=TFileStream.Create(Dsn,fmOpenRead or fmShareExclusive);
         Size:=Stream.Size;
         if Size>MaxInt then
            raise Exception.Create('Datei kann nicht geladen werden, ist zu groß');
         SetLength(S,Size);
         Stream.Read(S[1],Size);
         ShowMessage('Datei geladen. Test beginnt mit OK');
         T0:=GetTickCount;
         // LaengsteZiffernFolgeDerWelt
         S1:=LaengsteZiffernFolgeDerWelt(S);
         T1:=GetTickCount;
         // longestNumber
         S2:=longestNumber(S);
         T2:=GetTickCount;
         // LongestCipherSequence
         S3:=LongestCipherSequence(S);
         T3:=GetTickCount;
         SLen:=Length(S);
         S:='';
         Dec(T3,T2);
         Dec(T2,T1);
         Dec(T1,T0);
         NL:=Length(IntToStr(Max(Max(T1,T2),T3)));
         SL:=MaxIntValue([Length(S1),Length(S2),Length(S3)]);
         ShowMessage('Länge von S = '+IntToStr(SLen)+#13+
                     'Zeit: '+NStr(T1,NL)+' ms '+SStr(S1,SL)+' '+F1+#13+
                     'Zeit: '+NStr(T2,NL)+' ms '+SStr(S2,SL)+' '+F2+#13+
                     'Zeit: '+NStr(T3,NL)+' ms '+SStr(S3,SL)+' '+F3);
      except
         on E:Exception do ShowMessage(E.Message);
      end;
   finally
      Stream.Free;
   end;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:01 Uhr.
Seite 2 von 2     12   

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