n-viele Integer Zahlen deklarieren?



  • Ach vector ^^ vielen Dank an euch beide 🙂 Dabei arbeite ich die ganze Zeit mit vectoren 🙂 w

    Weiß noch jemand wie ich die alle unterschiedlich setzen kann? Bei 4 Zahlen habe ich das mit einer whileschleife gemacht . Jedoch wird die Bedingung für jede weitere Zahl die zu überprüfen ist immer länger -.-

    Gruß



  • Was genau ist denn deine Anforderung? Vielleicht ist std::set eine Alternative zu std::vector?



  • Also ich bin noch nicht so lange bei C++ ^^ Ist halt ein kleiner Programmierkurs über ein Semester gewesen. Es geht darum das ich ein Spiel programmiere (Minesweeper) und ich will je nach Feldgröße verschiedene Mengen von Minen legen. Deswegen halt die variable Anzahl an Integers. Diese sollen die Positionen der Minen auf einem eindimensionalen Vektor darstellen. Auf einem 8x8 Feld will ich beispielsweise 10 Minen legen. Dabei sollen diese Minenpositionen die ich wohl in einem Vector erzeuge, paarweise verschieden sein.

    srand( (unsigned)time( NULL ) );
          A1 = rand()%63;
          A2 = rand()%63;
    	while(A2==A1) A2 = rand()%63;
          A3 = rand()%63;
          while(A3==A1 || A3==A2) A3 = rand()%63;
    	A4 = rand()%63;
    	while(A4==A1 || A4==A2 || A4==A3) A4 = rand()%63;
    

    So hatte ich vor kurzem 4 verschiedene Zahlen erzeugt zwischen 0 und 63.
    Hoffe jemand kann mir (Anfänger) da helfen.^^

    Gruß



  • Meinst du sowas?

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    int main()
    {
    int value;
    vector< int > theValues;
    
    while( cin >> value, value != 0 )
    {
    theValues.push_back( value );
    }
    
    // Du kannst so lange Zahlen eingeben, bis du eine 0 eingibst, jede Zahl wird in den Vektor kopiert. Umgang mit Vektor wird dir ja vll bekannt sein? Wenn nicht, du kannst über Iteratoren oder Indizies( sowas hier [0] ) auf die einzelnen Elemente zugreifen.
    

    Lg freeG

    EDIT:
    Weiß nicht ob du das gemeint hast, war auf deinen Post davor bezogen nicht auf deinen letzten.

    Ok ich habs glaub falsch verstanden.
    Meinst du so:

    int anzahlMines = 10;
    vector< int > mines;
    
    for( int i = 0; i != 10; ++i )
    {
    mines.push_back( rand() % 63 );
    }
    

    Lg freeG



  • @SeppJ:
    Wiso ist das denn kompliziert? Wenn die Größe eines Feldes bekannt ist und sich nicht mehr verändert, spricht doch auch nichts gegen ein dynamisches Feld. Ein solches Feld ist IMHO auch recht einfach zu Handhaben. Sollte das Feld noch erweitert werden, würde ich auch zu vector tendieren.

    Das Setzen der Zahlen ist doch einfach:

    for(int i=0;i<n;i++)
    {
        A[i] = rand()%m+1;
    }
    
    // oder mit einer while-schleife
    
    int i=0;
    while(i<n)
    {
        A[i++] = rand()%m+1;
    }
    
    // rand()%m+1 liefert eine Zahl zwischen 1 und m
    

    MfG, Jochen



  • SOVIELE ANTWORTEN. 😮

    Vector ist mir bekannt. Das Problem ist halt das ich n paarweise verschiedene Zahlen erzeugen will. 🙂

    Das wäre etwas wie:

    int n; 
    cin >> n; //ANZAHL DER ZAHLEN
    vector<int> val(n);
    srand( (unsigned)time( NULL ) );
    for(int i = 0; i <= n-1; i++) {
    val[i] = rand()%m; 
    }
    

    Nur diese Zahlen wären im Allgemeinen nicht paarweise verschieden. 😞

    PS: ERZEUGT rand()%m; dann nur Zahlen zwischen 0 und m-1?


  • Mod

    Jochen S. schrieb:

    @SeppJ:
    Wiso ist das denn kompliziert? Wenn die Größe eines Feldes bekannt ist und sich nicht mehr verändert, spricht doch auch nichts gegen ein dynamisches Feld. Ein solches Feld ist IMHO auch recht einfach zu Handhaben. Sollte das Feld noch erweitert werden, würde ich auch zu vector tendieren.

    Nenn mir einen Vorteil eines dynamischen Arrays gegenüber Vector. Nur einen. Dafür habe ich mindestens einen gravierenden Nachteil des des dynamischen Arrays: Kein RAII. D.h. man ist für das Aufräumen selber verantwortlich. Sobald das Programm auch nur ein bisschen komplexer wird, wird es kompliziert.

    Dazu bietet Vector auch noch jede Menge Zusatzfeatures: Erweiterbarkeit, Kopierbarkeit( ⚠ ), Bekannte Größe, verschiedene Zugriffsmethoden, einheitliches Interface (d.h. Austauschbarkeit mit anderen Containern). Und das alles für lau.



  • Wenn die Zahlen verschieden sein sollen, kann man folgendes machen:

    int Random(int m)
    {
        static std::vector<int> A(m);
        static NumValues = 0;
    
        bool RunLoop = true;
        int x;
    
        while(RunLoop)
        {
            x = rand()%m+1;
            for(int i=0;i<NumValues;i++)
            if(A[i]==x)RunLoop = false;
            RunLoop = !RunLoop;
        }
    
        if(++NumValues>=m)NumValues=0;
        return x;
    }
    

    Die Funktion liefert Zufallszahlen zwischen 1 und m und verhindert Wiederholungen. (Hab sie nicht getestet, müsste aber korrekt sein.)

    Eventuell kann dir die Funktion ja nützlich sein.

    MfG, Jochen


  • Mod

    BAHA schrieb:

    Vector ist mir bekannt. Das Problem ist halt das ich n paarweise verschiedene Zahlen erzeugen will. 🙂

    Wenn ich dich recht verstehe: Schreib doch erstmal die Zahlen der Reihenfolge nach in den vector und dann mach ein random_shuffle.



  • int N = ...;
    std::vector<int> zahlen;
    int MAX = 10;
    while(N--)
    {
      int r = -1;
      while(r == -1 || std::find(zahlen.begin(), zahlen.end(), r) != zahlen.end())  // r schon enthalten?
        r = rand() % MAX + 1;
      zahlen.push_back(r);
    }
    

  • Mod

    Das hier immer wieder so Algorithmen mit derart schlechter Zeitkomplexität vorgeschlagen werden. 🙄

    @Maxi und Jochen S.: Testet Eure Vorschläge mal mit 10.000 oder 100.000 Zahlen und staunt wie lange selbst ein heutiger Rechner dafür braucht.



  • Hmm ich werde mal das von Jochen S. testen. Der Rest ist für mich als Anfänger leider etwas zu kompliziert, bzw reichen meine ohnehin eher dürftigen Kenntnisse nicht soweit.

    Vielleicht kann mir jemand noch zum Schluss diese Frage beantworten.

    rand()%m; // ERZEUGT Zahlen zwischen 0 und m
    

    oder

    rand()%m; // ERZEUGT Zahlen zwischen 0 und m-1
    

    ps. laut Aufgabenstellung soll das Feld beliebig groß sein (jedoch nicht zu groß -.-) Denke so eine Begrenzung durch das Konsolenfenster ist legitim.



  • rand()%m erzeugt Zufallszahlen zwischen 0 und m-1.
    Wenn du Zufallszahlen zwischen 1 und m haben willst, musst du noch 1 hinzuaddieren.

    Kleine Optimierung meiner Funktion Random:

    int Random(int m)
    {
        static std::vector<int> A(m);
        static NumValues = 0;
    
        bool RunLoop = true;
        int x = rand()%m+1;
        int var = 0;
    
        while(RunLoop)
        {
            for(int i=0;i<NumValues;i++)
                if(A[i]==x){RunLoop = false;x=var++;}
            RunLoop = !RunLoop;
        }
    
        if(++NumValues>=m)NumValues=0;
        return x;
    }
    

    Dürfte schneller sein. Ist aber nicht mehr ganz so zufällig 😉

    MfG, Jochen


  • Mod

    Das sind Zahlen zwischen 0 und m-1, jeweils einschließlich. Das Prozentzeichen ist der modulo-Operator, das heißt der Rest einer Division durch m. Und der kann logischerweise nur zwischen 0 und m-1 liegen.



  • @SeppJ: Mir ist klar, dass der Algo nicht grad der schnellste ist. Dafür ist er leicht zu verstehen :).



  • Da hab ich doch letzten auch was gepostet... passt gut hierher:

    RNG ohne Duplikate.
    Laufzeitverhalten ist linear beim Erzeugen, konstant beim Ziehen. Speicherverbrauch wächst leider auch linear 😃

    Edit:
    2. Posting auf der Seite



  • SeppJ schrieb:

    BAHA schrieb:

    Vector ist mir bekannt. Das Problem ist halt das ich n paarweise verschiedene Zahlen erzeugen will. 🙂

    Wenn ich dich recht verstehe: Schreib doch erstmal die Zahlen der Reihenfolge nach in den vector und dann mach ein random_shuffle.

    einfacher gehts gar nicht mehr - schneller auch nicht.

    #include <algorithm> //random_shuffle
    #include <iostream> //ein + ausgabe
    #include <vector> //unser container für die zahlen
    #include <cstdlib> //unsere zufallszahlen-funktion
    
    int main()
    {
      using namespace std;
    
      srand(time(0)); //zufallszahlen generator initialisieren
      rand(); //die erste zufallszahl ist nicht gut genug für uns
        //dieser zufallszahlengenerator wird intern (so lang nicht anders angegeben) von random_shuffle verwendet
    
      int max;
      cin >> max;
      vector<int> numbers(max);
      for(int i(0); i != max; ++i)
        numbers[i] = i;
    /*numbers sieht jz (bei max==5) so aus: {0; 1; 2; 3; 4}*/
    
      int count;
      cin >> count;
      if(count > max)
        return EXIT_FAILURE;
      random_shuffle(numbers.begin(), numbers.end()); //mischen
    /*numbers sieht jz z.Bsp. so aus: {3; 2; 4; 0; 1}*/
      numbers.resize(count);
    /*numbers sieht (bei count==3) so aus: {3; 2; 4}*/
    
    //die ausgabe, damit du auch siehst, dass es funktioniert:
      for(vector<int>::const_iterator i(numbers.begin()), e(numbers.end()); i != e; ++i)
        cout << *i << endl;
    
      char dont_close;
      cin >> dont_close;
    }
    

    random_shuffle(numbers.begin(), numbers.end()); //mischen
    die Zeile ist vermutlich die einzige, die du nicht verstehst.
    Sollte aber eigtl ganz intuitiv zu verstehen sein.
    Dokumentation dazu:
    http://www.cplusplus.com/reference/algorithm/random_shuffle/

    bb

    PS: Gabs bei std::vector nicht auch irgendwo im Standard nen Satz zum CTor(die iteratoren-Überladung) von wegen: Wenn der iterator zu nem size_t gecastet werden kann, dann werden Zahlen eingefügt? Habs gerad nicht auf die Schnelle finden können, war mir aber eigtl relativ sicehr... -.-



  • unskilled schrieb:

    PS: Gabs bei std::vector nicht auch irgendwo im Standard nen Satz zum CTor(die iteratoren-Überladung) von wegen: Wenn der iterator zu nem size_t gecastet werden kann, dann werden Zahlen eingefügt? Habs gerad nicht auf die Schnelle finden können, war mir aber eigtl relativ sicehr... -.-

    was meinen? es gibt einen konstruktor, der X-mal den Wert Y einfügt, das hat aber nichts mit einem cast zu tun.



  • kunststudent schrieb:

    unskilled schrieb:

    PS: Gabs bei std::vector nicht auch irgendwo im Standard nen Satz zum CTor(die iteratoren-Überladung) von wegen: Wenn der iterator zu nem size_t gecastet werden kann, dann werden Zahlen eingefügt? Habs gerad nicht auf die Schnelle finden können, war mir aber eigtl relativ sicehr... -.-

    was meinen? es gibt einen konstruktor, der X-mal den Wert Y einfügt, das hat aber nichts mit einem cast zu tun.

    Ne, den meinte ich nicht.
    Mir war so, als ob es irgendwo nen (sequentiellen) COntainer gab, bei dem bei der Iterator-Überladung des inserts und/oder des CTors so etwas stand, wie:
    if 'Iterator' could be cast to an size_t ...

    habs aber nicht gefunden - hab 3 Standards(bzw Drafts: '95,'03,'05) durchsucht aber nichts gefunden - wer weiß, wo ich das wieder gelesen hatte... : D

    bb



  • schau dir mal die allgemeine einleitung zu containern an, da steht afair irgendetwas zu dem thema, bezieht sich aber, glaube ich, generell darauf, dass es compilerspezifisch ist, zu bestimmen, ob der iterator ein inputiterator ist oder nicht und falls er das nicht ist, eine andere version der funktion/des konstruktors aufgerufen werden soll.

    eine zeit noch etwas vor concepts und type_traits (zumindest erlaubt es das verwenden von type traits).


Anmelden zum Antworten