Kettenkettenzähler



  • Hallo, habe ein Programm geschrieben, welche die Nichtprimzahlketten zählt und ausgibt. Es funktioniert.

    (Bitte nicht wegen des Progranmmierstiles rummosern, bin totaler Autodidakt

    ich hätte jetzt noch gern, wie ich es machen kann, daß es nicht nur die Ketten Nummer umgibt, sondern auch daß es sagt, dies ist die 7. 2-er kette etc.

    Und am Ende sollen ein Protokoll ausgeben, in der Art
    Bis zur Zahl xy
    git es x 1-er ketten, die beginnen an:
    gibt es y 2-er ketten. die beginnen
    gint es z 3-er ketten, die beginnen

    etc. etc

    Welche befehle gibt es dafür? ich brauche was dynamisches, also, ws dynamisch Vektoren anlegt, je nach bedarf, und diese füllt, weil ich nicht weiß, wie hoch die höchste Kettenlänge eines zu untersuchenden Intervalles ist.

    Und noch was. Wie kann ich erreichen, daß mein eingebauter Vector, nur noch die erste Position ausgibt? Die anderen kann man sich dann selbst dazuzählen ....

    Hier mein Code, er läuft

    #include <string>
    #include <fstream>
    #include <iostream>
    #include <cmath>
    #include <stdio.h>
    #include <vector>
    #include <list>
    using namespace std;
    
    int main(int argc, const char * argv[])
    {
        std::vector<int> NPZcontainer;
        std::vector<int> PZcontainer;
        int pzz=1; //Primzahlzähler
        int kettenzeler=0;
    
        int unpzz=1; // unger. Nichtprimzahlzähler
        int letztwert=1; // den braucht er um zu prüfen, ob eine Kette vorliegt.
        int ketnz=1; // Kettennummerzähler
        int x, i;
        for (x = 3; x <= 1000; x=x+2)
        {
            for (i = 2; i < x; i++)
            {
                // std::cout<<i<< " =i "<<x<<" =x\n";
                if (x%i == 0)
                    break;
            }
    
            if (i==x) //Hier werden die PZ hergestellt
            {
                // std::cout<<i<<" = "<<pzz<<". Pz.\n";
                pzz++;
                PZcontainer.push_back(i);
                letztwert = 1;
            }
    
            if (x/i>1) //Hier werden die NPZ hergestellt
            {
    
                //std::cout<<x<<" = "<<unpzz<<". NPZ \n";
    
                NPZcontainer.push_back(x);
                unpzz++;
                letztwert = 0;
    
            }
    
            if(letztwert == 1)
            {
    
                for(auto it = NPZcontainer.begin(); it != NPZcontainer.end();it++) // Ausdruck
                {
                    cout<<""<< *it<<" "; // Hier spuckt er die zahlenkette aus.
                    kettenzeler++;
                }
                if (kettenzeler>0) // Hier stellt er den kettenzähler auf 0, wenn eine PZ kommt.
                {
                    cout<<kettenzeler<<"-er Kette\n";
                     cout<<"KetNr:"<<ketnz<<" ";
                    ketnz++;
                }
                NPZcontainer.clear();
                kettenzeler=0;
            }
    
        }
    
        return 0;
    }
    

    Danke für die Tips



  • Du suchst std::map, damit kannst du beliebige Werte auf beliebige andere Werte mappen, auch Vektoren:

    //Definition
    std::map<int,std::vector<int>> laengenZaehler;
    
    //Zugriff und gleichzeitige Erzeugung der Einträge
    laengenZaehler[kettenLaenge].push_back(kettenAnfang);
    
    //Iterieren
    for (auto&& pair : laengenZaehler)
    {
      std::cout << pair.second.size() << " " << pair.first << "-Ketten: ";
      for (auto&& zahl : pair.second)std::cout << zahl << " ";
      std::cout << std::endl;
    }
    

    Die Einträge einer map bestehen aus std::pair, first ist der key (hier die Kettenlänge), und second ist der Wert (hier der Vektor).

    Und noch was. Wie kann ich erreichen, daß mein eingebauter Vector, nur noch die erste Position ausgibt?

    Indem du nicht alle Zahlen ausgibst. Anstatt mit der Schleife über den Vektor zu gehen, gibt das erste Element aus:

    cout << NPZcontainer.at(0) << " ";
    

    Dass du die Primzahlen und Nichtprimzahlen in einem Container speicherst ist eigentlich auch unnötig, du musst dir ja nur den Anfang der jeweils aktuellen Kette merken.



  • Vielen Dank, Rohan ....

    ;Rohan schrieb:

    Du suchst std::map, damit kannst du beliebige Werte auf beliebige andere Werte mappen, auch Vektoren:

    Die Einträge einer map bestehen aus std::pair, first ist der key (hier die Kettenlänge), und second ist der Wert (hier der Vektor).

    Danke für den Tip, Map kannte ich noch nicht.

    Und wo bekomme ich die Startzahlen der einzelnen Ketten im Protokoll, welches am Ende ausgegeben wird?

    ;Rohan schrieb:

    cout << NPZcontainer.at(0) << " ";
    

    ich habs jetzt mit eckigen Klammern, .. war ja nicht untätig ...

    ;Rohan schrieb:

    Dass du die Primzahlen und Nichtprimzahlen in einem Container speicherst ist eigentlich auch unnötig, du musst dir ja nur den Anfang der jeweils aktuellen Kette merken.

    hat ich auch schon gemerkt, aber für den Anfang und zur Kontrolle erst mal gut ....



  • otto56 schrieb:

    Und wo bekomme ich die Startzahlen der einzelnen Ketten im Protokoll, welches am Ende ausgegeben wird?

    NPZcontainer[0] ist jeweils die Startzahl, die speicherst du alle in der map.

    otto56 schrieb:

    ich habs jetzt mit eckigen Klammern, .. war ja nicht untätig ..

    .
    Nur benutzen wenn du zu 100% sicher bist, dass der jeweilige Index zu diesem Zeitpunkt auch existiert. at() führt einen range check durch, [] nicht.


Log in to reply