Java Zufallszahlen ohne Zurücklegen?

3 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

du hast ein logik fehler

du kannst doch ncihts setzen wenn du noch gar nicht die ganze reihe abgearbeitet hast .

du musst doch alle testen und erst wenn alle tests false ergeben (bzw keiner davon wahr ist) kannst du die neue setzen .

vor die innere FOR schleife packst du ein

bool found = false;

und dann kommt da keine while schleife in der inneren for schleife

sondern nur ein

if (vergleich psotitionen a == b ) {
 found = true ;
}

und nach der inneren for schleife

if (!found) { setze neue zufallszahl ;}

und dann musst du dir noch überlegen was passiert wenn du halt ein doppel gefunden hast , den dann darf die äussere schleife ja nicht hochgezählt werden .

also mit der äusseren solltest du kein FOR nehmen sondern ein WHILE und den Zähler nur weiter setzen wenn halt eine neue zufallszahl auch wirklich gesetzt werden konnte.

dervondaoben28 
Fragesteller
 16.12.2021, 18:13

Danke schonmal für die Tipps. Ich bin gerade dabei es zu überarbeiten.

0
TechPech1984  16.12.2021, 18:13
@dervondaoben28

habs nochmal nachgebessert , du kannst nicht mit einer äusseren FOR schleife arbeiten , lieber mit while

1
dervondaoben28 
Fragesteller
 16.12.2021, 18:46
@TechPech1984

@TechPech1984 bei mir sieht das jetzt so aus:

public void zufall(int von, int bis)
  {
    System.out.println(""); 
    Random zufallszahl = new Random();  
    while()
    { 
      zufallsPosition[a] = zufallszahl.nextInt(bis - von + 1) +von;
      boolean found = false; 
      for(int b = von; b < (von + a) ; b++)
      {
        if(zufallsPosition[a] == zufallsPosition[b])
        { 
          System.out.println("found"); 
          found = true; 
        }
      }
      if(found == true)
      {
        zufallsPosition[a] = zufallszahl.nextInt(bis - von + 1) +von;
      }
      System.out.println(zufallsPosition[a]); 
    }
  }

Ich frage mich jetzt aber noch, was ich dann als Bedingung in die äußere While-Schleife schreiben soll.

0

Also ich würde so an die Sache herangehen:

public class RandomNumber {
    public static void main(String[] args) {
        ArrayList<Integer> randomNumbers = new ArrayList<Integer>();
        for(int i = 0; i<10; i++) {
            int generatedNumber = generateNumber(1,10);
            if(!randomNumbers.contains(generatedNumber)) {
                randomNumbers.add(generatedNumber);
            } else {
                i--;
            }
        }
        System.out.println(randomNumbers);
    }

    public static int generateNumber(int min, int max) {
        Random rand = new Random();
        int randomNum = rand.nextInt((max - min) + 1) + min;

        return randomNum;
    }
}

Du machst nen Loop der 10 mal durchläuft und jedes mal eine neue Random Zahl erstellt. Diese Zahl wird überprüft ob sie in einer Liste von Zahlen enthalten ist. Wenn ja wird der loop "rückgängig" gemacht (weiss nicht genau obs da in Java ne bessere Alternative gibt als den Zähler - 1). Wenn die Zahl einmalig ist, wird sie dem Array hinzugefügt.

TechPech1984  16.12.2021, 18:30

da nimmt man schlicht kein for sondern ein while mit doppelbedinung wenn zähler nicht max oder einer gefunden wiederhole .

0
dervondaoben28 
Fragesteller
 16.12.2021, 18:33

@NoArtFX danke für Deine Hilfe. Ich glaube, dass deine Idee doch um einiges leichter ist als meine. Eine Frage hätte ich noch: wofür steht das "!" zwischen der Klammer auf und "randomNumbers"? Sowas ist mir an dieser Stelle noch nie begegnet.

0
dervondaoben28 
Fragesteller
 16.12.2021, 18:42
@dervondaoben28

Habe das jetzt eingefügt und bei mir steht da "Undeclared Method: contains(...)" und "Undeclared Method: add(...)"

Muss ich noch irgendwas importieren, damit diese Methoden vorhanden sind?

0
TechPech1984  16.12.2021, 18:52
@dervondaoben28

mein tip , übernehme nichts denn du lernst davon nichts, programmieren ist wirklich das selber auf eine lösung kommen egal über welche umwege , ansonsten machste kopie paste, verstehst nicht wie du darauf gekommen bist und damit lernste auch nix .das ist abgucken , so wie wenn du jemand beim fomrel 1 rennen zuguckst, ohne es selber zu machen wirst du halt nicht formel 1 fahrer . ich hab dir doch die lösung schon geschrieben . und du bist ja auch schon fast bei der lösung . warum wirfste alles wech ? jetzt schon aufgeben ... naja .

0
dervondaoben28 
Fragesteller
 16.12.2021, 18:56
@TechPech1984

@TechPech1984 habe keinesfalls aufgegeben, probiere nur deine Variante und die von NoArtFX gleichteitig aus

0
TechPech1984  16.12.2021, 18:49

zu deiner frage mit dem

ne bessere Alternative gibt als den Zähler - 1

ja , mann macht gar keine schrittweite in die for schleife (das geht bei java) und erhöht nur wenn eine zufallszahl hinzegfühgt wurde.

0

ich mach dir mal ein pseudocode damit du da mal die richtigen gedanken bekommst.

also

du willst 10 zufallszahlen erzeugen , die nicht doppelt sein sollen , was ist zu tun

du fängst mit der 1 position (im array 0. position) an , dann

machst du solange eine neue zufallszahl solange die position noch nicht länger als die endposition ist .

wenn du eine zufallszahl den endlich gefunden hast die nicht drinne vorgekommen ist , setzt du die zufallszahl an die stelle erhöhst du den zähler für die stelle

array[10]
pos = 0
/* erzeugung */
while (pos < 10 ) /* solange nicht alle positionen eine zufalls zahl haben  */
{
  zufallgefunden = false;
  zufall = neuerzufall;
  for (i=0 to pos) 
  {
      if (array[i] == zufall)
      {
        zufallgefunden = true;
        break; /* beende for schleife */
      }
  }
  if (!zufallgefunden)  /* also wenn NICHT zufallgefunden , also zufallgefunden false ist und das nicht macht daraus true */
  {
   array[pos] = zufall;
   pos++;
  }
}
/* ausgabe */
for (i=0 to pos)
{
    print array[i];
}

das musst du in java umsetzen

TechPech1984  16.12.2021, 19:19

habs nochmal korrigiert wegen dem

zufallgefunden = false;

das war an der falschen stelle .

1
dervondaoben28 
Fragesteller
 16.12.2021, 20:21
@TechPech1984

Es funktioniert endlich, danke erstmal für Deine Hilfe :-)

Die erste FOR-Schleife durchläuft die bisher mit Zufallszahlen zugewiesenen Indizes.

Wenn an einer Stelle der Wert des Index i gleich dem der vor der FOR-Schleife erzeugten Zufallszahl ist, wird die Boolean-Variable auf "true" gesetzt und die for-Schleife wird abgebrochen. Geht der dann wieder an die Stelle "found = false"(an den Anfang von dem, was in der WHILE-Schleife steht)? Alles andere würde ja keinen Sinn ergeben, da sonst, wenn er ganz an den Anfang zu der WHILE-Schleife gehen würde, die zweite Bedinigung, also "found == true", erfüllt wäre und somit die WHILE-Schleife gar nicht ausgeführt werden würde, obwohl mit einer relativ hohen Wahrscheinlichkeit noch nicht alle Stellen mit den "richtigen" Zufallszahlen gefüllt sind.

Ist "found == false", also wenn die zuvor erstellte Zufallszahl noch nicht in den vorherigen Stellen vorhanden ist, ordnet er diese dem aktuellen Index zu. Anschließend wird die Zählvariable um 1 erhöht, sodass die WHILE-SCHLEIFE a) abbricht oder b) noch mal durchläuft, diesmal mit der nächsten Stelle.

In der unteren FOR-Schleife wird das Array durchlaufen und dabei werden die Werte der jeweiligen Indizes ausgegeben, das ist ja klar.

Ich würde mich freuen, wenn Du mir sagen könntest, ob ich es im Allgemeinen richtig verstanden habe und mir Du mir vielleicht die Funktion des "found = true" in der ersten IF-Schleife erklären/erläutern könntest.

0
TechPech1984  16.12.2021, 20:31
@dervondaoben28

ich geb zu die while schleife ist tricky .

und wo du es gerade erklärst sogar zu tricky :) da hab ich zuviel gedacht .

eigentlich kann das

OR  zufallgefunden

weg . denn es wiederholt sich ja sowieso solange die end position nicht überschritten wurde und pos sich ja auch nur erhöht wenn eine neue zufallszahl gesetzt wurde .

sorry , da wa ich etwas übereifrig :) mein erster gedanke war ganz anders, deswegen hab ich den fehler mitgeschleppt ;)

ich korrigiere das mal .

0
TechPech1984  16.12.2021, 20:34
@dervondaoben28

könntest du nochmal dein aktuellen code posten , dann kommentier ich das in deinem code rein .

0
dervondaoben28 
Fragesteller
 16.12.2021, 20:47
@TechPech1984

Code:

 public void zufall(int von, int bis)
  {
    System.out.println(""); 
    Random zufallszahl = new Random(); 
    boolean found = false;
    int a = von; 
    while(a < bis || found == true)
    {
      found = false; 
      int zufall = zufallszahl.nextInt(bis - von + 1) +von;
      for(int b = von; b < (von + a + 1) ; b++)
      {
        if(zufallsPosition[b] == zufall)
        { 
          found = true;
          break; 
        }
      }
      if(found == false)
      {
        zufallsPosition[a] = zufall; 
        a++; 
      }
    }
    for(int i = von; i < (bis +1); i++)
    {
      System.out.println(zufallsPosition[i]); 
    }
  }

Ja stimmt, es funktioniert auch, wenn man dass "|| found == true" in der Bedingung für die WHILE-Schleife entfernt.

Und nochmal allergrößten Dank Dich, dass Du in Deiner Freizeit anderen Leuten bei ihren Problemen in Informatik hilfst :-)

0
TechPech1984  16.12.2021, 21:04
@dervondaoben28
 public void zufall(int von, int bis)
 {
   System.out.println(""); /* ausgabe nichts */
   Random zufallszahl = new Random(); /* radom generator initialisieren */
   boolean found = false; /* wird benötigt für die findeung von doppelten zufallszahlen */
   int a = von; 
   while(a < bis) /* solange das ende nicht erreicht ist wiederhole */
   {
     found = false; /* startwert setzen , fals der bei doppelten fund auf true gesetzt wurde */
     int zufall = zufallszahl.nextInt(bis - von + 1) +von; /* zufallszahl erzeugen */
     for(int b = von; b < (von + a + 1) ; b++) /* die bisher erzeugen zufallszahlen überprüfen */
     {
       if(zufallsPosition[b] == zufall) /* wenn zufallszahl schon an einer position vorhanden */
       { 
         found = true; /* dann merk dir das */
         break; /* und beende die schleife , ein doppel zu finden reicht */ 
       }
     }
     if(found == false) /* wenn kein doppel gefunden wurde */ 
     {
       zufallsPosition[a] = zufall; /* pack die zufallszahl an aktuelle position */
       a++; /* erhöhe die position */
     }
   }
   for(int i = von; i < (bis +1); i++)
   {
     System.out.println(zufallsPosition[i]); 
   }
 }

reicht dir das ? btw zum lesen ist variable a und b halt echt schlecht gewählt

dann lieber position für a und den standard zähler i für b , denn guten code kann man so lesen ohne nachdenken zu müssen .

1
dervondaoben28 
Fragesteller
 16.12.2021, 21:09
@TechPech1984

Ist so gut verständlich :-)

Danke für den Hinweis, die Variablennamen ändere ich jetzt noch.

1
TechPech1984  16.12.2021, 21:30
@dervondaoben28

du kannst auch noch das

boolean found = false;

einfach runter packen und das

found = false;

damit ersetzen .

bei java geht das ja , da die im block ja eigenständige variablen sind, in anderen sprachen darf man das so nicht machen , da wäre dann der fehler , wurde schon definiert .. :)

0
TechPech1984  16.12.2021, 21:34
@dervondaoben28

allerdings wunder ich mich das du die while schleife

while(a < bis)

machst

und aber unten bei der ausgabe

von <= bis 

machst

da fehlt doch dann eine position

immer daran denken array fangen bei 0 an nicht bei 1 und gehen bei z.b. array[10] halt nur bis 9

1
dervondaoben28 
Fragesteller
 16.12.2021, 21:51
@TechPech1984

Erstmal danke für die weiteren Optimierungstipps.

Verstehe ich auch nicht, funktioniert aber. Würde dir eigentlich gerne einen Screenshot der Ausgabe schicken, in diesem Antwort-Modus kann ich aber leider keine Bilder einfügen.

Wenn man "while(a<=bis)" hinschreibt, dann scheint es so, als ob die Bedingung nie erfüllt werden kann, weil diese "Java Virtual Machine" die ganze Zeit läuft, der Computer also rechnet.

0