10 Zufällige Zahlen, die unterschiedlich sein sollen



  • Hallo Zusammen,
    ich hab mich hier angemeldet, weil ich mich jetzt doch nochmal ans programmieren ranwagen wollte, aber einsehen muss, dass ich doch immer noch schnell an meine Grenzen komme 🙂

    Ich will eigentlich nur (bis zu) 10 zufällige aber unterschiedliche Zahlen haben.
    Dafür lasse ich mir erst eine Zufällige Zahl generieren und weise diese dann einem Array mit 10 Elementen zu..
    Funktioniert auch, aber leider weiß ich dann nicht, wie ich die Elemente sinnvoll miteinander vergleiche...
    Mit meinem begrenzten Kenntnissen würde ich so anfangen:
    if (Nr[1]!=Nr[2]&&Nr[1]!=Nr[3]&&Nr[1]!=Nr[4]....Nr[10]!=Nr[9]) (bzw. natürlich heben sich später welche weg )
    a=1 //wenn das meine Variable wäre, mit der ich prüfe, ob alle Zahlen unterschiedlich sind.

    Deswegen meine Frage an Euch:
    Wie kann ich das ganze Prozedere abkürzen? Mit anderen Befehlen oder ähnliches?
    Vielen Dank für alle Antworten!!



  • Erstelle doch 10 weitere Variablen und jedesmal wenn zu eine Zufallszahl erzeugst,
    speicherst du sie bsp:

    int temp[9];
    int i;
    
    for(i=0;i<=9;i++){
    do{
    Nr[i] = rand() % 100;
    }while((compare(Nr[i]) == 0);
    temp[i] = Nr[i];
    }
    

    dann schreibst du eine Funktion (in dem Fall compare) welche Nr mit allen temps vergleicht, aber vorher solltest du temp noch initialisieren.



  • auch wenns peinlich ist:
    ich komm nicht ganz mit 😃
    ich hab also jetzt mit:

    a= MaxZahlen;

    while (a>0)
    {
    b=rand()%10;//Zufallszahlen generieren
    Zufallszahlen[a]=b;//Zufallszahlen zuweisen
    printf("%d\n",Zufallszahlen[a]);
    a--;
    }
    Also habe ich jetzt MaxZahlen (zb. 5) Zufallszahlen in dem Array Zufallszahlen gespeichert.

    Und in deinem code weist du 9 mal "meiner" Variable Zufallszahlen Werte zwischen 1 und 100 zu vergleichst die dann in der Funktion? Wobei ich nicht genau weiß wie die Funktion aussehen muss, bzw ich was mit was vergleichem muss..



  • So sieht die Funktion in etwa aus:

    int compare(Compare){
    
    for(a=0;a<9;a++){
    
        if(Compare == temp[a]){
        return 0;
        }
    
    }
    
    return 1;
    }
    

    Nimm doch statt einer while, eine for Schleife.
    In meinem Code wird Nr so lange eine Zufallszahl zugewiesen, wie compare 0 zurück gibt. Und compare gibt 0 zurück, wenn die Zufallszahl schon einmal erzeugt wurde.



  • Hör nicht auf C-Fritze, ist zwar nett gemeint, aber in dem Code sind diverse Fehler (u.a. UB).

    Ich denke mal du willst sowas:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define NUMBER_AMOUNT 10
    
    int exists_in_array(int number, int *array, int array_size)
    {
    	int i;
    
    	for (i = 0; i < array_size; ++i)
    	{
    		if (array[i] == number)
    		{
    			return 1;
    		}
    	}
    
    	return 0;
    }
    
    int main()
    {
    	int numbers[NUMBER_AMOUNT];
    	int i;
    	int tmp;
    
    	srand((unsigned int) time(NULL));
    
    	for (i = 0; i < NUMBER_AMOUNT; ++i)
    	{
    		do
    		{
    			tmp = rand() % 100;
    		} while (exists_in_array(tmp, numbers, NUMBER_AMOUNT));
    
    		numbers[i] = tmp;
    	}
    
    	for (i = 0; i < NUMBER_AMOUNT; ++i)
    	{
    		printf("%d\n", numbers[i]);
    	}
    
    	return 0;
    }
    


  • @asdasddsd
    Bis auf den Zeiger ist das doch der gleiche Code, was habe ich den für Fehler gemacht?
    edit: Du hast Recht, ich nehm alles zurück



  • Du musst aber nicht das ganze Feld durchsuchen.
    Der bisher gefüllte Teil reicht aus.



  • Stimmt natürlich ...

    ...
    
    while (exists_in_array(tmp, numbers, i - 1));
    
    ...
    


  • Vielen Dank asdasddsd! Das war mehr, als ich mir erwartet hab und ich hätte es wahrscheinlich auch selbst irgendwann aufgegeben.. 😃
    Danke auch an C-Fritze!


  • Mod

    Es gibt da übrigens noch eine andere Methode, die auch dann noch effizient ist, wenn die Zahl der zu ziehenden Zahlen groß ist oder von der Größenordnung der Grundmenge ist*. Der Nachteil ist etwas größerer Anfangsaufwand, daher greift es nicht ganz so gut in "normalen" Fällen wie 6 aus 49 (ist aber immer noch flott!), dafür ist kein einziger Fall richtig schlecht:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    int draw_unique(int[], unsigned int*);
    
    int main()
    {
      int basic_set[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // Die möglichen Ergebnisse. Hier können alle möglichen Daten stehen!
      unsigned basic_set_size = sizeof(basic_set) / sizeof(*basic_set);
      int i;
    
      srand(time(0));
    
      for(i = 0; i < 7; ++i)
        {
          printf("%d\n", draw_unique(basic_set, &basic_set_size));
        }
    
      return 0;
    }
    
    int draw_unique(int basic_set[], unsigned int* basic_set_size)
    {
      unsigned random_index = rand() % *basic_set_size;
    
      // Vertausche gezogenes und letzte Element:
      int result = basic_set[random_index];
      basic_set[random_index] = basic_set[(*basic_set_size) - 1];
      basic_set[(*basic_set_size)--] = result;  // Veringere außerdem die Zahl möglicher Ereignisse in der Zukunft
    
      return result;
    }
    

    *: Man denke sich folgende Fälle bei dem Code von asdasddsd:
    a) Man möchte 1 Million Zahlen ziehen. Bei den späteren Fällen werden bei jeder Zahl fast eine Million Vergleiche durchgeführt. Lahm!
    b) Man möchte 99 verschiedene Zahlen aus 100 ziehen. Bei der 99ten Zahl muss man so lange neu ziehen, bis man zufällig mal eine der beiden Zahlen trifft, die man bis dahin noch nicht gezogen hat. Lahm!



  • Ich habe das mal ähnlich wie SeppJ beschrieben gemacht, nur mit dem Unterschied, das ich die Zahlen zuerst in einen std::vector gespeichert habe und die zufällig gezogene Zahl dann dort herausgelöscht habe.
    Die von SeppJ vorgestellte Lösung finde ich jedoch viel eleganter, da muss nämlich keinerlei Reallokation von Speicher erfolgen, was das ganze natürlich auch viel effizienter macht. 👍 👍


Log in to reply