# Array mit Zufallswerten von 1 bis 45 ohne Wiederholung füllen



## eclipseworker (7. Dez 2011)

Ich habe den Code:

```
public int[] erzeugeZuffallsArray(int i){
int[] zuffallsArray = new int[i];
for(i=0; i<zuffallsArray.length;i++){
 zuffallsArray[i]=myRandom();
}
return zuffallsArray;
}
private int myRandom() {  
int zufallswert= new Double(Math.random() * 45).intValue();
for(int i=0; i<zuffallsArray.length; i++){
if(zufallswert==zuffallsArray[i]){
myRandom();
}
}
return zufallswert;
}
```
Aber die Arrays die er liefert enthalten oft eine oder mehre Gleiche Zahlen. Was mache ich falsch? ???:L


----------



## discipulo (7. Dez 2011)

```
import java.util.Random;

public class Test {

	private Random zufall=new Random();
	
	public int[] erzeugeZuffallsArray(int groesse){
		int[] zuffallsArray = new int[groesse];
		for(int i=0; i<zuffallsArray.length;i++){
			zuffallsArray[i]=myRandom(groesse,46 );
		}
		return zuffallsArray;
	}
	private int myRandom(int groesse, int max) {  
		int[] zufallsArray = erzeugeZuffallsArray(groesse).clone();
		int zufallswert=zufall.nextInt(max);
		boolean doppelt=false;
		int i=0;
		while(!doppelt && i<zufallsArray.length) {
			if(zufallsArray[i]==zufallswert) {
				doppelt=true;
			}
			if(doppelt==true) {
				zufallswert=zufall.nextInt(max);
				i=0;
			}
			else
			{
				i++;
			}
		}
		
		return zufallswert;
	}

}
```
Teste das mal


----------



## c2delegate (7. Dez 2011)

Ist das dein ganzer code?
zuffallsArray wird in der erzeugeZuffallsArray Methode instanziiert, woher soll die 2te Methode das Feld kennen? So kann das auf keinen Fall kompiliert werden.


----------



## c2delegate (7. Dez 2011)

discipulo hat gesagt.:


> ```
> import java.util.Random;
> 
> public class Test {
> ...



Etwas überdimensioniert


----------



## discipulo (7. Dez 2011)

c2delegate hat gesagt.:


> Ist das dein ganzer code?
> zuffallsArray wird in der erzeugeZuffallsArray Methode instanziiert, woher soll die 2te Methode das Feld kennen? So kann das auf keinen Fall kompiliert werden.



Wird komplimiert hab aber einen Fehler gemacht. Das Array wird jedes mal wieder in myRandom erzeugt.:lol:

@Edit: es ist glaube einfacher wenn man das erste void macht


----------



## Gast2 (7. Dez 2011)

Wenns auch nen Integer[] array sein darf:

```
public static Integer[] erzeugeZufallsArray(final int size) {
		List<Integer> numbers = new ArrayList<Integer>(size);

		for (int i = 0; i < size; i++) {
			numbers.add(i);
		}

		Collections.shuffle(numbers);
		return numbers.toArray(new Integer[0]);
	}
```


----------



## eclipseworker (7. Dez 2011)

discipulo hat gesagt.:


> ```
> import java.util.Random;
> 
> public class Test {
> ...


Mein Versuch ergab das: java.lang.StackOverflowError
. :noe:


----------



## discipulo (7. Dez 2011)

Dann versuch die List-Variante von EikeB oder take that maybe?!

```
import java.util.Random;
 
public class Test {
	public Test() {
	}
    
	private Random zufall=new Random();
        private int [] zufallsArray;
        
    public void erzeugeUndFuelleArray(int groesse){
    	zufallsArray = new int[groesse];
       
    	for(int i=0; i<zufallsArray.length;i++){
            zufallsArray[i]=myRandom(46 );
        }
        
    }
    private int myRandom(int max) {  
        int zufallswert=zufall.nextInt(max);
        boolean doppelt=false;
        	for(int i=0;i<zufallsArray.length;i++) {
        		if(zufallswert==zufallsArray[i]) {
        			doppelt=true;
        		}
        }
        if(doppelt==true) {
        return myRandom(max);
        }
        else {
        	 return zufallswert;
        }
    
       
    }
    public int [] getZufallsArray() {
    	return zufallsArray;
    }
```

Habe vorhin getest und sah nicht so aus als ob iwas doppelt wäre bei 40 zahlen.


----------



## eclipseworker (7. Dez 2011)

EikeB hat gesagt.:


> Wenns auch nen Integer[] array sein darf:
> 
> ```
> public static Integer[] erzeugeZufallsArray(final int size) {
> ...


Vielleicht ist der Code für meinen Test falsch ich habe meinen Eigenen um deinen herum gebackt aber deinen nicht verändert. 

```
public test2(int tryer)
    {
        for(int i=1;i<tryer;i++){
            x = 6;
            test=erzeugeZufallsArray(x);
            boolean o=richtig(test);
             if(o==true){
                 System.out.println("Passt!");
                }else{
                System.err.println(":-(");
            }
        }
    }
    
    private boolean richtig(Integer[] teufel){
        for(int i=0; i<teufel.length; i++){
            for(int j=0; j<i; j++){
                if(teufel[i]==teufel[j]){
                    return false;
                }
            }
            for(int j=0; j<teufel.length; j++){
                if(teufel[i]==teufel[j]){
                    return false;
                }
            }
        }
        return true;
    }

        public static Integer[] erzeugeZufallsArray(final int size) {
        List<Integer> numbers = new ArrayList<Integer>(size);
 
        for (int i = 0; i < size; i++) {
            numbers.add(i);
        }
 
        Collections.shuffle(numbers);
        return numbers.toArray(new Integer[0]);
    }
```
Nach dem Ausführen hatte ich viele traurige Smiles.


----------



## bERt0r (7. Dez 2011)

Hab eikebs Variante geringfügig angepasst:

```
static int[] erzeugeZufallsArray(int size)
{
	List<Integer> zahlen=new ArrayList<Integer>(45);
	for(int i=0;i<45;i++)
	{
		zahlen.add(i);
	}
	Collections.shuffle(zahlen);

	int[] ret=new int[size];
	for(int i=0;i<size;i++)
	{
		ret[i]=zahlen.get(i);
	}
	return ret;
}
```
[Edit] Und ja in deinem Test Programm ist ein Fehler, die 3. Forschleife ist unsinnig. Eigentlich müsste eine OutOfBounds Exception fliegen. Ausserdem kannst du meines Wissens nach Integer-Objekte nicht mit == vergleichen.[/Edit]


----------



## discipulo (7. Dez 2011)

Erläuter mal die Zeile genauer         test=erzeugeZufallsArray(x);

test ist eine int []
was genau liefert dir erzeugeZufallsArray(x);
oder erzeugeZufallsArray(x) : void


----------



## Marco13 (7. Dez 2011)

Ich gehe davon aus, dass du 'i' unterschiedliche Zufallszahlen willst, die zwischen 0 und 46 liegen. Das wird so oft gefragt (Stichwort Lotto...) dass man die Lösung von http://www.java-forum.org/java-basi...ablen-miteinander-vergleichen.html#post612775 mal in die FAQ aufnehmen sollte. (Und warum dieses Problem im allgemeinen und bei "naiven" (d.h. nicht Landeiig-trickreichen  ) Ansätzen nicht so leicht ist, steht sort im Thread etwas weiter oben)


----------



## eclipseworker (7. Dez 2011)

discipulo hat gesagt.:


> Erläuter mal die Zeile genauer         test=erzeugeZufallsArray(x);
> 
> test ist eine int []
> was genau liefert dir erzeugeZufallsArray(x);
> oder erzeugeZufallsArray(x) : void



Ich implementiere einen Integer-Array mit dem Namen test und lasse es auf die Methode erzeugeZufallsArray verweisen. Diese erzeugt ein Integer-Array (und kein void) mit Werten von 0 bis 45 ohne Wiederholung, auf dieses erzeugte Integer-Array ist dann test. Dann übergebe ich test meiner Methode richtig.


----------



## discipulo (7. Dez 2011)

D.h. erzeugeZufallsArray(x); return -> int []?
Dann müsstest du glaube schreiben
            test=erzeugeZufallsArray(x).clone();


----------



## eclipseworker (7. Dez 2011)

bERt0r hat gesagt.:


> Hab eikebs Variante geringfügig angepasst:
> [Edit] Und ja in deinem Test Programm ist ein Fehler, die 3. Forschleife ist unsinnig. Eigentlich müsste eine OutOfBounds Exception fliegen. Ausserdem kannst du meines Wissens nach Integer-Objekte nicht mit == vergleichen.[/Edit]



Meine Methode soll feststellen ob im getesten Array ein Wert mehrmals vorkommt:
Dazu wird jeder Wert mit jeden vergleichen. (for-Schleife 1). Es soll natürlich nicht ein Wert mit sich selbst verglichen werden aber mit jedem davor (for-Schleife 2) und jedem danach (for-Schleife 3). Hat er nichts gefunden ist der Array frei von Mehrwerten. Außerdem mit habe ich auf deine Methode den gleichen Test angewand (und hier ist meines Wissens der == Operator zulässig (und außerdem geht es mir um den Vergleich ob die Methode dann ==, equal oder sonst was ist ist mir egal)).


----------



## discipulo (7. Dez 2011)

bERt0r hat gesagt.:


> Hab eikebs Variante geringfügig angepasst:
> 
> ```
> ;
> ...



Das stimmt das müsste doch eine Zuweisung sein und kein Vergleich???:L


----------



## bERt0r (8. Dez 2011)

Das ist auch eine Zuweisung. Das ganze ist ein Lotto algorithmus, erst fülle ich eine ArrayList mit den Zahlen von 1 bis 45, dann würfle ich diese Zahlen durcheinander mit shuffle und anschließend picke ich mir die vordersten n Zahlen raus.
Meine bemerkung bezüglich == Richtete sich an diese code passage:

```
private boolean richtig(Integer[] teufel){     //Integer Array!!!
        for(int i=0; i<teufel.length; i++){     //Beim ersten schleifendurchlauf ist i=0 und j=0            
            for(int j=0; j<i; j++){             //Und teufel[0] ist numal == teufel[0]
                if(teufel[i]==teufel[j]){       //Diese Schleife ist unnütz und falsch          
                    return false;
                }
            }
            for(int j=0; j<teufel.length; j++){     
                if(teufel[i]==teufel[j]){                     
                    return false;                                     
                }
            }
        }
        return true;
    }
```

wie man alle Zahlen eines Arrays miteinander Vergleicht:

```
for(int i=0;i<arr.length-1;i++)
{
for(int j=i+1;j<arr.length;j++)
{
if(arr[i]==arr[j]){return false;}
}
}
```


----------



## eclipseworker (8. Dez 2011)

bERt0r hat gesagt.:


> Meine bemerkung bezüglich == Richtete sich an diese code passage:
> 
> ```
> private boolean richtig(Integer[] teufel){     //Integer Array!!!
> ...


Genau beim ersten Durchlauf der ersten Schleife sind i und j gleich 0 und deshalb dürfte die zweite Schleife in der ersten Runde nie starten, weil j<i false liefert. (Mir wäre neu dass die for-Schleife gleich arbeitet wie eine do-while Schleife.) Sie dürfte erst im zweiten Durchlauf der ersten Schleife starten wo sie dann teufel[1] mit teufel[0] vergleicht.


----------



## bERt0r (9. Dez 2011)

Aber deine 3. For schleife springt an und die wirft dich raus.
Wenn du dir schon mal überlegt hast was du da eigentlich machsst müsste dir das scon auffallen. Angenommen du hast einer 3er Array, also Elemente 0, 1 und 2. Du gehst das Array einmal mit der i-forschleife durch, vergleichst erst element 0 mit Element 0,1 und 2 in deiner 3. forschleife. Wenn beim vergleich 0 mit 0 noch nicht geflogen wäre, kämen beim nächsten i durchlauf die Vergleiche 1 mit 0, 1 mit 1, 2 mit 2. Merkst du jetzt was da gravierend falsch läuft? Du musst die elemente nur mit den Elementen vergleichen, die danach im array stehen. Die die davor stehen sollten schon verglichen worden sein.


----------



## turtle (9. Dez 2011)

Ich mache dies immer so, dass ich mir in einem boolan-Array merke, ob die Zahl an dieser Stelle bereits genommen wurde. Wenn ja, nehme ich die nächste Zufallszahl bis ich eine finde, die noch nicht hatte. Das wiederhole ich dann bis ich genügend Zahlen habe, im Beispiel 10 Zahlen (ohne Wiederholung) aus 45:


```
Random random = new Random();
		for (int j = 0; j < 5; j++) {
			boolean[] gezogen = new boolean[46];
			int[] zahlen = new int[10];
			for (int i = 0; i < 10; i++) {
				int slot = -1;
				do {
					slot = random.nextInt(45) + 1;
				} while (gezogen[slot]);
				gezogen[slot] = true;
				zahlen[i] = slot;
			}
			for (int zahl : zahlen)
				System.out.print(zahl + " ");
			System.out.println();

		}
```


----------



## eclipseworker (9. Dez 2011)

bERt0r hat gesagt.:


> Aber deine 3. For schleife springt an und die wirft dich raus.
> Wenn du dir schon mal überlegt hast was du da eigentlich machsst müsste dir das scon auffallen. Angenommen du hast einer 3er Array, also Elemente 0, 1 und 2. Du gehst das Array einmal mit der i-forschleife durch, vergleichst erst element 0 mit Element 0,1 und 2 in deiner 3. forschleife. Wenn beim vergleich 0 mit 0 noch nicht geflogen wäre, kämen beim nächsten i durchlauf die Vergleiche 1 mit 0, 1 mit 1, 2 mit 2. Merkst du jetzt was da gravierend falsch läuft? Du musst die elemente nur mit den Elementen vergleichen, die danach im array stehen. Die die davor stehen sollten schon verglichen worden sein.



Stimmt da habe ich aus versehen falsch kopiert, so gehört es richtig:

```
private boolean richtig(int[] test){
        for(int i=0; i<test.length; i++){ 
            for(int j=0; j<i; j++){ // Wenn i=j bricht die Schleife ab, wenn i=0 beginnt sie nie
                if(test[i]==test[j]){
                    return false;
                }
            }
            for(int k=i+1; k<test.length; k++){ // Wenn k gleich test.length bricht die Schleife ab, wenn i+1=test.length beginnt sie nie
                if(test[i]==test[k]){
                    return false;
                }
            }
        }
        return true;
    }
```
Na ja damit stimmt es. :applaus:


----------



## bERt0r (9. Dez 2011)

Du hast dir meinen Beitrag überhaupt nicht durchgelesen, es ist komplett sinnlos das Array in nach vor und zurück durchzulaufen. Du vergleichst die selben Objekte mehrmals miteinander. Wenn dus mir nicht glaubst, mach ein println bei jedem Vergleich und lass ein int[3] durchlaufen. Weiters Vergleicht man Objekte mit equals().

Die Methoden die dir hier gepostet wurden stimmen alle, das kannst du auch einfach überprüfen indem du so ein Array ausgibst. Ich hab eikeBs Methode nur angepasst weil darin nicht Zahlen von 0-45 sondern von 0-Größe vom Array erzeugt wurden.


----------

