primzahlen bestimmen



  • hallo!

    ich soll ein programm schreiben, dass alle alle primzahlen von 3 bis 2100 berechnet und in einem vector<int> speichert.

    allerdings habe ich noch etwas schwierigkeiten mit vektoren zu arbeiten.

    int primzahl=3;

    vector<int> primvektor;
    prim.push_back(primzahl);

    for (int i=3; i<=2100; i+=2)
    {

    for (int j=0; j<prim.size(); j++)
    if(i%prim [j]!=0) { prim.push_back(i);}

    sowas habe ich zur zeit, aber natürlich funktioniert das so nicht, denn i%prim [j] ist ja wieder ein vektor und ich kann damit nicht bestimmen, ob da ein glied 0 ist.
    ihr merkt wohl, das mit dem programmieren ist alles noch relativ neu für mich^^

    ich würde mich über eine kleine hilfe freuen.



  • zerleg dir das Problem:
    erster Schritt:

    std::vector<int> prim;
    for (int i = 2; i <= 2100; ++i)
    {
      if (/* i ist prim */)
      {
        prim.push_back(i);
      }
    }
    

    jetzt ist zu überlegen wie man rausfindet ob i prim ist.
    Brute-force wäre, für alle Zahlen kleiner i die Teilbarkeit von i durch die jeweilige Zahl zu testen. Wird kein Teiler gefunden, dann ist i prim.
    Es gibt aber zwei Verbesserungsmöglichkeiten:

    1. wenn i Teiler hat, also gilt i = a*b, dann ist entweder a oder b kleiner oder gleich der Wurzel von i. Man muss also nur bis zur Wurzel nach Teilern suchen
    2. wenn i Teiler hat, dann ist der kleinste Teiler von i eine Primzahl. Außerdem haben wir zu jedem gegebenen Zeitpunkt schon alle Primzahlen kleiner als i im vector gespeichert. wir müssen also nur alle Elemente im vector auf Teilbarkeit testen, die kleiner sind als die Wurzel von i.

    also

    std::vector<int> prim;
    for (int i = 2; i <= 2100; ++i)
    {
      //Teilbarkeit von i testen:
      bool isPrim = true;
      for (std::vector<int>::iterator it = prim.begin(), end = prim.end();
           it != end && (*it < std::sqrt(i)) ; //Reihenfolge ist wichtig!
           ++it)
      {
        if ((i % *it) == 0) //teiler gefunden?
        {
          isPrim = false;
          break;  //Schleife verlassen, brauchen nicht weiter suchen
        }
      }
      //entweder wurde die Schleife abgebrochen weil ein Teiler gefunden wurde, dann ist isPrim == false
      //oder sie ist bis zum Ende durchgelaufen und isPrim == true
    
      if (isPrim)
      {
        prim.push_back(i);
      }
    }
    

    Die Reihenfolge oben ist daher wichtig, weil it nur dann dereferenziert werden darf wenn it != end, hier wird also vom Kurzschluss-operator gebrauch gemacht.


Anmelden zum Antworten