Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi "Schlossknack"-Algorithmus (https://www.delphipraxis.net/90569-schlossknack-algorithmus.html)

kalmi01 19. Apr 2007 17:59

Re: "Schlossknack"-Algorithmus
 
Hi,
hab ich da was falsch verstanden, oder geht es darum, den korrekten Code eines Zahlenschlosses zu ermitteln ?
Wenn dem so iss, wie wärs denn mit ner simplen
Delphi-Quellcode:
for i := 0 to MaxWert do ....
Schleife ?

shmia 19. Apr 2007 18:38

Re: "Schlossknack"-Algorithmus
 
Es geht auch ohne Rekursion. Man muss sich nur überlegen, was passiert,
wenn zu einer "Zahl" der Wert 1 addiert wird.
Es kann an jeder Stelle einen Übertrag geben.

Delphi-Quellcode:
{**************************************************************************
 * NAME:   IncrementWithMask
 * DESC:   erhöht eine Nummer (die als String vorliegt) um Eins
 *          Dabei darf "Number" an bestimmten Stellen auch Buchstaben enthalten
 *          "Mask" bestimmt, an welchen Positionen Ziffern oder Buchstaben erlaubt sind
 * Mask: 0 = Ziffern    (0..9)
 *        A = Buchstaben (A..Z)
 *        Z = Ziffern & Buchstaben
 *        H = Hex-Ziffern (0..9, A..F)
 *          = diese Stelle bleibt
 * PARAMS: [-]
 * RESULT: die erhöhte Nummer
 *************************************************************************}
function IncrementWithMask(const Number, Mask:string):string;

   function IncrementDigit(x:PChar; m:Char):Boolean;
   var
      c : Char;
   begin
      Result := False;
      case m of
         '0':
         begin
            c := Succ(x^);
            if c > '9' then
            begin
               c := '0';
               Result := True;
            end;
            x^ := c;
         end;
         'A':
         begin
            c := Succ(x^);
            if c > 'Z' then
            begin
               c := 'A';
               Result := True;
            end;
            x^ := c;
         end;
         'Z':
         begin
            c := x^;
            if c = '9' then
               c := 'A'
            else if c = 'Z' then
            begin
               c := '0';
               Result := True;
            end
            else
               c := Succ(c);
            x^ := c;
         end;

         'H':
         begin
            c := x^;
            if c = '9' then
               c := 'A'
            else if c = 'F' then
            begin
               c := '0';
               Result := True;
            end
            else
               c := Succ(c);
            x^ := c;
         end;

         ' ':
            ;
      else
         raise Exception.CreateFmt('IncrementWithMask(%s, %s) - invalid Mask', [Number, Mask]);
      end;
   end;

var
   i : Integer;
begin
   Result := Number;
   for i:=length(Result) downto 1 do
   begin
      if not IncrementDigit(@result[i], Mask[i]) then
         Break;
   end;
end;
Beispiel:
Delphi-Quellcode:
var
   s, m : string;
begin
  s:= '0008899';
  m:= '0000000';
  s := IncrementWithMask(s, m); // s enthält nun '0008900'

alzaimar 19. Apr 2007 19:45

Re: "Schlossknack"-Algorithmus
 
Hmmm... Oder so (einfacher, kann dafür mit beliebigen Zahlensystemen arbeiten)
Delphi-Quellcode:
Const
  ccDigits = '0123456789';
// ccDigits enthält alle 'Ziffern' und kann beliebig erweitert werden
// Für Addition von HEX-Zahlen, setze ccDigits auf '0123456789ABCDEF';

Function AddOne(s: String): String;
Var
  i: Integer;
  cLast,cFirst : Char;

Begin
  i := Length(s);
  Result := s;
  cLast := ccDigits [Length (ccDigits)];
  cFirst := ccDigits[1];
  While i > 0 Do Begin
    If Result[i] <> cLast Then Begin
      Result[i] := ccDigits[1 + Pos (Result[i], ccDigits)]; // nächste 'Ziffer' aus den Digits nehmen
      Exit;
    End
    Else Begin
      Result[i] := cFirst;
      dec(i);
      End;
  End;
  Raise Exception.Create('Überlauf');
End;
Code:
AddOne('000') = '001'
AddOne('009') = '010'
AddOne('999') = Exception 'Überlauf'
Prinzipiell funktioniert es wie ein mechanischer Zähler. Hier wird beim letzten Zeichen begonnen. Ist das Zeichen < als die höchste Ziffer, ersetzen wir es durch die nächste und sind fertig. Ansonsten haben wir einen Übertrag: Wir setzen diese Stelle auf '0' (also auf die kleinste Ziffer), gehen um eine Stelle nach links und wiederholen das Ganze.


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

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz