kleines Problemchen



  • Hallo der Code lauft. Es gibt ein kleines Problemchen:
    Das Programm listet die unterquadratischen Intervalle und zählt die darin enthaltenen Primzahlen und ungeraden Nichtprimzahlen.

    Es macht folgendes Falsch: beginnt ein unterquadratisches Intervall mit einer ungeraden Quadratzahl, zählt es diese zu den Primzahlen. (Bitte nicht schimpfen, es ist ein Anfängerprogramm!)

    Wo mag der Fehler sein?

    #include <string.h>
    #include <iostream>
    using namespace std;
    #include <sstream>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <math.h>
    int zeler;
    int qz1=0; // aktuelle Zahl
    int qz2=0; // neue Zahl
    int Lenge;
    int input;
    
    int main(int argc, const char * argv[])
    {
        vector<int>npzzeler;
        vector<int>pzzeler;
        vector<int>zahlensammler;
        for (zeler=1; zeler<40; zeler++)// Dreieckszahlhersteller
        {
    
            qz1=zeler*zeler;
            qz2=(zeler+1)*(zeler+1);
    
    //        drz1=drz1+zeler;
      //      drz2=zeler+drz1;
            for(input=qz1; input<qz2; input++)
            {
                if (input%2==!0)
                    zahlensammler.push_back(input);
                //cout<< input<< " input\n";
            }
    
            std::cout <<zeler<<". iq.Interv.von "<<qz1<<" - "<<qz2<<"\n";
            for(auto it = zahlensammler.begin(); it != zahlensammler.end();it++) // Ausdruck
            {
                //cout<<""<< *it <<" ";
    
                int x=*it; int y=0; int Pruefung=0;
                for(y=3; y<sqrt(x); y++)
                {
                    if(x%y==0)
                    {
                        Pruefung=1;
                        //cout<<Pruefung<<"=Pr "<<y<<"-y "<<x%y<<"mod"<<endl;
                    }
                }
                if(Pruefung==!1)
                {
                    pzzeler.push_back(*it);
                    //cout <<x<< " Primzahl!" << endl;
                }
                else
                {
                    npzzeler.push_back(*it);
                    //  cout <<x<<" keine PZ!" << endl;
                }
                //cout<<"Ende"<<endl;
            }
            cout<<pzzeler.size()<<" PZ: ";
            for(auto it = pzzeler.begin(); it != pzzeler.end();it++) // Ausdruck
            {
                cout<<""<< *it <<" ";
    
            }
            cout<<"\n"<<npzzeler.size()<<" uNPZ: ";
    
            for(auto it = npzzeler.begin(); it != npzzeler.end();it++) // Ausdruck
            {
                cout<<""<< *it <<" ";
    
            }
            cout<<"\n hat "<<npzzeler.size()+pzzeler.size()<<" u. Zahlen\n";
            npzzeler.clear();
            pzzeler.clear();
            zahlensammler.clear();
        }
        return 0;
    }
    


  • if(Pruefung==!1)
    
    if (input%2==!0)
    

    Was soll das machen?



  • manni66 schrieb:

    Was soll das machen?

    if(Pruefung==!1)
    

    Hier prüft er ob in Prüfung eine zahl ungleich 1 vorliegt.

    if (input%2==!0)
    

    Hier prüft er, ob eine gerade Zahl oder nicht vorliegt, Gerade Zahl hat keinen Rest bei Teilung durch 2!



  • Dann schau mal unter Comparison operators, wie der Ungleich-Operator geschrieben wird.



  • Th69 schrieb:

    Dann schau mal unter Comparison operators, wie der Ungleich-Operator geschrieben wird.

    Wenn ich das ändere, ändert sich am Problem nichts...

    Wie kommt ich denn drauf, das so geschrieben zu haben? Gab es denn andre Standards?

    Gibt es irgendwo eine Liste, was die Codes nach dem Breakpoint meinen?



  • Abgesehen von den Dingen, die schon angesprochen wurden (!0 ist 1 (teste doch mal einfach ein cout << !0 << '\n'; ), hier noch ein paar allgemeine Kommentare.

    - Keine globalen Variablen nutzen
    - Nutze Funktionen!
    Als allererstes mach eine Funktion, die für eine gegebene Zahl p einen bool zurückgibt, der angibt, ob es sich um eine Primzahl handelt.

    Also

    bool isPrime(int p) {
        // Ausnahmen zuerst
        if (p == 1) return false;
        if (p == 2) return true;
        // Hier der Code, der alle ungeraden Zahlen von 3..sqrt(p) checkt
        ...
    }
    

    Dann brauchst du nicht ungeraden Nicht-Primzahlen nicht alle zu speichern. Du kannst einfach die Anzahl der ungeraden Zahlen in dem jeweiligen Intervall berechnen (z.B. in einer Funktion

    int NOddNumbersInInterval(int from, int to) { ... }
    

    Davon kannst du die Anzahl der Primzahlen abziehen (nur mit der 2 aufpassen).

    Und dann ist da noch der völlig überflüssige vector zahlensammler. Nur jede 2. Zahl bekommst du auch durch eine einfache Loop for (int i = ungerade_zahl; i < whatever; i += 2) ... hin. Du brauchst diese nicht zu speichern, sondern kannst gleich damit arbeiten. Außerdem fehlt dir auch hier die Spezialbehandlung von 1 und 2, die ungerade/nicht prim und gerade/prim sind.

    Und Schleifen wie diese hier:

    for(auto it = pzzeler.begin(); it != pzzeler.end();it++) // Ausdruck 
            { 
                cout<<""<< *it <<" "; 
                
            }
    

    kann man seit C++11 auch viel schöner schreiben:

    for (const auto &pz : pzzeler) cout << pz << " ";
    

    (oder nimm copy + ostream_iterator, aber ich finde die for-loop mit : leichter lesbar)

    PS: zeler ist ein furchtbarer Name. Für was soll das stehen?



  • otto56 schrieb:

    Gab es denn andre Standards?

    Das hat Dennis Ritchie schon in den frühen 70ern des letzten Jahrhunderts so gemacht.

    Gibt es irgendwo eine Liste, was die Codes nach dem Breakpoint meinen?

    Wovon sprichst du?



  • manni66 schrieb:

    Gibt es irgendwo eine Liste, was die Codes nach dem Breakpoint meinen?

    Wovon sprichst du?[/quote]

    Davon in Xcode

    Thread 1: breakpoint 1.1 2.1 3.1


Log in to reply