Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > C/C++
You last visited: Today at 22:55

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Lottozahlen Gen. C

Discussion on Lottozahlen Gen. C within the C/C++ forum part of the Coders Den category.

Reply
 
Old   #1
 
elite*gold: 0
Join Date: Jan 2011
Posts: 362
Received Thanks: 41
Lottozahlen Gen. C

Hallo , habe ein kleines Problem .
Habe einen Lottozahlen Generator geschrieben der 6 Zahlen random von 1-49 ausgibt und diese aufsteigen Sortiert. Leider bekomme ich es nicht gebacken das er keine Zahlen doppelt ausgibt und mir fällt leider auch keine idee ein wie ich dies umsetzen könnte.
Für Tipps wäre ich sehr Dankbar.!
Code:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main (void){
	int lotto[7];
	int i,x;
	int a,b,c,zz;
	srand(time(NULL));
	for(a=0;a<7;a++){
		zz=rand()%49+1;
		lotto[a]=zz;
	}
	for(i=0;i<7;i++){
		for(c=0;c<7;c++){
			if(lotto[i]<lotto[c]){
			x=lotto[i];
			lotto[i]=lotto[c];
			lotto[c]=x;
			}
		}
	}
	for(b=0;b<7;b++){
	printf("%i ",lotto[b]);
	}
	system("PAUSE");
	return 0;
}
Rullx3 is offline  
Old 01/25/2013, 15:51   #2
 
elite*gold: 0
Join Date: May 2010
Posts: 793
Received Thanks: 268
du könntest eine liste mit alle zahlen zwischen 1 und 49 machen, aus der du immer random eine ziehst und diese dann aus der liste entfernst.
hier ist mna ein C# code der das macht hoffe du kannst damit was anfangen(die zahlen werden noch nicht sortiert):
Code:
List<int> numbers = Enumerable.Range(1,49); //(.ToList))
int[] ergebniss = new ergebniss[7];
for(int i = 0; i < 7; i++)
{
int r = rand()%numbers.Count;
ergebniss[i] = numbers[i];
numbers.RemoveAt(r);
}
nkkk is offline  
Thanks
1 User
Old 01/25/2013, 16:05   #3


 
Jeoni's Avatar
 
elite*gold: 966
Join Date: Apr 2010
Posts: 1,105
Received Thanks: 681
Als Alternative zur schon erwähnten Liste (std::vector in C++?), kann man auch checken, ob sich die generierte Zahl schon im Array befindet und wenn das der Fall ist, dann einfach nochmal eine Zahl generieren bzw. solange eine Zahl generieren, bis eine generierte Zahl noch nicht im Array steht (Do-While-Schleife). Doch gerade bei größeren Arrays könnte es hier zu Problemen bzw. Verzögerungen kommen, da das Array beim checken, ob sich die generierte Zahl schon darin befindet, vollständig durchgegangen werden muss.
Trotzdem hier mal der Code für diese Variante:
Code:
	for(a=0;a<7;a++){
		do
		{
			zz=rand()%49+1;
		} while (AlreadyInside(lotto, zz, 7)); // solange neue zahlen generieren, bis eine neue dabei ist
		lotto[a]=zz;
	}
(...)
bool AlreadyInside(int* array, int number, unsigned int arraylength) // prüft ob eine gegebene zahl innerhalb eines arrays ist
{
	for (int i = 0; i < arraylength; i++) // das array durchgehen
	{
		if (array[i] == number) // number ist im array
		{
			return true;
		}
	}

	return false;
}
(vergib mir etwaige Fehler, ich hab nur im epvp-editor gemacht)

Ich hoffe, ich konnte helfen
Jeoni
Jeoni is offline  
Thanks
1 User
Old 01/25/2013, 16:16   #4
 
elite*gold: 0
Join Date: May 2010
Posts: 793
Received Thanks: 268
Quote:
Originally Posted by Jeoni View Post
Als Alternative zur schon erwähnten Liste (std::vector in C++?), kann man auch checken, ob sich die generierte Zahl schon im Array befindet und wenn das der Fall ist, dann einfach nochmal eine Zahl generieren bzw. solange eine Zahl generieren, bis eine generierte Zahl noch nicht im Array steht
Jeoni
ja das kann man in dem fall machen. Ist aber im allgemeinen keine schöne lösung, da wenn man z.B. 999 zahlen aus 1000 ziehen will (unter beachtung der reihenfolge).
muss man z.B. bei der 999 zahl durchschnittlich 500 mal versuchen muss zu ziehen bevor man die eine der beiden zahlen zieht die noch nicht gezogen ist. Da die zufallsgeneratorn oft nicht ganz so gut sind eher mehr. D.h wie schnell der algoritmus ist hängt sehr stak vom zufall ab.
nkkk is offline  
Old 01/25/2013, 16:44   #5

 
snow's Avatar
 
elite*gold: 724
Join Date: Mar 2011
Posts: 10,479
Received Thanks: 3,318
Ganz primitive Lösung:

Array mit 49 Feldern. Allen Feldern den Wert 0 zuweisen
-> int zahlen[49];
for (int i = 0; i < 49; i++) {
zahlen[i] = 0;
}

Und dann 6x eine random-Zahl auswerfen:

for (int i = 0; i < 6; i++) {
int random = rand() %49; // somit sind die Zahlen von 0 - 48, also unser Array abgedeckt
if (zahlen[random] == 0)
zahlen[random] = random + 1; // der Zahl am n. Index den Wert n + 1 zuweisen (zahlen[9] = 10 z.B.)
else
--i; // wenn die Zahl noch nicht gesetzt wurde, Zahl setzen, ansonsten i um eins reduzieren, damit es noch einen Durchlauf macht.
}

Und jetzt kannst du die Lottozahlen ausgeben lassen & sie sind sortiert:

for (int i = 0; i < 49; i++) {

if (zahlen[i] != 0)
printf("Lottozahl: %d\n", zahlen[i]);
}

Wir mussten so eine Aufgabe für die Vorlesung machen und ich hab es auch über Sortieren und Durchläufe und was weiß ich gelöst, aber die Lösung hier oben stammt von einem Kommilitonen - finde ich ziemlich gut.
snow is offline  
Thanks
1 User
Old 01/25/2013, 18:27   #6
 
elite*gold: 0
Join Date: Aug 2012
Posts: 236
Received Thanks: 94
Du könntest ein Feld der möglichen Werte erstellen und dann das gezogene Element entfernen, wie nkkk vorschlug. Dabei könntest du das Element entfernen, indem du das Element mit dem gezogenen Index durch das letzte Element der Liste ersetzt und die "Länge" des Feldes dekrementierst. Damit ist das Feld danach zwar nicht mehr sortiert, aber das war ja auch nicht gefordert.
In C könnte das etwa so aussehen:
Code:
const int Länge = 49, Anzahl = 7;
int Feld [Länge];
int Ergebnis [Anzahl];
int gezogen, i = 0, Länge_übrig = Länge;

//das Feld füllen und undefiniertes Verhalten vermeiden
while (i < Länge) {
	Feld [i] = i + 1;
	++i;
}

//die Zahlen auswählen
for (i = 0; i < Anzahl; ++i) {
	gezogen = rand () % Länge_übrig;
	Ergebnis [i] = Feld [gezogen];
	--Länge_übrig;
	Feld [gezogen] = Feld [Länge_übrig];
}
Es wäre auch ganz sinnvoll, nicht Bubblesort zum Sortieren zu nutzen, wenn es mal viele Elemente werden sollten, die sortiert werden sollen.
Tasiro is offline  
Thanks
1 User
Old 01/29/2013, 00:55   #7
 
Raz9r's Avatar
 
elite*gold: 297
Join Date: Dec 2010
Posts: 1,129
Received Thanks: 1,687
Hier sind noch einmal zwei vollständige Lottozahlen-Generatoren: Einer in C ("lottery_c") und einer in C++ ("lottery_cpp").

Code:
// cpp-version
#include <iostream>
#include <random>
#include <set>

// c-version
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// cpp-version
void lottery_cpp();

// c-version
void lottery_c();
void quicksort_c(int *data, int count);

int main(int argc, const char *argv[]) {
	// Test it!
	lottery_cpp();
	lottery_c();
	
	return 0;
}

void lottery_cpp() {
	// Using-Direktiven
	using std::cout; using std::endl;
	using std::size_t; using std::set; using std::less;
	using std::mt19937;	using std::random_device;
	using std::uniform_int_distribution;
	
	// Einstellung für 7 aus 49
	constexpr size_t lottery_numbers_to_draw = 7;
	constexpr size_t lottery_numbers_range_min = 1;
	constexpr size_t lottery_numbers_range_max = 49;
	
	// Ein std::set<T> mit der Sortierung std::less<T> und T = std::size_t für
	// die Lottozahlen.
	set<size_t, less<size_t>> lottery_numbers;
	
	// Ein simpler Zufallsgenerator für Integer-Werte im gewählten Wertebereich
	// und ein Lambda-Ausdruck, der einen solchen Wert berechnet.
	mt19937 random_generator({ random_device()() });
	uniform_int_distribution<> lottery_distribution(lottery_numbers_range_min,
													lottery_numbers_range_max);
	auto draw_lottery_number = [&random_generator, &lottery_distribution] {
		return lottery_distribution(random_generator);
	};
	
	// Wir fügen solange zufällige Werte hinzu, bis wir die gewollte Anzahl an
	// Werten im std::set lottery_numbers haben. std::set().insert().second ist
	// true, wenn der Wert erfolgreich eingefügt wurde.
	for (size_t draw_count = 0;
		 draw_count < lottery_numbers_to_draw;
		 ++draw_count) {
		while (!lottery_numbers.insert(draw_lottery_number()).second) {
		}
	}
		
	// Gibt die Lottozahlen auf der Konsole aus
	for (auto n: lottery_numbers) {
		cout << n << ' ';
	}
	cout << endl;
}

void lottery_c() {
	// Initialisierung von rand()
	srand((unsigned)time(0));
	
	// Array, in dem die Zahlen gespeichert und dann "In-Place" sortiert werden
	int lottery_numbers[7];
	
	// Berechnet zufällige Werte zwischen aus [1,49], wenn diese noch nicht in
	// lottery_numbers vorhanden sind, werden sie hinzugefügt.
	// Am Ende der Schleife ist garantiert, dass lottery_numbers 7 verschiedene
	// Elemente enthält.
	for (int draw_count = 0; draw_count < 7; ++draw_count) {
		bool already_drawn;
		int drawn_number;
		do {
			already_drawn = false;
			drawn_number = rand() % 49 + 1;
			for (int i = 0; i < 7; ++i) {
				if (lottery_numbers[i] == drawn_number) {
					already_drawn = true;
					break;
				}
			}
		} while (already_drawn == true);
		
		lottery_numbers[draw_count] = drawn_number;
	}
	
	// Sortiert die 7 Werte in lottery_numbers aufsteigend mit einem
	// "In-Place"-Quicksort Verfahren (Implementation siehe unten)
	quicksort_c(lottery_numbers, 7);
	
	// Gibt die Lottozahlen auf der Konsole aus
	for (int i = 0; i < 7; ++i) {
		printf("%d ", lottery_numbers[i]);
	}
	printf("\n");
}

// In-Place-Quicksort, rekursiv
// Funktionsweise: http://en.wikipedia.org/wiki/Quicksort
void quicksort_c(int *data, int count) {
    if (count < 2) {
        return;
	}
	
    int pivot = data[count / 2];
	
    int *left = data;
    int *right = data + count - 1;

    while (left <= right) {
        if (*left < pivot) {
            left++;
            continue;
        }
        
		if (*right > pivot) {
            right--;
            continue;
        }
		
        int temp = *left;
        *left++ = *right;
        *right-- = temp;
    }
	
    quicksort_c(data, (int)(right - data + 1));
    quicksort_c(left, (int)(data + count - left));
}
Ein möglicher Output wäre:
Code:
21 26 27 36 37 43 46 
6 28 32 35 37 42 45
Offensichtlicher Nachteil der C-Variante: Bei größeren Arrays wird es mit Komplexität O(n) langsamer zu überprüfen, ob bereits Werte existieren. Das kann jedoch elegant umgangen werden, wenn man die von snow911 genannte Methode verwendet. Die wird übrigens dann ineffizient, wenn man wenige Elemente aus einer großen Range aussuchen soll. Bestenfalls benutzt man diese also nicht, wenn die Range groß ist, sondern wenn die gesuchte Anzahl an Elementen nicht sehr viel kleiner als die Range ist.

Bei der C++-Variante kann man anstelle des Lambdas auch std::bind benutzen, das mag clang++ aber manchmal nicht (Ist nicht so ganz fehlerfrei im aktuellen Xcode Dev Preview):
Code:
auto draw_lottery_number = std::bind(std::uniform_int_distribution<>{1, 49}, std::mt19937{std::random_device{}()});
Die weitere Optimierung überlässt man dann std::set. Übrigens kann man hier auch anders sortieren, man ist ja nicht an std::less<T> gebunden.
Raz9r is offline  
Thanks
1 User
Old 02/09/2013, 00:18   #8
 
elite*gold: 0
Join Date: Oct 2011
Posts: 322
Received Thanks: 12
hat mir auch weitergeholfen ^^ danke....
Hacker41822 is offline  
Old 02/09/2013, 00:29   #9
 
elite*gold: 0
Join Date: Jan 2011
Posts: 362
Received Thanks: 41
Habe es so gelöst falls es jemanden interessiert
Code:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main (void){
	int lotto[7];
	int i,j,x,temp;
	int a,b,c,zz;
	srand(time(NULL));
	for(i=0;i<7;i++){
		lotto[i]=rand()%49+1;
		for(j=0;j<=i-1;j++){
			if(lotto[j]==lotto[i]){
				j=i;
				i--;
			}
		}
	}
	for(i=0;i<7;i++){
		for(c=0;c<7;c++){
			if(lotto[i]<lotto[c]){
			x=lotto[i];
			lotto[i]=lotto[c];
			lotto[c]=x;
			}
		}
	}
	for(b=0;b<7;b++){
	printf("Zahl %i = %i\n ",b+1,lotto[b]);
	}
	system("PAUSE");
	return 0;
}
Rullx3 is offline  
Old 02/09/2013, 01:31   #10
 
Schlüsselbein's Avatar
 
elite*gold: 0
Join Date: Feb 2013
Posts: 1,137
Received Thanks: 869
Sieht beim Überfliegen gut aus, nur lass das system("PAUSE") weg. Das ist Pfui!
Schlüsselbein is offline  
Old 02/09/2013, 16:53   #11
 
elite*gold: 0
Join Date: Jan 2011
Posts: 362
Received Thanks: 41
Quote:
Originally Posted by Schlüsselbein View Post
Sieht beim Überfliegen gut aus, nur lass das system("PAUSE") weg. Das ist Pfui!
Nein ist es nicht sonst schließt sich die Konsole bei mir immer direkt nach dem öffnen des pause verhindert dies
Rullx3 is offline  
Old 02/09/2013, 17:23   #12
 
Dr. Coxxy's Avatar
 
elite*gold: 0
Join Date: Feb 2011
Posts: 1,206
Received Thanks: 736
Quote:
Originally Posted by Rullx3 View Post
Nein ist es nicht sonst schließt sich die Konsole bei mir immer direkt nach dem öffnen des pause verhindert dies
nope, er meint, dass system("pause"); bzw. allg. system "böse" wäre.
das stimmt zwar zu einem gewissen grad, ist aber vollkommen irrelevant für dieses programm.
Dr. Coxxy is offline  
Old 02/09/2013, 17:35   #13
 
Schlüsselbein's Avatar
 
elite*gold: 0
Join Date: Feb 2013
Posts: 1,137
Received Thanks: 869
Genauso wie es für viele Programme irrelevant ist, Speicher wieder frei zu geben etc. Von der Relevanz abgesehen ist es vorteilhaft, wenn ein Anfänger auch zu Beginn lernt, sauber zu programmieren. Und dazu gehört m.E. kein system("PAUSE").

Quote:
Nein ist es nicht sonst schließt sich die Konsole bei mir immer direkt nach dem öffnen des pause verhindert dies
Je nach IDE kannst du die Konsole auch nach Beendigung des Programms offenthalten. Beim Visual Studio gehts mit STRG+F5.
Schlüsselbein is offline  
Thanks
1 User
Reply




All times are GMT +1. The time now is 22:55.


Powered by vBulletin®
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2026 elitepvpers All Rights Reserved.