Generátor 6 náhodných čísel bez opakování – Java – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Generátor 6 náhodných čísel bez opakování – Java – Fórum – Programujte.comGenerátor 6 náhodných čísel bez opakování – Java – Fórum – Programujte.com

 

Vlákno bylo úspěšně vloženo.
Pokud sám přijdeš na řešení, nezapomeň ho sem přidat!
gafan4ik0
Duch
12. 6. 2013   #1
-
0
-

Dobrý den. Potřeboval bych pomoc s programem na generování 6 náhodných čísel od 1 do 49.

Našel jsem na internetu tohle :  

  public static void main(String[] args) {
   
        Random r = new Random();
         int[] nCisla = new int[7];
         for(int i=1; i < 7; i++) {
             nCisla[i] = r.nextInt(48);
                 System.out.print(nCisla[i]+1 + " ");
         }}}   

Ale to furt neřeší můj problém s tím, že by se daná čísla neměla opakovat.

Při spuštění programu co jsem našel se vygeneruje 6 čísel, ale po několika spuštění se stejně dvě čísla opakují a proto bych chtěl poprosit o pomoc a taky o řešení jak by se tento problém mohl odstranit.

Nahlásit jako SPAM
IP: 89.102.169.–
KIIV
~ Moderátor
+43
God of flame
12. 6. 2013   #2
-
+3
-
Zajímavé

no bud muzes pri vygenerovani projet jiz vygenerovane hodnoty, jestli neni stejne.. a pripadne opakovat generovani..

nebo si udelas treba pole hodnot a vyjmes z nej pokazdy prvek na nahodne pozici.. (da se klidne prohodit hodnota s poslednim prvkem a ten pak odstranit) ale to se hodi az na vetsi mnozstvi...

nebo pole prvku od 0 do 49, shuffle a pak vzit prvnich 6...

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Michal
~ Anonymní uživatel
683 příspěvků
12. 6. 2013   #3
-
+1
-
Zajímavé

 Takhle sem to udelal s ArrayListem. Oproti poli ma uz naimplementovanou metodu contains(), ktera zjisti, jestli dany prvek uz uvnitr je a nemusis to zjistovat manualne.

public class Neco {
     public static void main(String[] args) {
   
        Random r = new Random();
        ArrayList ar = new ArrayList();
        int odpocet=0;
        while(true){
            int cislo = r.nextInt(48)+1;
            if (!ar.contains(cislo)) {
                ar.add(cislo);
                odpocet++;
            }
            if (odpocet==7) 
              break;  
            
        }
        
         for (int i = 0; i < ar.size(); i++) {
             System.out.print(ar.get(i)+"  ");
         }
     
     }
}
Nahlásit jako SPAM
IP: 81.201.55.–
crazy
~ Moderátor
+10
Grafoman
12. 6. 2013   #4
-
0
-

#1 gafan4ik
bud jak psal KIIV nebo si udelej mnozinu a pak jenom neco ve smyslu:

Set<int> mnozina = new HashSet<int>();

while(mnozina.size() < 6) mnozina.add(random.nextInt());
Nahlásit jako SPAM
IP: 147.32.31.–
All you need is vision and time.
Michal
~ Anonymní uživatel
683 příspěvků
12. 6. 2013   #5
-
0
-

Jen si tam uprav šestku. Nevím proč sem myslel, že jich chceš 7. :-)

Nahlásit jako SPAM
IP: 81.201.55.–
gafan4ik0
Duch
12. 6. 2013   #6
-
0
-

#3 Michal

Děkuji za program, ale ne se vším jsem pracoval a ne vše bych dokázal vysvětli někomu dalšímu a proto bych chtěl poprosit o popis  // co a jak každá část programu dělá a jak to vše funguje :) Předem ještě jeden dík :)

Nahlásit jako SPAM
IP: 89.102.169.–
Michal
~ Anonymní uživatel
683 příspěvků
12. 6. 2013   #7
-
+1
-
Zajímavé

   

public class Neco {
     public static void main(String[] args) {
   
        Random r = new Random();    // Trida z knihovny util, ktera umoznuje generovat nahodna trida
        ArrayList ar = new ArrayList();     // ArrayList je kolekce... takovy chytrejsi pole, ktery nema pevnou delku a predem pripravene nektere uzitecne metody
        int odpocet=0;
        while(true){                // while cyklus je jako for, akorat jede dokud neni splnena podminka v zahlavi. V tomto pripade do nekonecna
            int cislo = r.nextInt(48)+1;
            if (!ar.contains(cislo)) {  // metoda contains(int a) -> zavolas nad ArrrayListem, nacpes do ni cislo a ona ti vrati boolean (true/false) jestli uz v danym arrayListu takovy cislo je.
                ar.add(cislo);      // metoda analogicka k operaci pole[i]=cislo; -> Tedy vlozeni objektu do ArrayListu. Akorat neuvadis index, o to se ArrayList postara sam.
                odpocet++;          //pokud se cislo pridalo, zvysi se hodnota odpocet -> coz ti zajisti ze jich bude jen 6
            }
            if (odpocet==7)     
              break;            // Jakmile dosahnes v odpoctu cisla 6, tak breaknes while cyklus -> tzn. vyskocis z nej. Uz neni potreba aby dal probihal.
            
        }
        
         for (int i = 0; i < ar.size(); i++) {      // ar.size() -> je analogicka metoda k pole.length. Proste ti to rekne kolik ten ArrayList obsahuje prvku, jak je velkej.
             System.out.print(ar.get(i)+" ");       // ar.get(i) -> ti vrati hodnotu ArrayListu na indexu i. Analogicky k pole[i].
         }
     
     }
}
Nahlásit jako SPAM
IP: 81.201.55.–
lukber0
Newbie
13. 6. 2013   #8
-
+1
-
Zajímavé

Nevýhoda tohoto řešení je, že pokud by gafan4ik potřeboval změnit rozsah čísel/počet čísel (třeba vybrat 6 čísel z 6ti, nebo 49 čísel ze 49) tak by se nemusel dočkat výsledku. Funkce totiž kontroluje jestli vygenerované pseudonáhodné číslo již není vloženo do výsledného seznamu => čím více se bude výsledný seznam rovnat počtu požadovaných čísel tím více se bude muset generátor náhodných čísel "trefit" do užší množiny hodnot.

Řešení nabídl již KIIV - pseudonáhodná čísla nebudou reprezentovat množinu výsledků, ale bude to index ze seznamu možných hodnot.

Mohlo by to vypadat třeba takto:

final int SOURCE_FROM = 1;
final int SOURCE_TO = 49;
final int MAX_SELECTED_COUNT = 6;

List<Integer> source = new ArrayList<Integer>();
List<Integer> selected = new ArrayList<Integer>(MAX_SELECTED_COUNT);

for (int i = SOURCE_FROM; i <= SOURCE_TO; i++) {
	source.add(i); // inicializace zdroju
}

for (int i = 0; i < MAX_SELECTED_COUNT; i++) {
	int randomIndex = new Random().nextInt(source.size());
			
	Integer selectedValue = source.get(randomIndex);
	selected.add(selectedValue);
	source.remove(selectedValue);
}

for (Integer value : selected) {
	System.out.println(value);
}
Nahlásit jako SPAM
IP: 193.85.250.–
NotBeginner
~ Anonymní uživatel
185 příspěvků
16. 6. 2013   #9
-
0
-

Proč do toho tahat kolekce? Toto je trivialnější 

public class A_035_NaplniPoleRandom {
	public static void main(String [] args){
		int [] pole = new int [7];		// deklarujes a alokujes pole v o velikosti 7 => pole[0],pole[1],...,pole[6]
		for(int i=0;i<pole.length;i++){ // cyklus for = pro kazde pole proved
			pole[i]=(int)(Math.random()*100.0);	// do prvku pole vloz cislo od 0 do 100
			System.out.println("Pole ["+(i+1)+"] ="+pole[i]);	} // proved vypis daneho prvku pole
	}
}
Nahlásit jako SPAM
IP: 86.49.87.–
NotBeginner
~ Anonymní uživatel
185 příspěvků
16. 6. 2013   #10
-
0
-

A pokud bys trval tedy na tom ze skutečně potřebuješ aby se čisla neopakovala což porušuje základní principy random ( náhody ) pak je použití kolekce - Set taky docela vhodné 

import java.util.*;
public class A_035_NaplniPoleRandom {
	public static void main(String [] args){
		int [] pole = new int [7];		// deklarujes a alokujes pole v o velikosti 7 => pole[0],pole[1],...,pole[6]
		for(int i=0;i<pole.length;i++){ // cyklus for = pro kazde pole proved
			pole[i]=(int)(Math.random()*50.0);	// do prvku pole vloz cislo od 0 do 50
			System.out.println("Pole ["+(i+1)+"] ="+pole[i]);	} // proved vypis daneho prvku pole
		// a pro pripad ze by se nemeli opatkovat
		HashSet<Integer> mnozina = new HashSet<Integer>();
		do{		// provadej toto dokola
			mnozina.add((int)(Math.random()*50.0));
		} while ( mnozina.size() !=7);	// dokud nebude velikost kolekce rovna 7
		for(Iterator<Integer> iter = mnozina.iterator(); iter.hasNext();){ // iterator pro pruchod kolekci
			System.out.println("Cislo :"+iter.next());	}	}
}
Nahlásit jako SPAM
IP: 86.49.87.–
KIIV
~ Moderátor
+43
God of flame
16. 6. 2013   #11
-
+1
-
Zajímavé

#10 NotBeginner
procpak by mel porusovat pravidla nahody? Zkus treba z balicku karet vytahnout tu samou vickrat, kdyz vybranou kartu nevracis :)

Nahlásit jako SPAM
IP: 94.112.32.–
Program vždy dělá to co naprogramujete, ne to co chcete...
NotBeginner
~ Anonymní uživatel
185 příspěvků
19. 6. 2013   #12
-
0
-

#11 KIIV
Já si myslím, že to zadání je špatně pochopené, již zadavatelem. Podle triviálnosti úlohy se jedná rozhodně o školský příklad a to pochybuji, že ve škole mu řekli, že by nesměl mít opakující se čísla. Nebo si snad myslíš že po něm chtěli kolekce nebo komplikované cykly s porovnáváním hodnot v daném poli na úrovni studenta ? Mýlit se samozřejmě mohu. 

Nahlásit jako SPAM
IP: 86.49.87.–
lukber0
Newbie
19. 6. 2013   #13
-
0
-

#10 NotBeginner
toto řešení má ale stejný problém jako jsem popisoval. Nech si vygenerovat 10 čísel z 11 možných a schválně si nech počítat počet iterací.

Nahlásit jako SPAM
IP: 94.112.235.–
NotBeginner
~ Anonymní uživatel
185 příspěvků
20. 6. 2013   #14
-
0
-

#13 lukber
Tak za prvé. Pokud použiješ pouze druhou část mého zdroje není možné aby se zobrazilo stejné číslo. Kolekce Set<> nic takového neumožnuje.  Za druhé použití iteratoru není iterace. Iterátor = cyklus pro průchod kolekcí, a iterace = provádění matematické operace v numerických metodách kdy se snažíš konvergovat(česky = přibližovat) k přesnému řešení. 

Nahlásit jako SPAM
IP: 86.49.87.–
lukber0
Newbie
20. 6. 2013   #15
-
0
-

#14 NotBeginner
Moje chyba, špatně jsem se vyjádřil:

Stejným problémem jsem myslel počet průchodů (iterací) které bude muset udělat cyklus do{} while než naplní požadovaný počet hodnot (tedy než bude porušena podmínka mnozina.size() !=7). Pokud by bylo potřeba např. vygenerovat 100 čísel ze 101 možných pak by tato podmínka nemusela být porušena (cyklus by neskončil) nikdy.

Nahlásit jako SPAM
IP: 193.85.250.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 2 hosté

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý