![]() |
"Schlossknack"-Algorithmus
Hallo DPler,
ich weiß nicht mehr weiter. :) Ich möchte sozusagen den "Schlossknack"-Algorithmus anwenden, d.h. eine Variable von 1 bis 9 hochählen, wenn 9, dann die nächste auf 1,... Nun hat mein "Schloss" aber x Stellen. Die einzige möglichkeit, die mir einfiel, war ein dyn. Array of Integer zu erstellen, ihm die Länge zu geben und dann die einzelnen Integer-Zahlen hochzuzählen. Will der Compiler aber nicht :evil: ... Gibts noch ne andere Möglichkeit? MfG Steffen //Edit: besserer Titel |
Re: for-Schleife x-Mal
Hi,
Verschachtelte for-schleifen? Oder versteh ich was falsch?
Delphi-Quellcode:
Gruß
var Schloss: Array[1..Stellen] of Integer;
for i:= 1 to Stellen do begin for j:= 1 to 9 do inc(Schloss[i]); end; Neutral General |
Re: for-Schleife x-Mal
Das Problem hatte ich auch mal. Die Lösung ist Rekursion. Du setzt eine globale Variable auf x. Dann erstellst du eine Funktion:
Delphi-Quellcode:
Edit: Neutral Generals Lösung scheint aber besser zu sein.
procedure schlossknack(laenge:integer);
begin //mach irgendwas mit globalen Variablen if laenge>1 then schlossknack(laenge-1); end; |
Re: for-Schleife x-Mal
@Neutral General:
Soweit ich sehe, zählt dieser Algorithmus einfach alle Variablen von 1 bis 9 hoch. Aber wenn die nächste eins hochgesetzt wird, sollte erst die ganz erste wieder von 1 bis 9 gezählt werden, so als wölltest du ein Schloss knachen. du versuchst es folgendermaßen (bei einem Schloss mit 3 Stellen:
Code:
1 1 1
2 1 1 3 1 1 ... 9 1 1 1 2 1 2 2 1 3 2 1 ... 8 9 3 9 9 3 1 1 4 2 1 4 ... |
Re: "Schlossknack"-Algorithmus
Nun, du musst eben bei jedem Aufruf der ersten for-Schleife die aktuelle Schlossvariable auf 0 setzen: Schloss[i]:=0;
Und der Stackbedarf ist deutlich besser als bei der Rekusrion, ich versuche mal, mein Prog, indem ich das durch Rekursion gelöst habe, zu beschleunigen. DANKE, NEUTRAL GENERAL!!! |
Re: for-Schleife x-Mal
Zitat:
111 112 113 ... Wieso einfach, wenns auch schwierig geht? ;) |
Re: "Schlossknack"-Algorithmus
@Torpedo: klaro, aber Start und Ende bei jeder Stelle sind dort, wo ich das Ganze brauche auch variabel :mrgreen:
@Apollonius: Werd mal überlegen :) |
Re: "Schlossknack"-Algorithmus
Zitat:
Oder ist das Problem wie man aus den einzelnen Stellen eine ganze Zahl macht? Ziffer1 = 2 Ziffer2 = 4 Ziffer3 = 6 Zahl = Ziffer1*100+Ziffer2*10+Ziffer3 |
Re: "Schlossknack"-Algorithmus
Du könntest auch einfach meine Komponente verwenden :mrgreen:
![]() |
Re: "Schlossknack"-Algorithmus
Ich nehme alles zurück!!! Neutral Generals Lösung funktioniert nicht, es sei denn, ich habe was falsch implementiert. Man muss ja sozusagen x ineinanderverschachtelte for-schleifen haben. Da fällt mir nichts anderes ein als die Rekursion, also:
Delphi-Quellcode:
Im Prinzip ist das eine Simulation von laenge ineineanderverschlachtelten for-Schleifen.
var schloss:array[1..stellen] of integer;
procedure angriff(laenge:integer); var i:integer; begin if laenge=1 then begin for i:=0 to 9 do begin schloss[laenge]:=i; knackdasschloss(schloss); end; end else begin for i:=0 to 9 do begin schloss[laenge]:=i; angriff(laenge-1); end; end; end; //Aufruf angriff(stellen); |
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:
Schleife ?
for i := 0 to MaxWert do ....
|
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:
Beispiel:
{**************************************************************************
* 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;
Delphi-Quellcode:
var
s, m : string; begin s:= '0008899'; m:= '0000000'; s := IncrementWithMask(s, m); // s enthält nun '0008900' |
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:
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.
AddOne('000') = '001'
AddOne('009') = '010' AddOne('999') = Exception 'Überlauf' |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:58 Uhr. |
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