Delphi-PRAXiS
Seite 1 von 3  1 23   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Erstellung einer Schleife mit drei Überprüfungen (https://www.delphipraxis.net/207974-erstellung-einer-schleife-mit-drei-ueberpruefungen.html)

Mo53 23. Mai 2021 00:11

Delphi-Version: 5

Erstellung einer Schleife mit drei Überprüfungen
 
Hallo,

Ich muss ein Programm für die Uni erstellen das überprüft ob in einer Schleife gerade Zahlen, Fibonacci Zahlen, oder Primzahlzwillinge vorhanden sind, und dann bei der Zahl jeweils TRUE oder FALSE anzeigen. Die Ausgabe sollte dann so aussehen:

0 even: TRUE fib: TRUE twinprim: FALSE
1 even: FALSE fib: TRUE twinprim: FALSE
2 even: TRUE fib: TRUE twinprim: FALSE
3 even: FALSE fib: TRUE twinprim: TRUE
4 even: TRUE fib: FALSE twinprim: FALSE
5 even: FALSE fib: TRUE twinprim: TRUE
6 even: TRUE fib: FALSE twinprim: FALSE
7 even: FALSE fib: FALSE twinprim: TRUE
8 even: TRUE fib: TRUE twinprim: FALSE
9 even: FALSE fib: FALSE twinprim: FALSE
10 even: TRUE fib: FALSE twinprim: FALSE
11 even: FALSE fib: FALSE twinprim: TRUE
12 even: TRUE fib: FALSE twinprim: FALSE
13 even: FALSE fib: TRUE twinprim: TRUE
14 even: TRUE fib: FALSE twinprim: FALSE
15 even: FALSE fib: FALSE twinprim: FALSE
16 even: TRUE fib: FALSE twinprim: FALSE
17 even: FALSE fib: FALSE twinprim: TRUE
18 even: TRUE fib: FALSE twinprim: FALSE
19 even: FALSE fib: FALSE twinprim: TRUE
20 even: TRUE fib: FALSE twinprim: FALSE
21 even: FALSE fib: TRUE twinprim: FALSE
22 even: TRUE fib: FALSE twinprim: FALSE
23 even: FALSE fib: FALSE twinprim: FALSE
24 even: TRUE fib: FALSE twinprim: FALSE
25 even: FALSE fib: FALSE twinprim: FALSE

Nun habe ich ein Problem mit Gleitkommawerten und wollte dies mit Epsilon lösen also 1E - 100, so hatten die uns das in der Vorlesung erklärt, jedoch funktioniert das nicht ganz ohne weiteres und ich finde im Internet auch nix brauchbares dazu. Im Programm muss dazu noch jeweils ein for, while und repeat vorkommen und ich weiß nicht wo ich das while integrieren soll.
Sorry für die dummen Fragen, ich bin noch blutiger Anfänger, habe vor einem Monat mit dem Programmieren angefangen.
Freue mich über jede Hilfe und danke im voraus.

Hier mein Quellcode:

Delphi-Quellcode:
// Schleife zum überprüfen ob gerade Zahl, Primzahl oder Fibonacci Zahl.
program ueb04;

{$APPTYPE CONSOLE}
{$R+,Q+,X-}

uses
  System.SysUtils, System.Math;

const
  LOWER_BORDER = 0;
  UPPER_BORDER = 50;
  Epsilon = 1E - 100;

var
  even: boolean;
  fib: extended;
  fibo: boolean;
  twinprim: boolean;
  zahl: integer;
  Primzahl: integer;
  teiler: integer;
  übrig: integer;

begin

  for zahl := 1 to 50 do
  begin
    // Überprüfung ob gerade
    even := (zahl mod 2 = 0);
    // Überprüfung ob Fibonacci
    fib := ((1 / sqrt(5)) * (Power(zahl, ((1 + sqrt(5)) / 2)) - (Power(zahl,
      ((1 - sqrt(5)) / 2)))));
    fibo := (zahl = (fibo - Epsilon));
    // Überprüfung ob Primzahl
    if zahl > 0 then
    begin
      teiler := 1;
      repeat
        teiler := teiler + 1;
        übrig := zahl mod teiler;
      until (teiler = 0);
      if (teiler = zahl) then
        Primzahl := zahl
    end;

    // Überprüfung ob Primzahlzwilling
    twinprim := (Primzahl + 2 = Primzahl);

    writeln(zahl, ' even: ', even, ' fib: ', fib, ' twinprim: ', twinprim);

  end;
  readln;

end.

TurboMagic 23. Mai 2021 00:33

AW: Erstellung einer Schleife mit drei Überprüfungen
 
Hallo,

keine Ahnung, aber mal 2 Anmerkungen:

1. uebrig bekommt bei dir zwar einen Wert zugewiesen aber den verwendest du nie.

2. dein Test ob es ein Primzahlzwilling ist kann nicht funktionieren.
Eine Zahl x kann niemls die selbe Zahl wie x + 2 sein!

Grüße
TurboMagic

KodeZwerg 23. Mai 2021 02:10

AW: Erstellung einer Schleife mit drei Überprüfungen
 
Zitat:

Zitat von Mo53 (Beitrag 1489949)
Im Programm muss dazu noch jeweils ein for, while und repeat vorkommen und ich weiß nicht wo ich das while integrieren soll.

Erstelle für Input ein Array of "Datentyp" zum abarbeiten.
Erstelle für Output ein Array of String für die Ausgabe.

In einer "For"-Schleife über Input Array überprüfst Du auf gerade Zahlen und schreibst das Ergebnis in das Output Array.
In einer "While"-Schleife über Input Array überprüfst Du auf Fibonacci Zahlen und schreibst das Ergebnis in das Output Array.
In einer "Repeat"-Schleife über Input Array überprüfst Du auf Primzahlzwillinge und schreibst das Ergebnis in das Output Array.

Somit wären diese Pflichten erledigt.

Nun musst Du Dir überlegen wie Du es auswertest mit dem True/False da ich nicht verstanden habe was True/False bedeuten soll.

Ich hoffe es bringt Dich ans Ziel.

Ps: Ich würde mir für das Überprüfen jeweils eine Eigene Methode erstellen, "IsEven, IsFibo, IsPrimePair" um in den Schleifen einfacher darauf zugreifen zu können.


//edit grober pseudo code der verdeutlichen soll wie ich es meine, etwaige fehler und lücken müssen noch bearbeitet werden.
Delphi-Quellcode:
program hausaufgabe;

uses Units;

function IsEven(const AValue: {Datentyp}): Boolean;
begin
//code
end;

function IsFibo(const AValue: {Datentyp}): Boolean;
begin
//code
end;

function IsPrimePair(const AValue: {Datentyp}): Boolean;
begin
//code
end;

var
  input: Array of {Datentyp};
  output: Array of string;
  i, maxI: Integer;
begin
  Writeln('Hausaufgabe');
  Writeln('');

  Randomize;
  maxI := Random(666);
  SetLength(input, maxI);
  SetLength(output, maxI);
  for i := 0 to maxI do
    input[i] := Random(666);

  for i := 0 to High(input) do
    if IsEven(input[i]) then
      output[i] := 'IsEven, '
      else
      output[i] := 'IsNotEven, ';

  i := 0;
  while True do
  begin
    if IsFibo(input[i]) then
      output[i] := output[i] + 'IsFibo, '
      else
      output[i] := output[i] + 'IsNotFibo, ';
    if i < Length(input) then
      Inc(i, 1)
      else
      Break;
  end;

  i := 0;
  repeat
    if IsPrimePair(input[i]) then
      output[i] := output[i] + 'IsPrimePair'
      else
      output[i] := output[i] + 'IsNotPrimePair';
    Inc(i, 1);
  until i > Length(input);

  for i := 0 to High(output) do
    Writeln('#' + IntToStr(i) + ': "' + DatentypToStr(input[i]) + '" = ' + output[i];

  Readln;
end.

himitsu 23. Mai 2021 02:36

AW: Erstellung einer Schleife mit drei Überprüfungen
 
"Überprüfung ob Primzahl" kann nicht stimmen.
* die Repeat-Schleife wird nur bei 0 verlassen
* das was in der Schleife ist, ist komplett sinnlos, weil niemals damit etwas gemacht wird
* "Zahl" kann sowieso niemals 0 sein

und bezüglich "Primzahlzwilling"
* man nehme das vorherige Ergebnis "IsPrime"
* und wenn ja, dann Zahl+2 und Zahl-2 prüfen, ob einwas davon auch eine Primzahl ist


Delphi-Quellcode:
  for zahl := 1 to 50 do
  begin
    ...
    if zahl > 0 then
    begin
Und überleg auch mal, ob diese Prüfung irgendeinen Sinn haben kann.

Oder andersrum, schau dir an, was die Ausgabe im ersten Post mit deiner Schleife nicht gemeinsam hat. :wink:

Michael II 23. Mai 2021 10:54

AW: Erstellung einer Schleife mit drei Überprüfungen
 
Fibonacci.

Da machst du diverse Fehler.

Du willst für die Berechnung offenbar Moivre-Binet (MB) verwenden. Mit MB kannst du die n-te Fibonacci Zahl ermitteln.
D.h. du musst bei deiner Überprüfung von "zahl" ein n finden, für welches f(n) = zahl gilt. Dann ist "zahl" Fibonacci Zahl.

Du verwendest in deiner Formel Power(a,b), was a^b entspricht. Schau dir noch einmal die Formel von MB an, dann siehst du, dass du in deinem Programm bei Power(a,b) Basis und Exponent vertauscht hast.

Näherung: Der zweite Power Therm in MB ist bereits für kleine n klein und (da ¦Basis¦ < 1) konvergent lim(n->unendlich) = 0. Du kannst auf den zweiten Therm verzichten und rechnen:

Delphi-Quellcode:
    sqrt5 := sqrt(5);
    fib := trunc( 1/sqrt5 * Power((1+sqrt5)/2,n) + 0.5 );
Noch einmal: Du musst (Code oben) nach einem n suchen, für welches fib=zahl.

Du suchst: Gegeben eine Zahl zahl. Gesucht: Gibt es ein n für welches gilt fib(n)=zahl. zahl := trunc( 1/sqrt5 * Power((1+sqrt5)/2,n) + 0.5 ) kannst du auflösen nach n: (zahl-0.5)*sqrt5=((1+sqrt5)/2)^n. => n = log(zahl-0.5)/log((1+sqrt5)/2).
Für grössere Werte von Zahl kannst du das 0.5 auch weglassen (dies ist ja die Abschätzung für ((1-sqrt)/2)^n in MB und dieser Funktion konvergiert gegen 0).
Bleibt zu prüfen, ob der gefundene Wert n (ist eine real Zahl) effektiv Index einer Fibonacci Zahl ist.

(Mit einem ε machst du mathematisch nix falsch, in einem Programm musst du aber i.A. im Auge behalten, wie beim von dir verwendeten Zahlentyp Werte abgespeichert werden. Die "reelle Zahlenwelt" im Computer weist mehr Löcher als Werte (nur endlich viele voneinander verschiedene Werte speicherbar, jedoch R überabzählbar) auf: Du findest zu einem abgespeicherten real Wert x locker ein ε für welches im (mathematischen) Intervall [x-ε,x+ε] alle Werte als x gespeichert werden.)

Nebenbei und für Uni (1. Jahr, Lineare Algebra, Differentialgleichungen) interessant: Du kannst für Folgen vom Typ a[n+1] = f*a[n] + g*a[n-1], Startwerte a[0], a[1] gegeben
eine Formel (wie jene von MB für Fibo) für a[n] berechnen. Wenn du dir die Herleitung von MB anschaust, dann siehst du sofort wie das geht. (Du betrachtest im R^2 die lineare Abbildung (a[n],a[n-1]) = A(a[n-1],a[n-2]) => (a[n+k],a[n+k-1]) = A^(k)(a[n],a[n-1]), Du suchst für A die Eigenvektoren und kannst so leicht A^(k) berechnen. Fertig.)

TurboMagic 23. Mai 2021 11:35

AW: Erstellung einer Schleife mit drei Überprüfungen
 
Hallo,

evtl. ist es auch sinnvoll, suerst mal die gerade/ungerade und primzahlen AUfgabenteile zu lösen, damit man
dafür eine saubere Grundstruktur des Programmes bekommt und danach dan das Fibonnaci Problem anzugehen.

Grüße
TurboMagic

Mo53 23. Mai 2021 12:57

AW: Erstellung einer Schleife mit drei Überprüfungen
 
@KodeZwerg
Vielen Dank für die Mühe, ich hatte aber vergessen zu erwähnen das wir noch keine arrays verwenden dürfen.

Mo53 23. Mai 2021 20:52

AW: Erstellung einer Schleife mit drei Überprüfungen
 
Leute könnt ihr mir vielleicht sagen warum nach dem compilen die Ausgabe nur für die Zahl Null ausgegeben wird, hänge da schon Stundenlang dran.
Delphi-Quellcode:
{$APPTYPE CONSOLE}
{$R+,Q+,X-}

uses
  System.SysUtils, System.Math;

const
  LOWER_BORDER = 0;
  UPPER_BORDER = 50;
  Epsilon = 1E-100;

var
  even: boolean;
  fib: extended;
  fibo: extended;
  twinprim: boolean;
  zahl: integer;
  Primzahl: integer;
  teiler: integer;
  uebrig: integer;
  n: real;

begin
  for zahl := LOWER_BORDER to UPPER_BORDER do
  begin
    // Überprüfung ob gerade
    if zahl > 1 then
    begin
      even := (zahl mod 2 = 0);
    end
    else
      even := FALSE;

    // Überprüfung ob Primzahl
    if zahl > 1 then

      teiler := 1;
    repeat
      teiler := teiler + 1;
      uebrig := zahl mod teiler;
    until (uebrig = 0);

    if (teiler = zahl) then
      Primzahl := zahl;

    // Überprüfung ob Primzahlzwilling
    if zahl >= 1 then
    begin
      while zahl = Primzahl do
        twinprim := (zahl + 2 or zahl - 2 = Primzahl);
    end;

    writeln(zahl, ' even: ', even, ' twinprim: ', twinprim);
  end;
  readln;

end.

Delphi.Narium 23. Mai 2021 21:40

AW: Erstellung einer Schleife mit drei Überprüfungen
 
Dashier führt zu einer Endlosschleife, wenn zahl = Primzahl.
Delphi-Quellcode:
   // Überprüfung ob Primzahlzwilling
    if zahl >= 1 then
    begin
      while zahl = Primzahl do
        twinprim := (zahl + 2 or zahl - 2 = Primzahl);
    end;
In der Schleife werden weder Zahl noch Primzahl verändert, so dass hier nie ein Schleifenabbruch geschehen wird.

Diese Zuweisung wird vermutlich auch nicht das gewünschte Ergebnis bringen:
Delphi-Quellcode:
twinprim := (zahl + 2 or zahl - 2 = Primzahl);

Das könnte eher mit
Delphi-Quellcode:
twinprim := (zahl + 2 = Primzahl) or (zahl - 2 = Primzahl);
erreicht werden.

Auch wenn Du irgendwo noch eine While-Schleife unterbringen musst, erschließt sich mir hier nicht, wie eine sinnvolle Nutzung an dieser Stelle möglich sein könnte.
Delphi-Quellcode:
    // Überprüfung ob Primzahlzwilling
    if (zahl >= 1) and (zahl = Primzahl) then
      twinprim := (zahl + 2 = Primzahl) or (zahl - 2 = Primzahl)
    else
      twinprim := false;

Michael II 23. Mai 2021 21:52

AW: Erstellung einer Schleife mit drei Überprüfungen
 
Ein Tipp: Du kannst dein Programm in die Delphi IDE laden und dann Zeile für Zeile durchsteppen und schauen, wo dein Programm durchläuft und welche Werte momentan in der Variablen gespeichert sind. Wenn du das tust, dann geht's schneller - hoffentlich hast du die vielen Stunden wenigstens an der Sonne programmiert ;-).

Zu deiner Prüfung, ob Primzahl oder nicht.

Deine Variable teiler lässt du in 1er Schritten von 2 bis zahl laufen.
Prüfe doch auf teilbar durch 2 und danach nur ob teilbar durch 3,5,7,9,11,...
Du sparst etwa die Hälfte der Abfragen: Faktor 2 schneller.
Das hier kennst du wahrscheinlich aus der Grundschule 7. Klasse Mathe führt aber wahrscheinlich punkto Delphi noch zu weit.

Du testest etwas viele "teiler" durch. Prüf doch nur bis zu sqrt(zahl) und hör dann auf. Statt zum Beispiel 1'000'000 "teiler Checks" führst du dann nur etwa 1'000 durch. Faktor 1'000 schneller.

Primzahlzwilling. Den Code musst du etwas überdenken.


Alle Zeitangaben in WEZ +2. Es ist jetzt 01:20 Uhr.
Seite 1 von 3  1 23   

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