Zufallszahlen aus dem Zahlenfeld werden nicht richtig verteilt.
-
Hallo ich bin Neu hier und ebenso noch ein absoluter Amateur und brauche deshalb mal etwas Hilfe bei einem Programm. Habe ein Programm geschrieben das Zufallszahlen erstellt. mit einer Funktion welche die Zufallszahlen in 10 verschieden Bereiche einteilen soll. So und hier ist das Problem. Das klappt nur mit der ersten Zahl danach wird immer irgendeine Speicheradresse oder so durch die Sortierfunktion geschickt. Deshalb habe ich mal eine Ausgabefunktion Programmiert um zu sehen was ich so erhalte un da kommt nur Schrott raus. Mach da jetzt schon ne Woche rum wäre toll wenn mir da jm. weiterhelfen könnte.
-
Hallo, es gibt da erst mal ein paar grundsätzliche Dinge.
In C++ haben die Include-Dateien der Standardbibliothek keine Endung (kein .h).
Den Standard C Include-Dateien wird ein c vorangestellt, also z. Bsp.#include <cmath>Die Elemente der C++ Standardbibliothek (inklusive der aus dem C Standard übernommenen Teile) befinden sich im Namensraum std.
Die Funktion main muss int als Rückgabetyp haben, aber das return Statement kann weggelassen werden und am Ende dieser speziellen Funktion wird dann automatisch 0 (=> 0 Fehler) zurückgegeben.
Bei der Arbeit mit rand ist es empfehlenswert, genau einmal (am Anfang der main Funktion) srand aufzurufen.Was dein Programm angeht, liegt das Problem vermutlich darin, dass du die Bedingungen in der "Gruppenzuweisung" nicht so formuliert hast, wie du es gemeint hast. Wenn beispielsweise zahl[ i ] zwischen 100 und 200 liegen soll, muss die Bedingung
if (zahl[ i ] < 200 && zahl[ i ] > 100)lauten, denn das logische oder, das du verwendet hast, würde in dem Fall alle Zahlen über 200 erlauben.
-
Dein Programm könnte man sehr stark vereinfachen, dann wird es wahrscheinlich auch leichter, den Fehler zu finden. Und statt einer einfach verketteten Liste würde ich eventuell zu STL-Containern raten.
#include <stdlib.h> // Einbindung der Bibliothek stdlib.h für rand #include <conio.h> // Einbindung der Bibliothek Conio für getch() #include <iostream.h> // Einbindung der Bibliothek iostream für cout, using namespace std; #include <time.h> // Einbindung der Bibliothek time.h für srand #include <math.h> // Einbindung der Bibliothek math.h für Mathematische FunktionenDie Bibliotheken sind veraltet. Verwende <cstdlib>, <iostream>, <ctime> und <cmath>. Brauchst du die wirklich alle?
const int Size = 500;
struct tGruppen { int Gruppe1 [Size]; int Gruppe2 [Size]; int Gruppe3 [Size]; int Gruppe4 [Size]; int Gruppe5 [Size]; int Gruppe6 [Size]; int Gruppe7 [Size];int Gruppe8 [Size]; int Gruppe9 [Size]; int Gruppe10[Size]; tGruppen *next; };Die 10 Membervariablen könntest du in einem 2D-Array speichern.
int zaehler1 = 0; int zaehler2 = 0; int zaehler3 = 0; int zaehler4 = 0; int zaehler5 = 0; int zaehler6 = 0; int zaehler7 = 0; int zaehler8 = 0; int zaehler9 = 0; int zaehler10 = 0;Das wäre wohl einfacher mit einem Array zu lösen:
int zaehler[10] = {0};void main(void) // main() muss standardmässig int zurück geben --> int main() { srand(time(0)); // würde dann hier hin gehören struct tGruppen *pTop = NULL; // willst du die Struktur nicht auf dem Stack haben? cout<< HEAD <<endl; // Headzeile wird ausgegeben zufallszahlen(pTop); ausgabe(pTop); ausgabe2(pTop); } void zufallszahlen (tGruppen *pTop) { const int anz=101; int zahl[anz]; // integer genaue Gleitpunktzahl, z.B. 3.14 und 299793.0 --> wie meinst du das? Integer oder Gleitkommazahl? Wohl eher Float oder? ( (unsigned)time( NULL ) ); // hier machst du rein gar nichts cout << "Hier einige Zufallszahlen"<<endl; for (int i=1; i<=anz-1; i++) // statt i<=anz-1 kannst du i<anz schreiben. { zahl[i] = rand()%1000; // Zuweisung einer Zufallszahl cout << zahl[i]<<"\t"; Gruppenzuweisung (pTop, zahl); } } /**/ void Gruppenzuweisung (tGruppen *&pTop, int zahl[]) // Warum Zeiger auf Referenz? { if (!pTop) { pTop = new tGruppen; pTop->next = NULL; // würd ich im Konstruktor machen } const int anz=101; int a[11] = {0}; for (int i=1; i<=anz; i++) { // Die If-ElseIf-Orgien kannst du auch in eine Schleife packen... // Aber Vorsicht: Bis jetzt schreibst du über die Array-Grenzen hinaus, denn anz ist 101 und a hat nur 11 Elemente... }return; // Am Schluss einer void-Funktion wird immer zurückgesprungen --> return überflüssig } void ausgabe (tGruppen *pTop) { if (pTop) { // Hier sollte eine Schleife sein, die das Array durchgeht } } void ausgabe2 (tGruppen *pTop) // könntest du auch in einer Schleife machen { // ... }
-
Vertausche mal die beiden Zeilen 49 und 50 miteinander, so dass der Aufruf 'Gruppenzuweisung (pTop, zahl);' außerhalb der for-Schleife steht. Weil Du sonst mit einem nur teilweise initialisierten Array 'zahl' in die Funktion 'Gruppenzuweisung' reingehst.
Dann hast Du bei der Funktion 'zufallszahlen ' die Referenz vergessen - also
void zufallszahlen (tGruppen *&pTop);und letztlich belegst Du in der Funktion 'Gruppenzuweisung' von der Struktur tGruppen nur den Member 'Gruppe1[]', gibst aber alle anderen auch aus (in 'ausgabe'). Da steht dann natürlich nur Schrott drin; den Membern Gruppe2 bis Gruppe10 wurden ja nie mit ein Wert zugewiesen.
Gruß
Werner
-
1. es heisst:
#include <cstdlib> #include <iostream> #include <ctime> #include <cmath>Dann hast du ein paar Sachen drin, wie HEAD, wo er nicht findet.
Dann könntest du bei den tGruppen ein 2 Dimensionales Array machen, anstatt die vars so aufzuzählen. Ebenso zaehler.
Ich erhalte nach dem zweiten 0-en.
-
wenn ich richtig verstehe, was du vorhast, könntest du es wie folgt abwickeln:
#include <iostream> //für cout #include <iomanip> //für setw #include <vector> //für vector #include <cstdlib> //für srand und rand #include <ctime> //für time //Dadurch darf man zum Beispiel cout statt std::cout schreiben, //aber dafür kein eigenes cout mehr im globalen Namensraum haben. using namespace std; int main() { const int GROUP_COUNT = 10; const int NUMBER_COUNT = 100; const int NUMBER_MAX = 1000; vector<int> groups[GROUP_COUNT]; //Zufallsgenerator initialisieren (nur einmal für das ganze Programm!) srand(time(0)); //Zufallszahlen erzeugen und der entsprechenden Gruppe zuweisen for (size_t i = 0; i < NUMBER_COUNT; ++i) { int number = rand()%NUMBER_MAX; groups[number/(NUMBER_MAX/GROUP_COUNT)].push_back(number); } //Übersicht wie viel Zahlen in welcher Gruppe sind for (size_t i = 0; i < GROUP_COUNT; ++i) cout << "Gruppe " << (i+1) << ":\t" << setw(2) << groups[i].size() << " Elemente\n"; //Detaillierte Übersicht der Zahlen in den einzelnen Gruppen for (size_t i = 0; i < GROUP_COUNT; ++i) { cout << "\nGruppe " << (i+1) << ":\n"; for (size_t j = 0; j < groups[i].size(); ++j) cout << setw(3) << groups[i][j] << "\n"; } }
-
Hallo erst mal Danke an euch ihr seit das erste Forumm das mir wirklich weiter geholfen hat ich werde jetzt versuchen die meisten eurer Tips umzusetzen. Naja das arbeiten mit nem Array habe ich gemacht allerdings habe ich im Moment auch noch schwächen ein array in eine Funktion zu übergeben und diese dann wieder zurück zugeben. deshalb hab ich versucht das zu vermeiden. Wegen den Bibliotheken muss ich leider sagen das ich nix verstehene. Arbeite mit Microsoft VS 6.0 und hab keine Ahnung wie ich daruf kommen sollte das mit den Bibliotheken zu ändern. In der Hilfe werden diese auch verwendet und in dem Buch mit dem ich lerne auch. Hättet ihr vielleicht ne erklärung oder nen Link.
MFG Chris
-
ChrisTucker schrieb:
Wegen den Bibliotheken muss ich leider sagen das ich nix verstehene.
Der C++98 Standard kennt schlicht und ergreifend keine Standardheader mit einer Dateiendung mehr. Alle Header der C-Standardbibliothek wurden zudem um ein "c" im Namen ergänzt. Und alles aus der Standardbibliothek ist nach dem C++98 Standard im Namensraum std (Sprich statt cout z.b. std::cout...).
ChrisTucker schrieb:
Arbeite mit Microsoft VS 6.0
Wenn du nicht diese IDE zwingend verwenden musst, bitte gleich umsteigen. VS6 ist dermaßen veraltet und nicht Standardkonform...
Hinweis: Wenn du die MFC nicht brauchst gibt es die Express Edition vom Visual C++ 2008 kostenlos.
ChrisTucker schrieb:
In der Hilfe werden diese auch verwendet und in dem Buch mit dem ich lerne auch. Hättet ihr vielleicht ne erklärung oder nen Link.
Dann auch ganz dringend das Buch ändern. Es gibt wohl zwei wirklich gute Einstiegsbücher: Entweder der C++ Primer (den es in deutsch und englisch zu kaufen gibt) oder wenn dir englisch nichts ausmacht: Thinking in C++ Volume 1+2.
cu André
-
Da steht einiges über Arrays und deren Übergabe. Da solltest du dann auch relativ einfach auf ein eindimensionales übertragen können.
-
@minimi
nette Lösung leider für mich zu fortgeschritten außerdem würde ich gerne mein Programm zum laufen bringen.Hallo es läüft viel Besser als vorher, aber ich brauch noch ein wenig Hilfe.
Hat jm. Rat wie ich das ganze If else Zeug verkürzen könnte.
Achja wegen der Bibliotheken bitte nicht sauer sein, ich habe es zwar kapiert, arbeite aber noch mit dem alten Programm, mit dem Neuen muss ich mich erst mal einarbeiten.
-
Hallo kommt noch jemand in meinen Thread?

-
ChrisTucker schrieb:
.. außerdem würde ich gerne mein Programm zum laufen bringen.
Hallo Christian,
dann sage uns doch mal konkret, was nicht geht.
Nochmal zur Info: wenn man ein Array Gruppe[10] definiert, so ist nur der Zugriff auf Gruppe[0] bis Gruppe[9] zulässig. Die '10' bei der Definition gibt die Anzahl der Elemente an, aber die Zählung der Indizes beginnt bei 0, nicht bei 1. Also 0,1,2 .. 8,9 sind die 10 gültigen Indizes.
Gruß
Werner
-
Also ich habe es jetzt einwandfrei zum laufen gebracht allerdings würde ich gerne das mit der if else Anweisung ein wenig vereinfachen, mit ner Schleife oder so aber cih bekomme en nicht so ganz hin liegt daran das ich nicht weis wie ich soviele Variablen gleichzeitig beim schleifendurchlauf berücksichtigen soll. Habe mal eine Seite weiter hinten den letzten stand des Quellcode hinein edittiert.
-
Hast du meinen Post angeschaut? Ich habe diverse Änderungsvorschläge gebracht, von denen du keinen einzigen beachtet hast (z.B. neue Header,
int main()etc...). Dann hättest du auch keine Überschreitungen der Arraygrenzen. Aber es reicht scheinbar nicht, wenn es auch noch Werner Salomon sagt. Das selbe gilt übrigens für die Header - bereits 5 Mal wurde es schon erwähnt (Kreppel, ich, drakon, minimi, asc), aber du inkludierst immer noch <iostream.h>...
Und wenn du Schleifen beherrschst, solltest du das auch hinkriegen mit den If-Else-Abfragen.
void Gruppenzuweisung (tGruppen *&pTop, int zahl[]) { // ... for (int i=0; i<anz; i++) // pass hier auf, dass anz nicht zu gross wird. { if (zahl[i] > 100*i && zahl[i] < 100*(i+1)) { pTop->Gruppe[i][a[i]] = zahl[i]; a[i]++; zaehler[i]++; } } }Ich habe jetzt einfach mal die Abfragen in einer Schleife zusammengefasst, ohne den ganzen Zusammenhang mit eventuellen anderen Fehlern zu untersuchen. Du solltest versuchen, die Vereinfachung zu verstehen, und nicht ohne Weiteres zu kopieren. Zudem solltest du vielleicht den grundlegenden Aufbau noch einmal überdenken, dann hättest du auch nicht mit Pointern auf Referenzen zu tun...
Ich hoffe, du schaust meinen vorherigen Thread und diesen genau an, sonst muss ich mir überlegen, dir weiterhin zu helfen...

-
ChrisTucker schrieb:
Achja wegen der Bibliotheken bitte nicht sauer sein, ich habe es zwar kapiert, arbeite aber noch mit dem alten Programm, mit dem Neuen muss ich mich erst mal einarbeiten.
Hast du es denn mal probiert mit <iostream> und so, ohne .h am Ende? Denn ich bin mir ziemlich sicher, dass sogar Visual C++ 6 diese Header kennt.
-
Also das mit den Bibliotheken geht nicht der erkennt die nicht, wie gesagt er erkennt nur die wo ich benutze. Umsteigen auf ein neues VS kann ich nicht. Weil Microsoft nicht Abwärtskompatibel ist. und die Programme müssen wieder mit VS 6.0 geöffnet werden. Außerdem ist des VS 6.0 Eine Vollversion die ich kostenlos nutzen kann.
Wieso darf anz nicht zu groß werden?
Die Header hab ich geändert Allerdings meldet er dann immer warnings das ich einen Wert zurückgeben muss.warnings
C:\Dokumente und Einstellungen\Neo\Desktop\c++\Aufgabenblatt\Aufgabe8\Aufgabe8_Feldstatistik1.cpp(164) : warning C4518: 'int ' : Unerwartete(r) Speicherklassen- oder Typbezeichner; wird ignoriert
C:\Dokumente und Einstellungen\Neo\Desktop\c++\Aufgabenblatt\Aufgabe8\Aufgabe8_Feldstatistik1.cpp(164) : warning C4228: Nicht dem Standard entsprechende Erweiterung : Qualifizierer nach einem Komma in der Deklaratorliste werden ignoriertAlso habe es jetzt zum Laufen bekommen, bin euch shr dankbar für eure Geduld. Werde natürlich jetzt noch versuchen soviel eir möglich von euren Verbesserungsvorschlägen noch umzusetzen.
-
ChrisTucker schrieb:
Weil Microsoft nicht Abwärtskompatibel ist. und die Programme müssen wieder mit VS 6.0 geöffnet werden. Außerdem ist des VS 6.0 Eine Vollversion die ich kostenlos nutzen kann.
1. Kann man ältere Projekte konvertieren. (Klappt ganz gut mit dem VC 09).
2. Bringt dir eine alte Vollversion bei weitem weniger, als eine neue Expressversion, die sich an der Standard hält. (Das du die Features, die dir nicht angeboten werden eh nicht brauchst, mal ganz davon abgesehen.)
-
drakon schrieb:
ChrisTucker schrieb:
Weil Microsoft nicht Abwärtskompatibel ist. und die Programme müssen wieder mit VS 6.0 geöffnet werden. Außerdem ist des VS 6.0 Eine Vollversion die ich kostenlos nutzen kann.
1. Kann man ältere Projekte konvertieren. (Klappt ganz gut mit dem VC 09).
2. Bringt dir eine alte Vollversion bei weitem weniger, als eine neue Expressversion, die sich an der Standard hält. (Das du die Features, die dir nicht angeboten werden eh nicht brauchst, mal ganz davon abgesehen.)Was kostet mich den das neue Visual Studio? Muss ich da was beachten beim Kauf?
-
ChrisTucker schrieb:
drakon schrieb:
ChrisTucker schrieb:
Weil Microsoft nicht Abwärtskompatibel ist. und die Programme müssen wieder mit VS 6.0 geöffnet werden. Außerdem ist des VS 6.0 Eine Vollversion die ich kostenlos nutzen kann.
1. Kann man ältere Projekte konvertieren. (Klappt ganz gut mit dem VC 09).
2. Bringt dir eine alte Vollversion bei weitem weniger, als eine neue Expressversion, die sich an der Standard hält. (Das du die Features, die dir nicht angeboten werden eh nicht brauchst, mal ganz davon abgesehen.)Was kostet mich den das neue Visual Studio? Muss ich da was beachten beim Kauf?
Express ist Gratis.
http://www.microsoft.com/germany/express/download/default.aspx
-
ChrisTucker schrieb:
Was kostet mich den das neue Visual Studio? Muss ich da was beachten beim Kauf?
Die Express-Version ist kostenlos und reicht ziemlich sicher aus.
Geh auf http://www.microsoft.com/germany/express/ und lade dort die C++-Version herunter.Edit: Verdammt, drakon!

-
Hallo wie von euch empfohlen habe ich jetzt auf die Version 2008 umgestellt. Das Programm das vorher noch ging ist jetzt wieder ein Absturzprogramm. Syntax stimmt trotzdem klappt die Gruppenverteilung nicht.
Desweiteren steht in der Version 2008 das ich sie nur noch 25 Tage nutzen kann und ich ein Registrierschlüssel eingeben soll.Kann das Vielleicht an Zeile 31 liegen das die Struktur in den Stack muss?? Wenn ja wie bekomme ich das hin?