Einzelnen Beitrag anzeigen

Benutzerbild von dizzy
dizzy

Registriert seit: 26. Nov 2003
Ort: Lünen
1.932 Beiträge
 
Delphi 7 Enterprise
 
#1

Ganz ekelige Fehler in Verb. mit dyn. Arrays

  Alt 24. Mär 2004, 20:07
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:
Angehängte Dateien
Dateityp: zip project1_214.zip (239,7 KB, 1x aufgerufen)
Fabian K.
INSERT INTO HandVonFreundin SELECT * FROM Himmel
  Mit Zitat antworten Zitat