Größe eines Array während der Laufzeit ändern



  • Hallo zusammen,
    ich möchte ein kleines Programm schreiben, das zu einer eingegeben Zahl alle Teiler herausfindet. Bis jetzt habe ich es so gemacht, dass alle Teiler einfach ausgegebn werden. Das Mini-Programm sieht so aus:

    #include <iostream.h>
    int main()
    {
     int zahl;
     cin >> zahl;
     for (int i=1; i<=zahl; i++)
     {
      if (zahl % i==0) cout << i << endl;
     }
    };
    

    Nun möchte ich alle Teiler nicht einfach ausgegen, sondern in einem Array speichern. Zwar weiß ich wie man ein dynamisches Array anlegt,
    doch ist hier das Problem, dass ich auf während der Laufzeit keine exakte Größe angegen kann, da ich nicht weiß, wie viele Teiler vorhanden sind. Das Array müsste also immer um ein Element vergrößert werden, wenn ein neuer Teiler gefunden worden ist.

    Außerdem habe ich hier "zahl" als integer deklariert. Damit stoße ich schnell an meine Grenzen, denn mich interessieren riesig große Zahlen. Ich habe an long double gedacht, doch spielt da der "%" Operator nicht mit, da dieser anscheinend nur integer Variablen annimmt. Wie könnte ich dieses Problem lösen?

    Vielen Dank für eure Hilfe
    lg, freakC++



  • #include <iostream.h>
    #include <vector>
    
    int main()
    {
     std::vector<int> numbers;
     int zahl;
     cin >> zahl;
     for (int i=1; i<=zahl; i++)
     {
      if (zahl % i==0)
      { 
        cout << i << endl;
        numbers.push_back ( i );
      }
     }
    };
    

  • Mod

    Solche dynamischen Datenstrukturen kannst du dir entweder mit new/delete und pointern selber zusammenzimmern oder die VIEL bessere Alternative: Du guckst dir mal die Standard Template Library an, da sind nämlich schon viele gängige Container dabei. Für dich eignen sich nach deiner Problembeschreibung wohl std::vector, std::deque oder std::list.

    Hier gibt es eine Entscheidungshilfe:
    http://adrinael.net/containerchoice.png



  • Hallo,
    vielen Dank für die Antworten. Da ich noch keine Erfahrung mit std::vector habe, wollte ich fragen, ob dies nun auch auf (umständlichere) Weis mit einem Array möglich ist...und wie dies etwa aussieht, da ich das nicht so richtig hinbekomme. Am liebsten wäre mir eine KOnstrukion aus Zeigern und Arrays, da ich mich damit beschäftige, aber leider noch nicht in der Lage so ein Konstrukt ohne Hilfe zu erstellen. Könntet ihr mir mal einen Anfangscode posten oder einen Hinweis geben?

    Wie könnte man das "int-Problem" lösen?

    Vielen Dank für euer Bemühen.
    lg, freakC++




  • Mod

    freakC++ schrieb:

    Wie könnte man das "int-Problem" lösen?

    Die Fließkommatypen wie double sind dafür ungeeignet, da diese zwar sehr große Zahlen darstellen können, aber nur bis auf eine gewisse Anzahl zählender Stellen genau (~12-13 in Dezimalstellen). Um wirklich große Ganzzahlen genau darzustellen muss man sich selber etwas programmieren, das ist nicht in Standard C++ enthalten. Da das jedoch ein ziemlich häufiges Problem ist, wurde das schon von vielen Leuten gelöst, eine gute Umsetzung ist zum Beispiel die BigInteger Bibliothek:

    http://mattmccutchen.net/bigint/



  • freakC++ schrieb:

    Hallo,
    vielen Dank für die Antworten. Da ich noch keine Erfahrung mit std::vector habe, wollte ich fragen, ob dies nun auch auf (umständlichere) Weis mit einem Array möglich ist...

    Ja, aber das läuft darauf hinaus, daß Du std::vector nachprogrammierst. Als kleines q&d Beispiel wie man es relativ einfach mit einem Array fester Größe machen kann. Es fehlt noch die Umstellung auf Templates, so daß man auch Typen für beliebig große Zahlen aufnehmen kann und diverse andere Dinge, die std::vector kennt.

    #include <cstdlib>
    #include <algorithm>
    
    class Array {
        std::size_t size_;
        long* p_;
    
        void copy (Array& rhs) {
            for (std::size_t i = 0; i != this->size_; ++i) {
                rhs.p_[i] = this->p_[i];
            }
        }
    public:
        explicit Array (std::size_t s) : size_(s), p_(new long[s]) {}
        Array (Array const& rhs) : size_ (rhs.size_), p_ (new long[rhs.size_]) {
            for (std::size_t i = 0; i != rhs.size_; ++i) {
                this->p_[i] = rhs.p_[i];
            }
        }
        Array& operator= (Array const& rhs) {
            Array t (rhs);
            this->copy(t);
    
            std::swap (t.size_, this->size_);
            std::swap (t.p_, this->p_);
    
            return *this;
        }
        ~Array () {
            delete[] this->p_;
        }
        void increaseSize () {
            Array t (this->size_ * 2);
            this->copy (t);
    
            std::swap (t.size_, this->size_);
            std::swap (t.p_, this->p_);
        }
        long& operator[] (std::size_t i) {
            assert (i < this->size_);
            return this->p_[i];
        }
    };
    


  • Hallo zusammen,

    @Nettes Tutorial: Das ist genau das was ich gesucht habe. Vielen Dank! Zwar ist das keine große Zeigerarbeit, doch liegt die Hauptidee darin, dass ich einfach das alte Array zwischenspeicher. Super 👍

    @SeppJ: Vielen Dank für den Link. Ich werde mich mal morgen in die Materie einarbeiten. Wenn's Schwierigkeiten gibt, dann melde ich mich wieder.

    @~john: Auch dir vielen Dank für deinen Beispielcode. Da ich leider noch gar nicht mit der STL - Libary gearbeitet habe, ist es für mich nicht sehr einfach das komplette Programm nachzuvollziehen. Ich werde jedoch bald diese Wissenslücke schließen. 👍 ´

    Bis bald
    lg, freakC++



  • Zur Einführung in die STL-Container gibts hier einen guten Artikel.

    Als Nachschlagewerk zu den einzelnen Klassen und Funktionen kannst du www.cplusplus.com verwenden. Die Adresse solltest du dir sowieso merken, da dort sehr viele Teile der Standardbibliothek dokumentiert sind.


Anmelden zum Antworten