Fibonacci Primzahlen



  • Sehr geehrte Foren Mitglieder

    Ich habe mir vorgenommen ein Programm zu schreiben, welches den Nutzer nach einer Zahl m fragt und danach alle Fibonacci Primzahlen bis zu dieser Zahl ausgibt. Die Fibonacci Zahlen an sich sind mir gelungen, nur die Primzahlprüfung gelingt mir nicht 😞
    Z. Bsp wird in der Console mit dem aktuellen Code die Zahl 21 ausgegeben. 21 ist zwar eine Fibonacci Zahl, jedoch keine Primzahl. Ich vermute in meiner for Schleife wird das e nie erhöht, wodurch 21%e tatsächlich nicht null ist. Sicher bin ich mir aber nicht (das Programm kompiliert übrigens, auch wenn im unten angegebene code vlt das return 0; fehlt).

    #include <iostream>
    #include <cassert>
    
    int main ()
    
    {
      int m;
      std::cin >> m;
      
      
    if (m==0)
      std::cout << 0 << std::endl;
    if (m==1)
      std::cout << 0 << std::endl;
    if (m==2){
      std::cout << 2 << std::endl;
      std::cout << 1 << std::endl;
    }
    else {  //also m grösser als 2
      int n1=0;
      int n2=1;
      int n3;
      for(int i=2; i <=m; i++){ 
              n3=n2+n1; // n3 wird zu 1 // n3 wird zu 2 // n3 =3
              n1=n2; // n1 wird zu 1 // n1 wird zu 1 // n1 =2
              n2=n3; //n2 wird zu 1 // n2 wird zu 2 // n2 =3
              i =n1+n2; // i wird zu 2 // i wird zu 3 // i wird zu 5 // i wird zu 8 -->13-->21
              if (i==2)
                std::cout << i << std::endl;
                
              else
              {
              assert (i>2);
              for(int e=2; e<i;e+=1){  
                if (i%e ==0 ){ // 21%2 ist tatsächlcih nicht 0 // e wird nie zu 3 (schlecht)
                  break;
                }
              
              
                if (i<=m) //zahl 21 kommt hierhin und erfüllt logischerweise bedingung
                {
                    std::cout << i << std::endl;
                    break;
                  }
                
              }
              }
      }
    }
    }
    
    
    
    

  • Mod

    Du machst ja gar nichts mit der Erkenntnis, dass i einen Teiler hat. Das break in Zeile 36 bricht die for-Schleife aus Zeile 34 ab. Und was dann? Dann läuft das Programm genau so weiter als würden die Zeilen 34-37 gar nicht existieren.

    Vielleicht kommst du mit deinen vielen ein- und zweibuchstabigen Variablen durcheinander? Mindestens i hat bei dir mehrere Bedeutungen. Programmieren ist kein Wettbewerb, möglichst wenige Zeichen zu nutzen.



    1. Formatiere deinen Code sinnvoll (nutze automatische Formatierungstools!)
    2. Mach kleine Funktionen, die jeweils genau eine Aufgabe erfüllen. Insbesondere bieter es sich doch an, für den Primzahlcheck eine Funktion zu schreiben.
    3. zu deiner Anmerkung mit return 0: Ein return 0; am Programmende ist optional. Du darfst es weglassen.
    4. du hast zu viele (und auch noch einbuchstabige) Variablen - 1 Buchstabe (i) ist ok für eine Schleifenvariable, aber auch nur, wenn du nicht verschachtelst. Merke: tiefe Verschachtelungen sind schlecht - dann solltest du den tief eingerückten Code in eine Funktion auslagern oder anderweitig den Code umschreiben.

    Nur formatiert, ansonsten unverändert, sieht sein Programm so aus:

    #include <cassert>
    #include <iostream>
    
    int main()
    
    {
        int m;
        std::cin >> m;
    
        if (m == 0)
            std::cout << 0 << std::endl;
        if (m == 1)
            std::cout << 0 << std::endl;
        if (m == 2) {
            std::cout << 2 << std::endl;
            std::cout << 1 << std::endl;
        } else { // also m grösser als 2
            int n1 = 0;
            int n2 = 1;
            int n3;
            for (int i = 2; i <= m; i++) {
                n3 = n2 + n1; // n3 wird zu 1 // n3 wird zu 2 // n3 =3
                n1 = n2;      // n1 wird zu 1 // n1 wird zu 1 // n1 =2
                n2 = n3;      // n2 wird zu 1 // n2 wird zu 2 // n2 =3
                i = n1 + n2; // i wird zu 2 // i wird zu 3 // i wird zu 5 // i wird zu 8 -->13-->21
                if (i == 2)
                    std::cout << i << std::endl;
    
                else {
                    assert(i > 2);
                    for (int e = 2; e < i; e += 1) {
                        if (i % e ==
                            0) { // 21%2 ist tatsächlcih nicht 0 // e wird nie zu 3 (schlecht)
                            break;
                        }
    
                        if (i <= m) // zahl 21 kommt hierhin und erfüllt logischerweise bedingung
                        {
                            std::cout << i << std::endl;
                            break;
                        }
                    }
                }
            }
        }
    }
    
    

    Was tut außerdem die Ausgabe von "0"? 0 ist keine Primzahl. 1 übrigens auch nicht.



  • Ich mache dir einen Gegenvorschlag:

    #include <cmath>
    #include <iostream>
    
    class FibonacciGenerator {
        int n1 = 1;
        int n2 = 0;
    
    public:
        int next() {
            int result = n1 + n2;
            n1 = n2;
            n2 = result;
            return result;
        }
    };
    
    bool is_prime(int candidate) {
        if (candidate < 2)
            return false;
        if (candidate == 2)
            return true;
        if (candidate % 2 == 0)
            return false;
        int root = sqrt(candidate);
        for (int i = 3; i <= root; i += 2) {
            if (candidate % i == 0)
                return false;
        }
        return true;
    }
    
    int main() {
        int max_value;
        std::cin >> max_value;
    
        auto fg = FibonacciGenerator();
        for (auto fib = fg.next(); fib <= max_value; fib = fg.next()) {
            if (is_prime(fib))
                std::cout << fib << '\n';
        }
    }
    

    Hier siehst du, dass Generieren von Fiboncci-Zahlen und das Testen auf Primzahlen kleine & einfache Funktionen sind - insbesondere ist die tiefste Verschachtelung hier ein if in einem for.



  • Vielen Dank Euch beiden für die ausführlichen antworten, sie haben sehr geholfen 🙂
    Und das Programm funktioniert mittlerweile auch, danke!


Anmelden zum Antworten