Lottozahlen

Blender3D

Top Contributor
Ich finde:
do {
zufall = (int) (Math.random() * MAX) + 1;
} while (lottozahl[zufall] == 1);
Diese Lösung bildet die Wirklichkeit sehr schlecht ab.
Jedenfalls habe ich noch keine Lottoziehung gesehen, wo die gezogene Zahl wieder in den Kessel geworfen wird und bei der nächsten Ziehung geschaut wird ob diese bereits gezogen war.
Das führt zu unnötigen Laufzeiten z.B. 44 aus 45 oder ähnliches braucht für jede Zahl immer länger bis die nächste Zahl gefunden wird.
Also: Lösung wäre die Anzahl der Zufallszahlen nach jeder Ziehung zu reduzieren und das Ergebnis der Nächsten Zahl auf die Zielmenge zu übertragen.
Code:
public class Lotto {
    public static int[] ziehen(int totalNumbers, int drawingQuantity) {
        boolean[] usedNumbers = new boolean[totalNumbers];
        int[] drawnNumbers = new int[drawingQuantity];
        int toDrawQuantity = drawingQuantity;
        Random rnd = new Random(System.currentTimeMillis());
        while (toDrawQuantity != 0) {
            int number = Math.abs(rnd.nextInt()) % (toDrawQuantity) + 1;
            drawnNumbers[drawingQuantity - toDrawQuantity] = getConcretNumber(usedNumbers, number);
            toDrawQuantity--;

        }
        return drawnNumbers;
    }

    private static int getConcretNumber(boolean[] usedNumbers, int number) {
        int nummerNeu = number;
        for (int i = 0; i < usedNumbers.length; i++) {
            if (usedNumbers[i])
                nummerNeu++;
            if (i == nummerNeu - 1)
                break;
        }
        usedNumbers[nummerNeu - 1] = true;
        return nummerNeu;
    }

}
;)
 

Blender3D

Top Contributor
Sorry vorheriger Code stimmt nicht! Hier die Korrektur!:)
Code:
import java.util.Random;

public class Lotto {
    public static int[] ziehen(int totalNumbers, int drawingQuantity) {
        boolean[] usedNumbers = new boolean[totalNumbers];
        int[] drawnNumbers = new int[drawingQuantity];
        int toDrawQuantity = drawingQuantity;
        Random rnd = new Random(System.currentTimeMillis());
        while (toDrawQuantity != 0) {
            int number = Math.abs(rnd.nextInt()) % (totalNumbers) + 1;
            drawnNumbers[drawingQuantity - toDrawQuantity] = getConcretNumber(usedNumbers, number);
            toDrawQuantity--;

        }
        return drawnNumbers;
    }

    private static int getConcretNumber(boolean[] usedNumbers, int number) {
        int nummerNeu = number;
        while (usedNumbers[nummerNeu - 1])
            nummerNeu = (nummerNeu + 1) % usedNumbers.length;
        usedNumbers[nummerNeu - 1] = true;
        return nummerNeu;
    }

}
 

javastudent25

Bekanntes Mitglied
Ich muss gestehen, ich habe mir nicht den ganzen Thread durchgelesen aber wenn ich das richtig verstehe möchtest du ein Array mit Zufallszahlen, dass keine doppelten Einträge enthält.
Wenn du nur mit Arrays arbeiten willst, dann würde sowas klappen:
Java:
    public static void main(String[] args) throws ParseException {
        int[] array = new int[6];
        Random r = new Random();
        int randomNumber;
        for(int i=0; i<array.length; i++){
            do{
                randomNumber = r.nextInt(6) + 1;
            }while(containsValue(array, randomNumber));
            array[i]=randomNumber;
        }
        System.out.println(Arrays.toString(array));
    }
 
    private static boolean containsValue(int[] array, int value){
        for(int i=0; i<array.length; i++){
            if(array[i]==value){
                return true;
            }
        }
        return false;
    }


Ansonsten wäre für die Aufgabe ein Set ganz nützlich, weil es keine doppelten Elemente enthalten kann, aber das hat vermutlich schon jemand vorgeschlagen:
Java:
        Set<Integer> set = new TreeSet<>();
        Random r = new Random();
        do {
            set.add(r.nextInt(42) + 1);
        } while (set.size() != 6);
        System.out.println(set.toString());

#Edit: Wobei ich gerade sehe, dass unter anderem kneitzel schon Code gepostet hat, der genau das macht. Vllt. hab ich dein Problem dann falsch verstanden ;;o

Hallo Tarrew

Vielen Dank für deinen Beitrag, der hat endlich geholfen.. :)
Die Beiträge von kneitzel finde, ich was meine Kenntnisse angeht auch immer sehr hilfreich und kann meistens damit auch etwas anfangen.
Aber den Code von kneitzel habe ich in diesem Fall irgendwie überlesen und finde ihn immer noch nicht.

Wie ich sehe, gab es schon einige Kommentare. Ich finds schön, wenn es Diskussionen gibt, da kann man dann nur lernen von den Experten ;), aber nur solange, wenn die Leute sich hier nicht gegenseitig fertig machen.

Ich muss auch ehrlich gestehen, dass ich auf Codes wie HashSet oder Set, Lists etc. nicht eingegangen bin, da ja damit nicht direkt mein Problem gelöst ist.
Ich würde zwar schneller am Ziel sein, aber verstanden hätte ich Nichts.
Was das Programmieren angeht sind hier offensichtlich ein paar viele Einsteins.
Nur um deren Lösungen zu verstehen, müsste ich mich zuerst auf deren Niveau befinden.
Ich würde mich gerne mit der Thematik java viel mehr beschäftigen, aber leider fehlt mir einfach die Zeit dafür.

Deshalb sind mir Lösungen wie du, kneitzel und paar andere sie präsentiersen oder erklären meisten am Liebsten.
Denn so habe ich nicht nur das Problem gelöst, sonder auch verstanden..
Vor allem das mit der While-Schleifen-Bedingung..

Dann kann ich mich jetzt mal, um den nächsten Step kümmern ;)

Java:
import java.io.*;
import java.text.*;
import java.util.*;
import java.lang.String;

public class Lottozahlen {

    public static void main(String[] args) {
      
        Lotto lotto = new Lotto();
        lotto.getGesamtArray();
    }
}


Java:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;

public class Lotto {
   
    private int[] zufallsZahlen = new int[6];
    private int[] gluecksZahl = new int[1];
    private int[] array = new int[zufallsZahlen.length + gluecksZahl.length];

    private void zahlenAusgeben() {
       
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + " ");
        }
    }
   
    private void erzeugeZahlenArray() {
       
           Random rand = new Random();
           int randomNumber;
           for(int i=0; i<zufallsZahlen.length; i++){
               do{
                   randomNumber = rand.nextInt(42) + 1;
               }while(containsValue(zufallsZahlen, randomNumber));
               zufallsZahlen[i]=randomNumber;
           }       
    }
   
    private void erzeugeGlueckszahl() {

        Random random = new Random();
        int zufall = random.nextInt(6) + 1;
        gluecksZahl[0] = zufall;

    }
   
    public void getGesamtArray(){
       
        erzeugeZahlenArray();
        Arrays.sort(zufallsZahlen);
        erzeugeGlueckszahl();
       
        for(int i=0;i<zufallsZahlen.length;i++){
           array[i]=zufallsZahlen[i];
        }
        for(int i=0;i<gluecksZahl.length;i++){
           array[zufallsZahlen.length+i]=gluecksZahl[i];
        }
        zahlenAusgeben();
       
       
    }
   
    private boolean containsValue(int[] array, int value){
           for(int i=0; i<array.length; i++){
               if(array[i]==value){
                   return true;
               }
           }
           return false;
    } 
}
 

Blender3D

Top Contributor
Code:
import java.util.Random;

public class Lotto {
    public static int[] ziehen(int totalNumbers, int drawingQuantity) {
        boolean[] usedNumbers = new boolean[totalNumbers];
        int[] drawnNumbers = new int[drawingQuantity];
        int toDrawQuantity = drawingQuantity;
        Random rnd = new Random(System.currentTimeMillis());
        while (toDrawQuantity != 0) {
            int number = Math.abs(rnd.nextInt()) % (totalNumbers);
            drawnNumbers[drawingQuantity - toDrawQuantity] = getConcretNumber(usedNumbers, number);
            toDrawQuantity--;

        }
        return drawnNumbers;
    }

    private static int getConcretNumber(boolean[] usedNumbers, int number) {
        int nummerNeu = number;
        while (usedNumbers[nummerNeu])
            nummerNeu = (nummerNeu + 1) % (usedNumbers.length);
        usedNumbers[nummerNeu] = true;
        return nummerNeu + 1;
    }

}
Noch ein Fehler aber jetzt läuft es!
Laufzeit z.B 45 aus 45 ist konstant! 45 * 45/2
 

javastudent25

Bekanntes Mitglied
Code:
import java.util.Random;

public class Lotto {
    public static int[] ziehen(int totalNumbers, int drawingQuantity) {
        boolean[] usedNumbers = new boolean[totalNumbers];
        int[] drawnNumbers = new int[drawingQuantity];
        int toDrawQuantity = drawingQuantity;
        Random rnd = new Random(System.currentTimeMillis());
        while (toDrawQuantity != 0) {
            int number = Math.abs(rnd.nextInt()) % (totalNumbers);
            drawnNumbers[drawingQuantity - toDrawQuantity] = getConcretNumber(usedNumbers, number);
            toDrawQuantity--;

        }
        return drawnNumbers;
    }

    private static int getConcretNumber(boolean[] usedNumbers, int number) {
        int nummerNeu = number;
        while (usedNumbers[nummerNeu])
            nummerNeu = (nummerNeu + 1) % (usedNumbers.length);
        usedNumbers[nummerNeu] = true;
        return nummerNeu + 1;
    }

}
Noch ein Fehler aber jetzt läuft es!
Laufzeit z.B 45 aus 45 ist konstant! 45 * 45/2

Blender, bist du dir jetzt wirklich sicher? :D
 

Blender3D

Top Contributor
Code:
    public static void main(String[] args) {   
        int []z = Lotto.ziehen(45, 45);
        Arrays.sort(z);
        for( int i:z )
            System.out.print(i+ "\t");
    }
Teste mal so ! :)
 
X

Xyz1

Gast
Das ist ja ein Durcheinander. Du nimmst einfach die nächsthöhere, die nicht besetzt ist, Zahl.

Ich hingegen nehme einfach eine Liste, mische sie, nehme zwei Listen und schiebe in die 2. 6 - oder halt eine Set, Vorkommen zählen.

Wer will, kann ja alle Möglichkeiten einmal aufschreiben, und sich profilieren.

Oder ich nehme eine Trommel, befülle sie mit 49 Kugeln und drehe ein paar Mal, das nennt sich auch Zufall. :D
 

Flown

Administrator
Mitarbeiter
Warum versucht ihr alle einen simplen Algorithmus mit Mikro-Optimierungen zu verbessern?
Regel für Software Engineers: Readability > (Micro-)Optimization

@Blender3D Dein Algorithmus hat trotz allem eine Laufzeitkomplexität von O(n²)
 

Tarrew

Top Contributor
Und ihr werft mir Spagetticode vor, wenn ich das schon sehe *kotz*
Allein das neue Random Objekt ist unnötig.
Genau wie do while usw.
Math.random() ist bereits ein Singleton (über statische innere Klassen Fabrik)
do while ist ein Schlüsselwort mehr, unleserlich und langsam

Muss ich dazu noch mehr schreiben? An meinem Text hätte er noch was
lernen können.

Ein Random Objekt hat Vorteile gegenüber Math.random(). Das kannst du auch hier nochmal nachlesen:
http://stackoverflow.com/questions/738629/math-random-versus-random-nextintint

Warum dein restlicher Code eher schlecht ist, hat kneitzel ja schon ausführlich erläutert.
 
Zuletzt bearbeitet:

Tarrew

Top Contributor
Auf der Stackoverflow Seite kann ich auch keinen Beitrag von dir erkennen, weil durchgehend die Meinung herrscht dass Random.nextInt() besser ist als Math.random(). Laut deiner Aussage ist Math.random() ja viel besser ;)
 
Zuletzt bearbeitet von einem Moderator:

InfectedBytes

Top Contributor
Ist ja ok, wir haben alle gemerkt das du dich für allwissend hältst, aber tut mir leid dich enttäuschen zu müssen, das bist bei weitem nicht. Sieht man ja allein schon an deinem tollen code hier:
Java:
a: while (true) {
  // for...
  break a;
}
Eine endlosschleife per label break immer nach dem ersten durchlauf abbrechen...echt genial xD

Bezüglich dieses Beitrags wurde zudem schon mehrfach geschrieben das bereits alles erledigt ist. Aber du willst ja immer das letzte Wort haben...lass es doch einfach sein, das Thema ist schon längst beendet.
 
Zuletzt bearbeitet von einem Moderator:
X

Xyz1

Gast
Nö, erst unberechtigt Spaghetti vorwerfen und dann noch schlechteren Code posten, was soll daran erledigt sein, sehe ich hier eine Auflistung aller Möglichkeiten.
 
Zuletzt bearbeitet von einem Moderator:

Saheeda

Top Contributor
Könnt ihr nicht bitte damit aufhören? Ihr habt halt verschiedene Ansichten, was guter und was schlechter Code ist. Jeder hat seine Meinung dazu dargelegt, alles Weitere endet doch nur in einer Schlammschlacht.

Am Ende wird noch der Thread geschloßen, was dem TE am allerwenigsten hilft.
 
K

kneitzel

Gast
Also dem TE wurde schon geholfen und der Thread wurde von mind. 2 Anderen mit ähnlichem Anliegen 'gehijackt'.

Unterschiedliche Meinungen kann man haben aber gewisse Dinge sind einfach lachhaft! Und das Auftreten ist auch schon sehr interessant...

Ebenso wurde sachlich nicht auf meine Quellen geantwortet. Angeblich vertrete ich 40 Jahre alte Thesen ... Das Buch muss er ja nicht kennen aber clean-code-developer.de hätte er ja mal ansehen können ... Aber nein, das sind bestimmt auch nur Deppen wie wir, die keine Ahnung haben ...

Sorry, das musste leider raus.
 
X

Xyz1

Gast
Ich lese nicht nach, wie etwas funktioniert, ich schreibe es anderen zum nachlesen auf, wie etwas funktioniert. Hoffentlich erkennst du den Unterschied. :D

Aber ich will mal nicht so gemein sein, siehe dir doch api quelltext an, wenn du wissen möchtest, wie man aktuell und sauber etwas schreibt.
 
K

kneitzel

Gast
Und dann ist die Frage: Sollen falsche Behauptungen einfach so im Raum stehen bleiben?

Angeblich handelt es sich bei dem folgenden Code nicht um Spagetti Code:
Code:
int[] intArr =newint[6];// 6 bitte nicht ändern :-)
        a:while(true){
           for(int i =0; i < intArr.length; i++){
                intArr[i]=(int) func1(1, 49);
           }
           for(int i =0; i < intArr.length-1; i++){
               for(int j = i +1; j < intArr.length; j++){
                   if(intArr[i]== intArr[j]){
                       continue a;
                   }
               }
           }
           break a;
       }
       System.out.println(Arrays.toString(intArr));

Jetzt müssen wir uns einfach einmal fragen, was denn bitteschön Spagetticode ist. Dies mag manch einer einfach als "Nutzung von Goto Befehlen" oder so ansehen. Dies ist aber eine Definition, die so nicht haltbar ist. Also schauen wir doch einfach einmal auf Wikipedia - da wird sich dann ja schon eine Definition finden lassen: https://de.wikipedia.org/wiki/Spaghetticode
"Spaghetticode ist ein abwertender Begriff für Software-Quellcode, der verworrene Kontrollstrukturen aufweist."
Ok, jetzt müsste man klären, was verworrene Kontrollstrukturen sind. Aber Wikipedia führt das ja noch etwas weiter aus:
"Ein Indiz dafür kann etwa die übermäßige Verwendung von Sprunganweisungen (wie GOTO) sein, wobei übermäßig bedeutet: Zum gleichen Ziel könnte man auch mit weniger Sprüngen gelangen."

Schauen wir uns doch einfach einmal an, was da so an Code vorliegt:
Wir haben mehrere verschachtelte Schleifen. Bei der äußeren Schleife fällt auf, dass die while Schleife eigentlich keine wirkliche Whileschleife ist. Dies ist eigentlich nur ein Konstrukt, um zwei Punkt anspringen zu können. Der Code entspricht von der Funktion her dem folgenden (nicht java code):
Code:
int[] intArr =newint[6];// 6 bitte nicht ändern :-)
        a:
           for(int i =0; i < intArr.length; i++){
                intArr[i]=(int) func1(1, 49);
           }
           for(int i =0; i < intArr.length-1; i++){
               for(int j = i +1; j < intArr.length; j++){
                   if(intArr[i]== intArr[j]){
                       goto a;
                   }
               }
           }

       System.out.println(Arrays.toString(intArr));

Und damit wird eigentlich deutlich, dass hier ein Kontrollkonstrukt gebaut wurde, welches ich schon als Spagetticode bezeichnen würde. Die Kollstrukturen sind auf jeden Fall verworren in meinen Augen. Aber ok, jedem seine Meinung.

Aber der Wikipedia-Beitrag zu Spagetticode hat ein paar nette Links. So z.B. zur McCabe Metrik. Eine niedrige Metrik wird als wünschenswert angesehen. Hier könnte man dann über diese Metrik die Codes vergleichen. Einmal so eine dreifache Staffelung von Schleifen mit einem if entgegen einfachen Schleifen mit einem Funktionsaufruf.

Das einfach einmal zur Erläuterung, wieso ich diese tödliche Beleidigung gegenüber dem Sourcecode ausgesprochen habe.
 
X

Xyz1

Gast
Ich hab ja von Tarrew auch schon TreeSet gesehen - wegen der Umordnung usw. noch langsamer und schlimmer als HashSet.

Ich sollte echt mal den ganzen Thread von hinten nach vorne lesen, wenn ich mich amüsieren und/oder wen kritisieren möchte. :D
 

javastudent25

Bekanntes Mitglied
Ich lese nicht nach, wie etwas funktioniert, ich schreibe es anderen zum nachlesen auf, wie etwas funktioniert. Hoffentlich erkennst du den Unterschied. :D

Aber ich will mal nicht so gemein sein, siehe dir doch api quelltext an, wenn du wissen möchtest, wie man aktuell und sauber etwas schreibt.

Gut, wenn du bezüglich Java nichts mehr zu lernen hast und so perfekt bist, dann kannst du dich an die Orthographie machen...
zum Nachlesen schreibt man gross, Quelltext und Anderen auch..
Demnach solltest du Anderen besser nichts zum Nachlesen aufschreiben...
 
X

Xyz1

Gast
anderen schreibt man klein, aber egal.

Edit: Ich weiß nicht wieso, aber dann halt noch eine Version nach kneitzel:
Java:
    private static int[] aus49() {
        int[] irgendwas1 = new int[49]; // fuer Test
        for (int i = 0; i < irgendwas1.length;) {
            irgendwas1[i] = (int) (Math.random()*49.0)+1;
            for (int j = 0; j < i; j++) {
                if (irgendwas1[i] == irgendwas1[j]) {
                    i--;
                }
            }
            i++;
        }
        Arrays.sort(irgendwas1);
        System.out.println(Arrays.toString(irgendwas1)); // fuer Test
        return irgendwas1;
    }

Hier gefallen mir jetzt mehrere Dinge nicht, das Dekrementieren z. B. Aber ich soll ja nicht irgendwelche Sprünge einfügen.

Hat jemand Lust auf die Invariante aufzuschreiben=?
 
Zuletzt bearbeitet von einem Moderator:

Meniskusschaden

Top Contributor
Java:
private static int[] aus49() {
        int[] irgendwas1 = new int[49]; // fuer Test
        for (int i = 0; i < irgendwas1.length;) {
            irgendwas1[i] = (int) (Math.random()*49.0)+1;
            for (int j = 0; j < i; j++) {
                if (irgendwas1[i] == irgendwas1[j]) {
                    i--;
                }
            }
            i++;
        }
        Arrays.sort(irgendwas1);
        System.out.println(Arrays.toString(irgendwas1)); // fuer Test
        return irgendwas1;
    }

Was soll das denn jetzt zeigen? Das liefert doch nur ein Array mit den Zahlen 1 bis 49. Dann kann man das doch auch gleich ganz normal machen:
Java:
    private static int[] aus49() {
        int[] irgendwas1 = new int[49];
        for (int i = 0; i < irgendwas1.length; i++) {
            irgendwas1[i] = i+1;
        }
        System.out.println(Arrays.toString(irgendwas1));
        return irgendwas1;
    }
 

Flown

Administrator
Mitarbeiter
Wenn man eine Diskussion führt, dann bitte folgende Reihenfolge:
- These aufstellen
- Fakten darlegen (mit Referenzen)
- Argumentieren

Wenn jetzt von irgendeiner Seite nocheinmal beleidigt oder angestachelt wird, dann wars das mit diesem Thema!
 

Flown

Administrator
Mitarbeiter
Meine Damen und Herren, um jetzt mal ein offizielles Ranking der "besten" Lösungen zu geben, habe ich mal alle Snippets die hier gepostet wurden in einen Benchmark geworfen.
"Beste" Lösung heißt: Schnellster Methodendurchlauf (gegeben in Nanosekunden(ns)).

Benutzt wurde JMH mit folgenden Parameter:
- Warmup: 5 Iterationen
- Gemessen: 3 Forks zu je 10 Iterationen
- Random mit seed um gleiche Randomwerte zu erzielen

So sieht mal der Benchmarkcode aus:
Java:
/*
* Copyright (c) 2014, Oracle America, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Oracle nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

package test;

import java.util.Arrays;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;

@Fork(3)
@BenchmarkMode(Mode.AverageTime)
@Measurement(iterations = 10, timeUnit = TimeUnit.NANOSECONDS)
@State(Scope.Benchmark)
@Threads(1)
@Warmup(iterations = 5, timeUnit = TimeUnit.NANOSECONDS)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class MyBenchmark {

  public Random random;

  @Setup(Level.Iteration)
  public void setup() {
    random = new Random(10);
  }

  @Benchmark
  public int[] lottoStrammerMax93() {
    int[] zahlen = new int[49];
    for (int i = 0; i < 49; i++) {
      zahlen[i] = i + 1;
    }
    int h, z;
    for (int i = 0; i < 6; i++) {
      z = random.nextInt(49 - i);
      h = zahlen[z];
      zahlen[z] = zahlen[48 - i];
      zahlen[48 - i] = h;
    }
    return Arrays.copyOfRange(zahlen, 43, 49);
  }

  @Benchmark
  public int[] lottoVoid_Nutzer16() {
    int[] lottozahlen = new int[6];
    meinLabel: for (int i = 0; i < lottozahlen.length;) {
      int zwischenspeicher = random.nextInt(49) + 1;
      for (int k = 0; k < i; k++) {
        if (zwischenspeicher == lottozahlen[k]) {
          continue meinLabel;
        }
      }
      lottozahlen[i++] = zwischenspeicher;
    }
  
    return lottozahlen;
  }

  @Benchmark
  public int[] lottoThecain() {
    return random.ints(1, 50).distinct().limit(6).toArray();
  }

  @Benchmark
  public int[] lottoThorwine() {
    boolean[] gezogeneLottozahlen = new boolean[49];
    int[] result = new int[6];
    int zufallszahl = 0;
    for (int count = 0; count < 6; count++) {
      do {
        zufallszahl = random.nextInt(49);
      } while (gezogeneLottozahlen[zufallszahl]);
      gezogeneLottozahlen[zufallszahl] = true;
      result[count] = zufallszahl + 1;
    }
    return result;
  }

  @Benchmark
  public int[] lottoDerWissende() {
    int[] intArr = new int[6];
    a: while (true) {
      for (int i = 0; i < intArr.length; i++) {
        intArr[i] = random.nextInt(49) + 1;
      }
      for (int i = 0; i < intArr.length - 1; i++) {
        for (int j = i + 1; j < intArr.length; j++) {
          if (intArr[i] == intArr[j]) {
            continue a;
          }
        }
      }
      break a;
    }
    return intArr;
  }

  @Benchmark
  public int[] lottoTarrew() {
    Set<Integer> set = new TreeSet<>();
    do {
      set.add(random.nextInt(49) + 1);
    } while (set.size() != 6);
    int[] result = new int[set.size()];
    int i = 0;
    for (int s : set) {
      result[i++] = s;
    }
    return result;
  }

  @Benchmark
  public int[] lottoBlender3D() {
    boolean[] usedNumbers = new boolean[49];
    int[] drawnNumbers = new int[6];
    int toDrawQuantity = 0;
    while (toDrawQuantity < 6) {
      int number = random.nextInt(49);
    
      int nummerNeu = number;
      while (usedNumbers[nummerNeu]) {
        nummerNeu = (nummerNeu + 1) % usedNumbers.length;
      }
      usedNumbers[nummerNeu] = true;
    
      drawnNumbers[toDrawQuantity++] = nummerNeu + 1;
    }
    return drawnNumbers;
  }

}
Hier das Ergebnis:
Code:
# Run complete. Total time: 00:05:20

Benchmark                       Mode  Cnt    Score   Error  Units
MyBenchmark.lottoBlender3D      avgt   30   67,545 ± 0,548  ns/op
MyBenchmark.lottoDerWissende    avgt   30   93,476 ± 0,643  ns/op
MyBenchmark.lottoStrammerMax93  avgt   30   99,237 ± 0,918  ns/op
MyBenchmark.lottoTarrew         avgt   30  210,011 ± 1,866  ns/op
MyBenchmark.lottoThecain        avgt   30  326,354 ± 4,371  ns/op
MyBenchmark.lottoThorwine       avgt   30   70,558 ± 0,676  ns/op
MyBenchmark.lottoVoid_Nutzer16  avgt   30   66,025 ± 0,322  ns/op

Gewinner: void_nutzer16

Warum? Weil der Algorithmus fast linear läuft. Warum? Weil es wenig Kollisionen gibt und somit die Iterationen wenig bis nie wiederholt werden müssen (selbe gilt für die Lösung von Blender3D).
Fakt ist, dass beide quadratische Laufzeitkomplexität aufweisen O(n²).

Welche Lösung würde ich nehmen? Auf jedenfall den Einzeiler von thecain. Warum? Weil es für Normalsterbliche keinen Unterschied macht, ob man 66ns oder 300ns wartet. Beide Ergebnisse werden instant zurückgeliefert und die Intention ist auf den ersten Blick ersichtlich.
 
K

kneitzel

Gast
@DerWissende: Ich verstehe Deine Argumentation nicht. Ich habe klar begründet, wieso ich Deinen Code als Spagetti Code bezeichnet habe. Ich habe sogar extra die Definition von Spagetti Code dargelegt, damit es keine Probleme gibt mit unterschiedlichen Definitionen.

Die Verwendung von Sprunganweisungen sind nur ein Indiz. Das ist nichts Zwingendes. (Indiz: "Unter einem Indiz (von lat.: indicare „anzeigen“) wird im Prozessrecht ein Hinweis verstanden, der für sich allein oder in einer Gesamtheit mit anderen Indizien den Rückschluss auf das Vorliegen einer Tatsache zulässt. Im Allgemeinen ist ein Indiz mehr als eine Behauptung, aber weniger als ein Beweis." - Wikipedia).

Die Definition sagte ganz klar aus, dass es um verworrene Kontrollstrukturen geht. In diesem Zusammenhang habe ich auf die McCabe Metrik hingewiesen. Diese Punkte scheinst Du zu ignorieren und komplett auszublenden.

Vor dieser Antwort habe ich Dich auch schon auf http://clean-code-developer.de und KISS hingewiesen. Darauf bist Du auch in keiner Weise eingegangen.

Ich habe kein Verständnis, wenn jemand in einer Diskussion um ein generelles Thema, das Thema ignoriert und meint in einzelnen Punkten auf Beispielen herum zu reiten. Das ist vergleich mit einer Diskussion bezüglich "Du darfst nicht töten". Da wird dann auf diversen Ebenen argumentiert (z.B. Kants kategorischer Imerativ, Strafgesetz u.s.w.) und eben auch ein Beispiel gebracht, dass es eben nicht ok ist, wenn jemand einen anderen mit einer Pistole erschießt. Deine Argumentation ist jetzt: Ach was - töten ist doch in Ordnung. Wenn ich keine Pistole nehmen darf, dann nehme ich halt einen Revolver. Sorry, es wurden einige Argumente gebracht, auf die Du nicht eingehst.

Und das tolle bei der Softwareentwicklung bezüglich Clean Code ist, dass man sich viele kleine Regeln aufstellen kann. Eine ganz einfache Regel könnte z.B. sein, dass man in einer for Schleife die Variable der Schleife nicht zusätzlich verändert. (Und wenn man meint, dass sowas notwendig ist, statt einer For-Schleife eine While-Schleife verwendet. Dies hätte dann den Vorteil, dass man Code schneller einschätzen kann. Aber solche einfachen Regeln sind einfache Gebote, die teilweise willkürlich festgelegt werden. Diese sind in etwa Vergleichbar mit Regeln des Straßenverkehrs. Ob man nun rechts oder links fährt ist egal - wichtig ist, dass man eine Regel aufstellt und alle sich daran halten. Das führt dann oft auch zu Folgeerscheinungen wie z.B. das Lenkrad kommt dann auf die linke Seite.

Aber an dem Beispiel wird evtl. deutlich, dass man gerne andere Regeln aufstellen kann. Aber es wird (hoffentlich) niemand bezweifeln, dass es solcher Regeln bedarf, um die Anforderungen zu erfüllen. Im Beispiel mit dem Straßenverkehr ist die Anforderung hat, dass eine hohe Anzahl Verkehrsteilnehmer mit teilweise hoher Geschwindigkeit auf begrenztem Raum unterwegs sein sollen und die Anzahl der Unfälle minimiert werden soll.
So übergeordnete Ziele gibt es auch in der Software-Entwicklung. So soll Code wartbar sein, arm an Fehlern / fehlerfrei, zügig erstellt worden sein, ....

Und die reine Code Entwicklung ist dabei auch nur ein kleiner Teil. Ein weiterer Bereich ist die Analyse und das Design. Es ist toll, wenn Du von Dortmund nach Hamburg fahren willst und Du auch ganz schnell unterwegs sein willst um ganz schnell in Hamburg zu sein. Aber bei jedem Autobahnkreuz fährst Du ab und fährst erst auf die Autobahn, auf der Du weiter musst, wenn da auch gerade ein rotes Auto kommt. Beim zweiten Kreuz muss es ein rotes Mittelklasse-Auto sein. Beim dritten ein rotes Mercedes C-Klasse Auto. Wenn Du es bis zum vierten Kreuz schaffen solltest: da muss es natürlich ein roter Mercedes C-Klasse mit Münchener Kennzeichen sein!
Und weil es so toll ist: Jede zweite Ausfahrt fährst Du ab und in die Gegenrichtung wieder auf um dann bei der nächsten Ausfahrt zu wieder zu wenden um dann dieses Spiel wieder fortzusetzen. (Natürlich stellst Du sicher, dass nur Ausfahrten zählen, bei denen Du auch wenden kannst!)

Ja, mit diesen Regeln kommst Du zum Ziel. Als Beweis führst Du an, dass es auch mehrere rote Mercedes C-Klasse mit Münchener Nummernschild gibt und davon einige auch genau auf diesen Autobahnen von Zeit zu Zeit unterwegs sind. Und als Test: Du bist so schon mehrfach von Dortmund nach Hamburg gefahren.

Ja sehr gut. Super! Aber Du wolltest eigentlich nur von Dortmund nach Hamburg, dies relativ zügig, wolltest wenig Sprit verbrauchen u.s.w. Viele tolle Ziele. Aber als Vorschlag kommt dann so ein Vorgehen? Und wenn jemand sagt, dass dies nicht gut ist und mit Deinen Zielen nicht vereinbar: Ok, dann optimierst Du - Du hälst bei den Autobahnkreuzen und wartest auf das Erscheinen eines der gesuchten Fahrzeuge. Ahh ja. Interessant. Aber was soll man da noch argumentieren?

Argumente sind eigentlich alle genannt. Fakten liegen auf dem Tisch. Im Vergleich mit der Fahrt von Dortmund nach Hamburg liegen schon mehrere Fahrtrouten vor. Ok, manch einer holt sich im Kaufhaus in München erst noch einen Kühlschrank, weil er meint, dass der Laden dort toll ist, aber ok: Es gibt viele Fahrtrouten, die man betrachten kann. Die kann man vergleichen. Man kann Dinge kontrollieren wie Strecke, voraussichtlich benötigte Zeit, Funktionsfähigkeit (der 40t mit 3m Höhe wird evtl. nicht jede Strecke fahren können) und auch wie gut der Weg gefunden werden kann. Und es mag auch gute Argumente dafür geben, dass Du jede zweite Ausfahrt wendest um eine Ausfahrt zurück zu fahren: So kannst Du die Landschaft richtig gut betrachten! Aber wenn Du im professionellen Transportbereich tätig sein willst, dann wiegen die anderen Gründe doch deutlich höher.

Bezüglich Deines neuen Codes: Dazu gab es ja schon einen ersten Hinweis. Und wenn man die McCabe Metrik bedenkt: Evtl. findest Du ja auch bessere Lösungen :)

Soviel einfach einmal von meiner Seite aus zu dieser Diskussion. Ab jetzt werde ich mich nur noch darauf beschränken, falsche Fakten zu korrigieren.
 
Zuletzt bearbeitet von einem Moderator:
X

Xyz1

Gast
Danke für die Müh des Tests. Aber fair bleiben, und hiermit testen
(war die neuste Version von mir, angepasst an das random Objekt):
Java:
    public int[] lottoDerWissende() {
        int[] irgendwas1 = new int[6];
        for (int i = 0; i < irgendwas1.length;) {
            irgendwas1[i] = random.nextInt(49) + 1;
            for (int j = 0; j < i; j++) {
                if (irgendwas1[i] == irgendwas1[j]) {
                    i--;
                }
            }
            i++;
        }
        return irgendwas1;
    }

(Ohne Labels)

oder:
Java:
    public int[] lottoDerWissende() {
        int[] irgendwas1 = new int[6];
        a: for (int i = 0; i < irgendwas1.length;) {
            irgendwas1[i] = random.nextInt(49) + 1;
            for (int j = 0; j < i; j++) {
                if (irgendwas1[i] == irgendwas1[j]) {
                    continue a;
                }
            }
            i++;
        }
        return irgendwas1;
    }

(Mit diesem gefährlichen Label, Ohne Zwischenvariable)

Das führt dann dazu, dass
1. genau so schnell wie lottoVoid_Nutzer16 und
2. ungefähr genau so schnell bis etwas schneller als lottoVoid_Nutzer16.

Aber ihr müsst mir nicht huldigen.

@ kneitzel : TL;DR
 
X

Xyz1

Gast
Es wurde die Version von dir getestet auf die du so stolz warst

Es wurde (vorher) nichts von Mikrooptimierung oder Mikrobenchmark gesagt! Ich hatte zwei Versionen. Ich muss jetzt bewusst davon ausgehen, dass damit bewusst nicht getestet werden sollte.

@Flown: Ist schon okay, die echten Laufzeiten sind ungefähr gleich. Ich brauchte halt keine Zwischenvariable.
 
K

kneitzel

Gast
Also die Tests der Laufzeit sind recht nett und danke, dass Du Dir diese Arbeit gemacht hast.

Aber da kommen wir jetzt schnell zu einem Punkt, bei dem wir in eine Sackgasse rennen. Denn viele Streitereien gingen ja eben um den Punkt "Clean Code". Aber ehe ich hier wieder Zeit verschwende und lange Texte schreibe, gebe ich jetzt einfach nur einen Link weiter:
http://clean-code-developer.de/die-grade/roter-grad/#Vorsicht_vor_Optimierungen
 

Flown

Administrator
Mitarbeiter
Dieses Thema im Allgemeinen ist sehr unsinnig. Viele Leute hier reden von verschiedenen Sachen.
- Die einen reden von (Mikro-)Optimierungen (schneller, weniger Zeilen/Variablen, etc.)
- Die anderen reden von Clean-Code (Gliederung, Struktur, etc.)

Grundsätzlich sollte man Clean-Code als Richtlinie sehen und nicht als Gesetz, denn keiner kann von Anfang an perfekt Programmieren und Algorithmen perfekt strukturieren und abbilden. Das kommt alles mit der Zeit und Erfahrung -> haben alle selbst katastrophalen Code geschrieben, wo es einem gruselt!

Bitte bedenkt alle - ich wiederhole mich: Jeder der hier um Hilfe bittet ist meist kein Profi und es sind auch keine "schweren" Fragen für Fortgeschrittene+. Darum sollte man Hilfestellung geben, Verbesserungsvorschläge erbringen (am besten mit Links von Referenzen/Fakten - eben fundiert) und auch noch eine Erklärung hierzu abgeben, warum das in diesem Fall besser wäre. Hier kann man auch gerne Clean-Code ins Spiel bringen, um bei der Entwicklung des Programmierstils zu helfen.

Jeder Entwickler hat einen persönlichen Stil und bevorzugt gewisse Muster. Das soll heißen: Lasst andere Meinungen gelten und könnt gerne darüber diskutieren, aber immer mit einem gewissen Respekt.
 
Bei so einem Beispiel über Perfomace zu reden ist Unsinn. Wenn man mal die Lotto-App schreibt mit 1 Mio. Aufrufe pro Stunde, wird auch die Stelle mit der Gernerierung die kleinste Problem sein.

Ansonsten hat es hier im Anfängerbereich solche Lösungen mit Labels zu posten, den gleichen Charme als würde ein Architekturstudent im 5. Semester in den Legostore gehen um den Kids mal zu zeigen, wie man aus den Duplosteinen einen Turm richtig baut.
 
K

kneitzel

Gast
@Flown: Aber ich denke, dass Du es auch als sinnvoll ansiehst, wenn man Anfänger dort hin führt. Das läuft ja auch eigentlich immer ganz problemlos. So Diskussionen wie hier mit einer speziellen Person habe ich vorab auch nie erlebt. Denn wie soll ein Anfänger dies sonst lernen, wenn er nicht darauf hin gewiesen wird?
 

InfectedBytes

Top Contributor
eine ganz spaßige Lösung ist es auch sich einen eigenen linearen kongruenzgenerator zu schreiben, welcher als maximale Periodenlänge 49 hat:
Java:
private static int last = 0;
public static int next() {
    last = (15 * last + 13) % 49;
    return last + 1; // 1-49 anstatt 0-48
}

Damit besteht das folgende Array aus 6 paarweise verschiedenen Zahlen im Bereich von 1-49
Java:
last = (int)(Math.random() * 49); // zufälligen seed setzen
int[] zahlen = {next(), next(), next(), next(), next(), next()};

Vorteil:
Super schnell (am besten noch inlinen)
Ergebnis erscheint auf den ersten blick zufällig.

Nachteil:
Im grunde nutzt der algorithmus nur eine feste permutation der zahlen von 1-49. Daher ist die reihenfolge der zahlen immer gleich und diese ist:
32 38 30 8 21 20 5 25 31 23 1 14 13 47 18 24 16 43 7 6 40 11 17 9 36 49 48 33 4 10 2 29 42 41 26 46 3 44 22 35 34 19 39 45 37 15 28 27 12
danach geht es dann wieder von vorne los

durch den seed bestimmt man nur wo man in dieser reihe beginnt.

Ergo:
Da immer die gleiche permutation genutzt wird, macht es natürlich keinen sinn das in einer "echten" Anwendung zu nutzen, in der man möglichst echt wirkenden zufall braucht.
Falls man jedoch nicht auf sowas aus ist, dann hat man damit natürlich einen sehr schnellen algorithmus.

p.s.
Natürlich könnte man sich auch gleich eine Permutation vorgenerieren und immer daraus ziehen :D

edit:
hier einmal geinlined:
Java:
final int N = 6;
int[] zahlen = new int[N];
int x = (int)(Math.random() * 49);
for(int i = 0; i < N; i++) {
    x = (15 * x + 13) % 49;
    zahlen[i] = x + 1;
}
 
Zuletzt bearbeitet:

Flown

Administrator
Mitarbeiter
@InfectedBytes sehr unkonventionell gedacht. Gefällt mir!

@kneitzel Ich stimme dir zu, was ich auch geschrieben habe. Aber zuerst soll man sein eigenes abstraktes Denken fördern bevor man sich um Clean-Code kümmert. Wobei am besten wäre es, wenn sich sowas parallel entwickeln würde.
 
X

Xyz1

Gast
Ich will mich nicht zu weit aus dem Fenster lehnen, aber:
Er terminiert für höhere n nicht, weil Zufallszahlen nicht wirklich Zufallszahlen sind, müsste man schon das Hintergrundrauschen des Universums beobachten dafür.

das ist das Problem. Zufallszahlen sind nicht echte Zufallszahlen.

Meine Hypothese wäre jetzt, für n=36 terminiert er irgendwann, für n=37 nicht mehr, da es in der Folge von Zufallszahlen keine Teilfolge gibt, in der 37 Zufallszahlen ohne Wiederholung(en) gezogen werden.

Die Wahrscheinlichkeit lässt sich berechnen.

Deswegen bräuchte man echte Zufallszahlen, mit denen der Algorithmus für 0<=n<=49 IMMER terminieren wird, es dauert halt ein bisschen.

Auch 1,2,3,4,5,6,...,48,49 wird mit einer "bestimmten" Wahrscheinlichkeit gezogen werden, bei echten Zufallszahlen.

Das wäre nicht ohne Folgen für die "Lotto-Wirtschaft". Es gäbe einmal viele Gewinner und danach würden sich viele betrogen fühlen.
 
So auch wenn ich vorher gemeckert hab, will ich auch mal. Hier meine Lösung:

Java:
private Random random = new Random();

    public int[] lotto() {
        boolean[] lookup = new boolean[49];
        int[] result = new int[6];
        for (int i = 0; i < result.length;) {
            int zug = random.nextInt(49);
            if (!lookup[zug]) {
                lookup[zug] = true;
                result[i++] = zug + 1;
            }
        }
        return result;
    }

Ich verwalte die gezogenen Zahlen in einem boolean array. Eine viel performantere Möglichkeit, um nachzuschauen ob eine Zahl schon gezogen wurde, fällt mir nicht ein. Dafür verbraucht es aber auch ein bisschen mehr Speicher.
 

JStein52

Top Contributor
@DerUnwissende : ist keine Kritik, aber es gibt ja schon einige auch uralte Threads hier zu Lottozahlen und da gab es so eine Lösung mit einem Bool-Array auch schon mal. Und die gefällt mir gut. Bin gespannt was noch alles kommt ;););)
 

Jardcore

Top Contributor
Finde diese Lösung immer schön leserlich und intuitiv. :)
Java:
    private static final int NUMBER_OF_NUMBERS_YOU_WANT = 6; // :)
    private static final int MAX_NUMBERS = 49;
    private static final int INDEX_OF_FIRST_NUMBER = 0;
  
    @Test
    public void drawTest() {
        System.out.println(drawNumbers(createNumbers()));
    }
  
    private List<Integer> drawNumbers(List<Integer> numbers) {
        List<Integer> result = new ArrayList<Integer>();
      
        for(int i = 1; i <= NUMBER_OF_NUMBERS_YOU_WANT; i++) {
            Collections.shuffle(numbers);
            result.add(numbers.remove(INDEX_OF_FIRST_NUMBER));
        }
      
        Collections.sort(result);
      
        return result;
    }
  
    private List<Integer> createNumbers() {
        List<Integer> zahlen = new ArrayList<Integer>();
      
        for(int i = 1; i <= MAX_NUMBERS; i++) {
            zahlen.add(i);
        }
        return zahlen;
    }
 
Zuletzt bearbeitet:

JStein52

Top Contributor
Dieser Thread hier ist soooo cool. Wir hatten einfach angefangen, sind dann in ein Einstein-Universum der Softwareentwicklung gerissen worden und kommen nun wieder zum Einfachen zurück. Wenn jetzt wieder einer mit einem Einzeiler kommt flip ich aus. :):):):):)
 

InfectedBytes

Top Contributor
nicht ganz, du musst noch verhindern, dass eine zahl nicht mehrfach vorkommt. Dazu gab es vor ein paar seiten einen schönen einzeiler mit java8

edit:
hier der einzeiler von @thecain
Java:
final int[] ints =new Random().ints(1, 50).distinct().limit(6).toArray();
 

InfectedBytes

Top Contributor
@JStein52 falls du unbedingt einen Einzeiler willst, hier mal der pseudo lotto zahlen generator mit Java8 :D
Java:
int[] arr = IntStream.iterate((int)(Math.random() * 49), x -> (15 * x + 13) % 49).limit(6).toArray();
 

Jardcore

Top Contributor
Realität:
1. Schütte 49 Bälle in das Ziehgerät.
2. Ziehe 6 mal einen Ball.
2.1. Mische die Bälle.
2.2. Ziehe einen Ball.
3. Sortiere die gezogenen Bälle.

Programm:
1. Erstelle eine Liste mit 49 Zahlen.
2. Ziehe 6 mal eine Zahl.
2.1. Shuffel die Liste der Zahlen.
2.2. Ziehe die erste Zahl der Liste.
3. Sortiere die gezogenen Zahlen.

Das unleserliche liegt hier wohl eher an Java himself XD der Ablauf ist ja genau der gleiche wie beim Lotto :)
eine höhere Güte als Math.random()/Random
Collections.shuffle() benutzt übrigens auch den Zufall :)
 

javastudent25

Bekanntes Mitglied
Ähmm, ich hoffe ich störe mal nicht :D

Ich hab ein kleines Problem, dann wäre die Aufgabe endlich fertig..

Ich verstehe den Fehler einfach nicht, sprich ich weiss nicht warum er meckert, die Methoden gibt es ja schon

Multiple markers at this line
- The method getKombiArray() is undefined for the type
KombiArray
- The method getrandomKombi() is undefined for the type
RandomKombi

Betrifft die Zeile:
vergleich.vergleicheArrays(kombiArray.getKombiArray(), randomKombi.getrandomKombi());

im "Lottozahlen"

Java:
import java.io.*;
import java.text.*;
import java.util.*;
import java.lang.String;

public class Lottozahlen {

    public static void main(String[] args) {

        RandomKombi randomKombi = new RandomKombi();
        KombiArray kombiArray = new KombiArray();
        Vergleich vergleich = new Vergleich();
        vergleich.vergleicheArrays(kombiArray.getKombiArray(), randomKombi.getrandomKombi());
    }
  
}

Java:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

//Programm, um 3 vorgegebene Arrays mit zufällig generierten zu vergleichen

public class KombiArray {

    private int[] kombiArray; // in der Liste vorkommender Array/Kombination

    private void importFile() {

        String zeile = ("");

        try {

            FileReader reader = new FileReader("lottozahlen.txt");
            BufferedReader br = new BufferedReader(reader);

            while ((zeile = br.readLine()) != null) {
                stringTointArray(stringTointArray(zeile));
            }

            br.close();

        } // end try
        catch (FileNotFoundException ex) {
            System.out.println("File nicht gefunden");
        } // end catch
        catch (IOException ex) {
            System.out.println("Lesefehler");
        } // end catch
        catch (IndexOutOfBoundsException ex) {
            System.out.println("der String[][] array ist zu klein für diese Textfilegroesse");
            System.out.println("maximal sind " + "900000" + " Zeilen moeglich");
            System.exit(1);
        } // end try

    } // end importFile

    private String[] stringTointArray(String z) { // wandelt den eingelesenen
                                                    // Text
                                                    // in StringArray

        String string = z;
        String[] strArray = string.split(" ");

        for (int i = 0; i < strArray.length; i++) {
            System.out.print(strArray[i] + " ");
        }
        return strArray;
    }

    private void stringTointArray(String[] x) {

        String[] strArray = x;
        kombiArray = new int[strArray.length];
        for (int i = 0; i < strArray.length; i++)
            kombiArray[i] = Integer.parseInt(strArray[i]);
    }

    public int[] getKombiArray() {
        importFile();
        return kombiArray;
    }


}

Java:
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Random;
import java.util.Set;

public class RandomKombi {

    private int[] zufallsZahlen = new int[6];
    private int[] gluecksZahl = new int[1];
    private int[] randomKombi = new int[zufallsZahlen.length + gluecksZahl.length];
  

    public int[] getrandomKombi() {
        getGesamtArray();
        return randomKombi;
    }

    private void zahlenAusgeben() {

        for (int i = 0; i < randomKombi.length; i++) {
            System.out.print(randomKombi[i] + " ");
        }
    }

    private void erzeugeZahlenArray() {

        Random rand = new Random();
        int randomNumber;
        for (int i = 0; i < zufallsZahlen.length; i++) {
            do {
                randomNumber = rand.nextInt(42) + 1;
            } while (containsValue(zufallsZahlen, randomNumber));
            zufallsZahlen[i] = randomNumber;
        }
    }

    private void erzeugeGlueckszahl() {

        Random random = new Random();
        int zufall = random.nextInt(6) + 1;
        gluecksZahl[0] = zufall;

    }

    private void getGesamtArray() {

        erzeugeZahlenArray();
        Arrays.sort(zufallsZahlen);
        erzeugeGlueckszahl();

        for (int i = 0; i < zufallsZahlen.length; i++) {
            randomKombi[i] = zufallsZahlen[i];
        }
        for (int i = 0; i < gluecksZahl.length; i++) {
            randomKombi[zufallsZahlen.length + i] = gluecksZahl[i];
        }
        zahlenAusgeben();

    }

    private boolean containsValue(int[] array, int value) {
        for (int i = 0; i < array.length; i++) {
            if (array[i] == value) {
                return true;
            }
        }
        return false;
    }


}

Java:
public class Vergleich {

public void vergleicheArrays(int[] x, int[] y) {
      
        int[] kombiArray = x;
        int[] RandomArray = y;
        boolean bool = true;
      
           for(int i=0; i<RandomArray.length; i++){
              if(kombiArray[i] != RandomArray[i]){
                  bool = false;
              }
              }
           if (bool == false){
                System.out.println("\n Der zufällig generierte Array kommt im File nicht vor");
           }else{
              System.out.println("Der zufällig generierte Array kommt im File vor");
           }
    }
  
}
 

Meniskusschaden

Top Contributor
Ich finde dazu keinen passenden Fehler. Ist das wirklich derselbe Quelltext? Oder sind die letzten Änderungen der Datei KombiArray vielleicht noch nicht gespeichert?
 

Ähnliche Java Themen

Neue Themen


Oben