Geschwindigkeitsproblem bei Zufallszahlen
-
Hallo Hundefutter,
bei mir kommt ein Assert, wenn ich deinen Code kompiliere.
Desweiteren ist mir aufgefallen,
#include <iostream> #include <algorithm> #include <vector> #include <time.h> using namespace std; class RandomNumber { public: RandomNumber() { srand(time(0)); } int operator() ( int n) { return (int)((double)n * rand()/(RAND_MAX+1.0)); } }; int main() { typedef vector<int, allocator<int> > IntVector ; IntVector cards(36); int mem_zaehler = 1; int i; //--------------------------------- //Sollte die nicht bei 0 loslaufen? //--------------------------------- for(i=1;i< 19;i++) { cards[i] = mem_zaehler; mem_zaehler++; } mem_zaehler = 1; //-------------------------------- //Nicht doch lieber i < 36? //-------------------------------- for(i=19;i<37;i++) { cards[i] = mem_zaehler; mem_zaehler++; } RandomNumber rnd; std::random_shuffle(cards.begin(),cards.end(),rnd); //-------------------------------- //Nicht doch lieber i < 36? //-------------------------------- for(i=1;i<37;i++) { cout << cards[i] << endl; if(i==18) {cout << endl;} } cin >> i; return 0; };Zu den Nullen:
Bei mir wird der IntVector beim Erzeugen mit 0en vorbelegt
(benutze Visual C++ 2005)Die doppelten Zahlen:
Naja, durch die zwei Vorschleifen kommen doch jeweils zweimal die gleichen Zahlen vor.Gruss
Tobi
-
Wenn ich den Vektor einfach nur Fülle und ausgeben lasse, also das random_shuffle mal wegklammer, dann gibt er mir 2 mal jeweils für 1-18 und für 19-36 die Zahlen von 1-18 aus. Also das Füllen funktioniert einwandfrei.
Daher würde ich auch sagen, dass die Bedingungen der For-schleifen auch richig gewählt sind, da diese ja für das Füllen verantwortlich sind und dieses auch perfekt funktioniert.
Nur wenn ich dann das random_shuffle wieder reinnehme, dann tauchen in den 2 Zahlenreihen (1-18 u. 19-36) manche Zahlen doppelt auf und es kommen auch Nullen vor, wobei doch eigentlich in Jeder Zahlenreihe die Zahlen von 1-18 durcheinandergewürfelt vorkommen müssten, keine doppelt und auch keine Nullen.
Denke also, dass es am random_shuffle liegt, da nach dem Füllen ja noch alles richtig ist.
MfG
Hundefutter
-
std::vector beginnt bei 0 nicht bei 1. Daher sind Deine Grenzen falsch.
std::randon_shuffle nutzt daher die Werte von cards[0]...cards[35]. Du schreibst aber nach cards[1]...cards[36]
Daher Dein Problem.
Wenn Du natürlich nach cards[1]...cards[36] schreibst und das dann wieder ausgibst, ist die Wahrscheinlichkeit, dass das richtige rauskommt sehr hoch. Wenn Du Pech hast, gibt es aber einen Absturz, da cards[36] nicht mehr gültig ist. Oder wie schon berichtet eine Assertion, wenn die STL prüft, ob die Zugriffe gültig sind.random_shuffle würfelt Deine 36 Zahlen insgesamt durcheinander, d.h. in den ersten 18 Werten können Zahlen doppelt vorkommen.
Ich würde erwarten, dass eine Zahl != 0 nur einmal vorkommt, dafür einmal die 0 und alle anderen Zahlen zweimal.BTW, die RandomNumber Klasse ist unnötig. Das macht random_shuffle bis auf das srand selbst (das fehlte Dir im ersten Ansatz).
Ausserdem sollte vector<int> reichen, die Angabe des allocators sollte nicht notwendig sein.
-
Das hier sollte es auch tun
#include <iostream> #include <algorithm> #include <ctime> // statt time.h #include <vector> #include <cstdlib> // statt stdlib.h (stdio ist unnötig) using namespace std; int main() { vector<int> cards(36); // mem_zaehler ist unnötig, i sollte in der Schleife deklariert werden for(int i=0;i< 18;i++) // eine Schleife reicht { cards[i] = i+1; cards[i+18] = i+1; } srand(time(0)); // Initialisierung Zufallsgenerator nur einmal // Beide Teile separat mischen (evtl. besser zwei Vektoren verwenden) std::random_shuffle(cards.begin(),cards.begin()+17); std::random_shuffle(cards.begin()+18,cards.end()); for( int i=0; i<36; ++i) { cout << cards[i] << "\n"; if( i== 17 ) cout << "\n"; } }
-
ok, jetzt funktioniert es!
Vielen Dank für die ganzen Hilfen.

MfG
Hundefutter
-
Hätte jetzt nur noch ein weiteres kleines Problem:
Bin jetzt mal dabei, das ganze in mein eigentliches Projekt einzubauen. Jetzt wollte ich den Vector in einer Klasse als Protected deklarieren, damit er nur durch Methoden der Klasse verändert werden kann:
#include <vector> class Cmemory { //[...] protected: std::vector<int> cards(36); };Jetzt gibt er mir jedoch folgende Fehlermeldung beim Kompilieren aus:
error C2059: Syntaxfehler : 'constant'
Fehler beim Ausführen von cl.exe.Es bezieht sich auf die Zeile, in der der Vector deklariert wird. Was ist jetzt daran falsch?
MfG
Hundefutter
-
Hallo
der von dir gezeigte Ausschnitt ist soweit in Ordnung, der eigentliche Fehler wird wo anders ausgelöst.
Insbesondereerror C2059: Syntaxfehler : 'constant'
deutet darauf hin. Hast du irgendwo constant stehen? Soll doch sicher const heißen
bis bald
akari
-
Das wundert mich ja, habe nirgendswo ein const drin....
Hier ist die gesammte Datei:
#include <vector> class Cmemory { public: Cmemory(); virtual ~Cmemory(); void init_memory(void); void change_card(int i); void clean_up(void); protected: std::vector<int> cards(36); };Habe keine ahnung, wo der da ein const sieht..
MfG
Hundefutter
-
Hundefutter schrieb:
protected: std::vector<int> cards(36);Initialisieren kannst du diesen vector erst im Konstruktor.
-
Alles klar, danke!