none
Hilfe bei Berechnung der Fibonacci-Zahlenfolge RRS feed

  • Frage

  • Hallo Leute,

    ich habe gerade erst mit der C# Programmierung angefangen (ca. 1,5 Monate) und habe mich soweit durchgearbeitet das ich Datentypen kenne und einige Befehle kenne und ich habe einen Taschenrechner programmiert der allerdings nur die 4 Grundrechenarten rechnen kann. Ich lebe von kleinen Erfolgen....:)...

    Jetzt hatte ich mir quasi als nächstes Projekt ein kleines Programm vorgenommen womit ich die Fibonacci Zahlenfolge berechnen und ausgeben lassen kann. Nach etlichen rumprobieren und fluchen und weiter rumprobieren und lesen und weiter rumprobieren habe ich mir mittlerweile einen Muskelkater beim Denken geholt......mit anderen Worten: ich komme nicht weiter. 

    Habe dann nach Beispielen gegoogelt und dabei diesen Code gefunden:

     
     class Program
        {
            static void Main(string[] args)
            {
                double x, x0, x1;
    
                int zahl, folge;
    
                char antwort;
    
                Console.WriteLine("Dieses Programm berechnet die Fibonacci-Folgen\n");
    
                do
                {
                    Console.Write("Geben Sie die Anzahl der zu berechnenden Folgen ein ");
                    folge = Convert.ToInt32(Console.ReadLine());
    
                    Console.WriteLine("\nFibonacci-Folge von 1 = \t 1");
    
                    x0 = 0;
                    x1 = 1;
                    zahl = 2;
    
                    do
                    {
                        x = x0 + x1;
                        x0 = x1;
                        x1 = x;
    
                        Console.WriteLine("Fibonacci-Folge von {0} = \t {1}", zahl, x);
    
                        zahl++;
    
                    } while (zahl <= folge);
    
                    Console.WriteLine("\nNeue Berechnung? [j / n]");
                    antwort = Convert.ToChar(Console.ReadLine());
    
                } while ((antwort == 'j') || (antwort == 'J'));

    Was ich verstehe:

    - Verwendung einer do-while Schleife (fußgesteuert)

    - Ablauf des Programms

    - die Berechnung erfolgt bei dem Teil mit der Schleife

    Was ich nicht verstehe:

    - die Berechnung an sich

    Ich habe die Schleife mal aufm Schmierzettel durchgespielt, aber ich verstehe nicht warum oder womit die Folge weiter berechnet wird. 

    Ist das richtig wenn ich sage x = 1? Und bleibt x = 1?  Ich verstehe das nicht....

    Vllt kann einer hier mir aushelfen oder einen kleinen Denkanstoß in die richtige Richtung geben. Das wäre super.

    Grüße


    Dienstag, 14. November 2017 21:31

Antworten

  • Hallo,

    hier mein Vorschlag: An Stelle von...

    x = x0 + x1;
    x0 = x1;
    x1 = x;

    ... hier einmal mit anderer Benennung und auf dem "Schmierzettel", also ohne Schleife. Die Folge wird in den äußeren Kommentaren erkennbar:

    double fiboZahl, ersteZahl, zweiteZahl;
    
    ersteZahl = 0;                     //->       0
    zweiteZahl = 1;                    //->       1
    
    fiboZahl = ersteZahl + zweiteZahl; //->       1
    ersteZahl = zweiteZahl;            // = 1
    zweiteZahl = fiboZahl;             // = 1
    
    fiboZahl = ersteZahl + zweiteZahl; //->       2
    ersteZahl = zweiteZahl;            // = 1
    zweiteZahl = fiboZahl;             // = 2
    
    fiboZahl = ersteZahl + zweiteZahl; //->       3
    ersteZahl = zweiteZahl;            // = 2
    zweiteZahl = fiboZahl;             // = 3
    
    fiboZahl = ersteZahl + zweiteZahl; //->       5
    ersteZahl = zweiteZahl;            // = 3
    zweiteZahl = fiboZahl;             // = 5
    
    fiboZahl = ersteZahl + zweiteZahl; //->       8
    ersteZahl = zweiteZahl;            // = 5
    zweiteZahl = fiboZahl;             // = 8

    Wenn das klarer geworden ist, kannst du den Block in eine Schleife nehmen. Anstelle der DO-Schleife kannst du auch eine FOR-Schleife nehmen.

    Dein gefundener Algorithmus hat aber ein schwerwiegendes Problem: Der verwendete Zahlentyp. Für "Double" fliegt dir das für das ca. 1475ste Element um die Ohren. Gemeint ist, dass die Zahlen zu groß für "Double" werden.

    Dafür gibt es aber eine Lösung: System.Numerics.BigInteger

    Hier noch eine andere Variante, die mit weniger Variablen auskommt:

    public static void Fibo1(int n) {
      System.Numerics.BigInteger ersteZahl = 0, zweiteZahl = 1;
        if ( n < 3 ) {
          Console.WriteLine("Mindestens 3 Elemente anfordern...");
          return;
        }
        Console.Write($"{ersteZahl}, {zweiteZahl}, ");
    
        do {
            Console.Write($"{ersteZahl + zweiteZahl}, ");
            zweiteZahl = ersteZahl + zweiteZahl;
            ersteZahl = zweiteZahl - ersteZahl;
            n--;
        } while ( n > 2 );
    }

    Wenn du suchst, wirst du bestimmt noch andere Varianten finden. Ich würde dir empfehlen, diese einmal nebeneinander zu stellen und die jeweiligen Vor- und Nachteile zu suchen.

    Gruß

    Mittwoch, 15. November 2017 00:19
  • Bei Fibonacci Zahlen muss ich immer direkt an Rekursion denken.

    Ist ja auch eigentlich durch die definitionem schon vorgegeben.

    fib(0) =  0 , fib(1)= 1 und fib(n) = fib(n-1) + fib(n-1)

    folgt

    int fib(int n)
    {
          if(n == 0) return 0; //Abbruch Bedingung für n-2
          if(n == 1) retunr 1; // AbbruchBedingung für n-1
          return fib(n-1) + fib(n-2);
    }

    Mittwoch, 15. November 2017 17:08

Alle Antworten

  • Hallo,

    hier mein Vorschlag: An Stelle von...

    x = x0 + x1;
    x0 = x1;
    x1 = x;

    ... hier einmal mit anderer Benennung und auf dem "Schmierzettel", also ohne Schleife. Die Folge wird in den äußeren Kommentaren erkennbar:

    double fiboZahl, ersteZahl, zweiteZahl;
    
    ersteZahl = 0;                     //->       0
    zweiteZahl = 1;                    //->       1
    
    fiboZahl = ersteZahl + zweiteZahl; //->       1
    ersteZahl = zweiteZahl;            // = 1
    zweiteZahl = fiboZahl;             // = 1
    
    fiboZahl = ersteZahl + zweiteZahl; //->       2
    ersteZahl = zweiteZahl;            // = 1
    zweiteZahl = fiboZahl;             // = 2
    
    fiboZahl = ersteZahl + zweiteZahl; //->       3
    ersteZahl = zweiteZahl;            // = 2
    zweiteZahl = fiboZahl;             // = 3
    
    fiboZahl = ersteZahl + zweiteZahl; //->       5
    ersteZahl = zweiteZahl;            // = 3
    zweiteZahl = fiboZahl;             // = 5
    
    fiboZahl = ersteZahl + zweiteZahl; //->       8
    ersteZahl = zweiteZahl;            // = 5
    zweiteZahl = fiboZahl;             // = 8

    Wenn das klarer geworden ist, kannst du den Block in eine Schleife nehmen. Anstelle der DO-Schleife kannst du auch eine FOR-Schleife nehmen.

    Dein gefundener Algorithmus hat aber ein schwerwiegendes Problem: Der verwendete Zahlentyp. Für "Double" fliegt dir das für das ca. 1475ste Element um die Ohren. Gemeint ist, dass die Zahlen zu groß für "Double" werden.

    Dafür gibt es aber eine Lösung: System.Numerics.BigInteger

    Hier noch eine andere Variante, die mit weniger Variablen auskommt:

    public static void Fibo1(int n) {
      System.Numerics.BigInteger ersteZahl = 0, zweiteZahl = 1;
        if ( n < 3 ) {
          Console.WriteLine("Mindestens 3 Elemente anfordern...");
          return;
        }
        Console.Write($"{ersteZahl}, {zweiteZahl}, ");
    
        do {
            Console.Write($"{ersteZahl + zweiteZahl}, ");
            zweiteZahl = ersteZahl + zweiteZahl;
            ersteZahl = zweiteZahl - ersteZahl;
            n--;
        } while ( n > 2 );
    }

    Wenn du suchst, wirst du bestimmt noch andere Varianten finden. Ich würde dir empfehlen, diese einmal nebeneinander zu stellen und die jeweiligen Vor- und Nachteile zu suchen.

    Gruß

    Mittwoch, 15. November 2017 00:19
  • Bei Fibonacci Zahlen muss ich immer direkt an Rekursion denken.

    Ist ja auch eigentlich durch die definitionem schon vorgegeben.

    fib(0) =  0 , fib(1)= 1 und fib(n) = fib(n-1) + fib(n-1)

    folgt

    int fib(int n)
    {
          if(n == 0) return 0; //Abbruch Bedingung für n-2
          if(n == 1) retunr 1; // AbbruchBedingung für n-1
          return fib(n-1) + fib(n-2);
    }

    Mittwoch, 15. November 2017 17:08
  • Hallo, 

    erstmal vielen Dank für die Antworten. Ich habe das mal auf nem Schmierzettel versucht nachzuvollziehen. So ganz ist der Groschen noch nicht gefallen. Aber ich glaube ich bin auf einem guten Weg. Irgendwann wird es Klick machen...dauert bei mir halt....:D...

    Trotzdem erstmal nochmals Danke für die Hilfe.

    Grüsse

    Mittwoch, 15. November 2017 20:48