Hi Leute!
Ich komme grad nicht ganz klar mit meinem kleinen Progrämmchen...
Folgende Aufgabenstellung:
Eine Menge von gleichen Münzen ist gegeben, und EINE dieser Münzen ist leichter als die anderen (Falschgeld). Es steht lediglich eine Waage ohne Gewichte zur Verfügung. Ziel: Mit möglichst wenig Aufwand (Wiege-Durchläufen) die falsche Münze herausbekommen.
Bei meinem Ansatz verwende ich ein array of boolean, true für "echtes" Geld, und ein Eintrag false für die falsche Münze.
Prinzip:
Die Menge wird in zwei gleiche Haufen geteilt, und gewogen.
Die leichtere der beiden wird erneut geteilt, und wieder verwogen
und das so lange, bis nur noch 2 Münzen zu wiegen sind -> dann hat man sie
(Eine Behandlung für ungerade Münzanzahl ist mit drin, kommt gleich etwas Code dazu)
Das Prinzip funktioniert super-hervorragend, und ist wirklich schnell! Bei satten 1000 Münzen sind so nur 10 Wägungen nötig.
Jetzt das AABBEERR... Mein Programm funktioniert so weit, aber es tauchen an unterschiedlichsten Stellen Zugriffsverletzungen auf, die ich mir beim besten Willen nicht erklären kann!
Bei z.B. 50 Münzen in der Ausgangsmenge knallt's IMMER, aber bei Vielfachen von 50 gehts problemlos!?!? Dabei kommt dort die 50 ja durch das ständige Halbieren AUCH vor... ab > 8000 gibt's fast immer einen Fehler.
Noch schöner: Starte ich das Programm nicht in der
IDE, so bekomme ich nichtmal eine Fehlermeldung, sondern das Programm wird
sofort einfach abgeschossen. Knallhart...
hier etwas Code:
Delphi-Quellcode:
type
TArray = array of boolean;
.
.
.
procedure CopyArray(origin: TArray; var destination: TArray);
var i: Integer;
begin
for i := 0 to High(origin) do destination[i] := origin[i];
end;
function ArrayFirstHalf(arOriginal: TArray): TArray;
var i, m: Integer;
begin
m := Length(arOriginal) div 2;
SetLength(result, m);
for i := 0 to m do
result[i] := arOriginal[i];
end;
function ArraySecondHalf(arOriginal: TArray): TArray;
var i, m: Integer;
begin
m := Length(arOriginal) div 2;
SetLength(result, m);
for i := 0 to m do
result[i] := arOriginal[i+m];
end;
function SumTrueElements(arOriginal: TArray): Integer;
var i: Integer;
begin
result := 0;
for i := 0 to High(arOriginal) do
if arOriginal[i] then inc(result);
end;
function GetFalseElement(ar: TArray): Integer;
var
buffer, isBuffered : boolean;
arOriginal,
bufArray1, bufArray2 : TArray;
Weigh1, Weigh2 : Integer;
begin
result := 0;
SetLength(arOriginal, Length(ar));
CopyArray(ar, arOriginal);
buffer := false;
isBuffered := false; // zu Beginn noch nix gesichert :)
while Length(arOriginal) > 1 do
begin
inc(result);
if Boolean(Length(arOriginal) mod 2) then // Wenn Element-Anzahl ungerade
begin
if not isBuffered then // Wenn KEIN Wert gesichert
begin
buffer := arOriginal[High(arOriginal)]; // Wert des letzten Elementes in 'buffer' sichern
isBuffered := true; // Flag: Es IST ein Wert gesichert
end
else // Wenn ein Wert gesichert IST
begin
SetLength(arOriginal, Length(arOriginal)+1); // Array-Größe um 1 erhöhen
arOriginal[High(arOriginal)] := buffer; // gesichertes Element an letzte Position schreiben
isBuffered := false; // Flag: Es ist KEIN Wert gesichert
end;
end;
SetLength(bufArray1, Length(arOriginal) div 2);
SetLength(bufArray2, Length(arOriginal) div 2);
CopyArray(ArrayFirstHalf(arOriginal), bufArray1);
CopyArray(ArraySecondHalf(arOriginal), bufArray2);
Weigh1 := SumTrueElements(bufArray1);
Weigh2 := SumTrueElements(bufArray2);
if (Weigh1 = Weigh2) and isBuffered then Exit; // Beide Mengen sind gleich schwer -> im Puffer ist gesuchtes Element!
SetLength(arOriginal, Length(bufArray1));
if Weigh1 < Weigh2 then CopyArray(bufArray1, arOriginal)
else if Weigh1 > Weigh2 then CopyArray(bufArray2, arOriginal); // Die "leichtere" Menge zur OriginalMenge machen
end; // while-Schleife
end; // Prozedur
Eine Stelle, an der Fehler auftritt kann ich noch nicht mal angeben... mal wird erst gar keine angezeigt, und sonst ist es immer eine andere Zeile...
Wäre euch super-dankbar, wenn ihr mir etwas helfen könntet!
dizzy
Hier auch mal das Projekt:
Fabian K.
INSERT INTO HandVonFreundin SELECT * FROM Himmel