Obsah 4. přednášky: Datový typ pole - motivace Deklarace, vytvoření, inicializace pole Mechanismus vytváření pole, reference Pole jako parametr či návratová hodnota Změna pole daného parametrem Kopie polí Pole reprezentující množinu Vícerozměrná pole, matice Dynamické rozšiřování pole* Tato tematika je zpracována v Záznamy přednášek: str. 91 - 111
Přednášky KIV/PPA1, A. Netrvalová, 2016
4. přednáška
Datový typ pole - motivace Úkol – zjistit četnost číslic v jednořádkovém textu. int nula = 0; // vice promennych stejného typu Řešení pomocí přepínače int jedna = 0; Toto je sice funkční, ale ne efektivní! = zdlouhavé, obtížná modifikace, int dva = 0; Takto (lépe viz slide 19) např.nedělat!!! pro písmena, ...–NE!!! ... int osm = 0; int devet = 0; // reprezentuji citace vyskytu cislic String text = sc.nextLine(); // nacteni textu (radky) int i=0; while(i
= '0' && znak <= '9'){ switch (znak){ // pouzitim prepinace case '0': nula++; break; case '1': jedna++; break; case '2': dva++; break;
// ... case '8': osm++; break; case '9': devet++; break; default: /* System.out.println("Chyba"); */ d123y 662098 0: 1 break; 1: 1 } } i++; } System.out.println("0: " + nula); System.out.println("1: " + jedna); System.out.println("2: " + dva); //... System.out.println("8: " + osm); System.out.println("9: " + devet);
2: 3: 4: 5: 6: 7: 8: 9:
2 1 0 0 2 0 1 1
Strana 2 (celkem 25)
Pole - terminologie - strukturovaný datový typ - pevné délky (počet prvků, dán při vzniku) - prvky (položky) pole - typ: libovolný, ale pro všechny prvky stejný typ (homogenní datová struktura) - index: přístup k prvkům, typicky int (0 počet-1)
Deklarace, vytvoření, inicializace Deklarace datovyTyp[] jmenoPole; Příklad: int[]mePole;
Vytvoření (v Javě se s polem pracuje jako s objektem) jmenoPole = new datovyTyp [velikostPole]; Příklad: int[]tyden; tyden = new int[7]; Deklarace a vytvoření současně: datovyTyp[] jmenoPole = new datovyTyp [velikostPole]; Příklad: double[]teplota = new double[5];
Inicializace - užitím cyklu:
proměnná udávající počet prvků pole teplota
for (int i = 0; i < teplota.length; i++) teplota[i] = 37 + (double)i/10;
- výčtem hodnot: double [] teplota = {37.0, 37.1, 37.2, 37.3, 37.4}; Strana 3 (celkem 25)
Mechanismus vytváření pole, reference Deklarace int [ ] a = new int[3]; má tento efekt: – lokální proměnné a se přidělí paměťové místo v zásobníku, které však neobsahuje prvky pole, ale je „dimenzováno“ na uložení čísla reprezentujícího adresu jiného paměťového místa – operátorem new se v jiné paměťové oblasti rezervuje (alokuje) úsek potřebný pro pole 3 prvků typu int – adresa tohoto úseku se uloží do a, při grafickém znázornění reprezentace v paměti místo adres kreslíme šipky
Poznámka: reprezentace pole je zjednodušená, chybí ještě počet prvků.
Pozor: referenční proměnnou lze deklarovat i bez vytvoření pole int [ ] b;
b
null
V tomto případě se zavede referenční proměnná, která má nedefinovanou hodnotu, jde-li o lokální proměnnou, nebo speciální hodnotu null, která neukazuje „nikam“, jde-li o statickou proměnnou. Strana 4 (celkem 25)
Jedné referenční proměnné pole lze přiřadit jinou referenční proměnnou pole, ale tato pole musí být stejného typu. Po přiřazení obě proměnné ukazují na totéž pole! int[] x = new int [3]; Příklad: int[] y = x; y[1] = -6; -6 System.out.println(x[1]);
Poznámka: Přiřazení (hodnot) mezi dvěma poli není v Javě definováno, je řešeno prostřednictvím kopie pole (viz dále).
Výpis pole - cyklem: prvek po prvku - metodou toString(): celé, pouze jednorozměrné pole najednou v hranatých závorkách, prvky oddělené čárkou, metoda je v třídě Arrays v balíčku util (viz dále). Strana 5 (celkem 25)
Příklad: Pole - deklarace, inicializace, vytvoření public class PoleVytvoreni { static int [] b; // inicializace: null static int [] c = {1, 0, 7, 4, 5}; // inicializace public static void main (String [] args){ System.out.println("c = " + Arrays.toString(c)); System.out.println("b = " +Arrays.toString(b)); int [] a ; // reference, chybi incializace //System.out.println(Arrays.toString(a));
// nelze
a = null; // ALE POZOR!!!
System.out.println("ref c:" + c); // kam ukazuje System.out.println("ref b:" + b); System.out.println("ref a:" + a); if (a == null){ System.out.println("a = " + Arrays.toString(a)); } a = new int [2]; // pole vytvoreno System.out.println("a: "+Arrays.toString(a)); // vypis int[] x = new int [3]; int[] y = x; y[1] = -6; System.out.println("x1: " + x[1]); // vypis na indexu 1 System.out.println("y1: " + y[1]); System.out.println("x: "+ Arrays.toString(x)); //cele System.out.println("y: " + Arrays.toString(y)); x = new int [5]; // nove vytvoreni, stare nedostupne System.out.println("nove x: " + Arrays.toString(x)); System.out.println("y: " + Arrays.toString(y)); c = [1, 0, 7, 4, 5] } }
b = null ref c:[I@1db9742 ref b:null ref a:null a = null a: [0, 0] x1: -6 y1: -6 x: [0, -6, 0] y: [0, -6, 0] nove x: [0, 0, 0, 0, 0] y: [0, -6, 0]
Strana 6 (celkem 25)
Nyní můžeme použít pole pro již dříve uvedený příklad na výpočet četnosti číslic. import java.util.*; Toto je ok! public class CetnostCislicPole { static private Scanner sc = new Scanner(System.in); public static void main(String[] args) { 110w2 t3383g476 int cetnost [] = new int[10]; 0: 1 String s = sc.nextLine(); 1: 2 int k=0; 2: 1 while(k<s.length()) { 3: 3 char znak = s.charAt(k++); 4: 1 5: 0 if(znak >= '0' && znak <= '9'){ 6: 1 cetnost[(znak - (int)'0')]++; 7: 1 } 8: 1 } 9: 0 for (int i=0; i
Poznámka: příkaz for each – přístup postupně ke všem prvkům public class ForEach public class ForEach{ { public static void public static voidmain(String[] main(String[] args) args) {{ int pole = {1,2,3,4,5}; int pole [] =[] {1,1,1,1,1}; int soucet = 0; int soucet = 0; for(int i :pole) for(int i :pole) { { soucet soucet +=+= i; i; } } }
} System.out.println("soucet = " + soucet);
System.out.println("soucet = " + soucet); } soucet = 15 }
soucet = 5
Strana 7 (celkem 25)
Pole - parametr či návratová hodnota Reference pole může být: - parametrem metody (metoda vypisPole()) - návratovou hodnotou (metoda nactiPole())
Příklad import java.util.*; public class PoleParametrANavrat { static private Scanner sc = new Scanner(System.in); static int [] nactiPole(int pocet) { //zde pocetPrvku int[] pole = new int [pocet]; // nove pole for(int i=0; i<pole.length; i++){ System.out.print("Zadej a[" + i + "]: "); pole[i] = sc.nextInt(); // nacteni } return pole; // návrat } static void nacti(int pole []) { // jina moznost nacteni - zde pole for(int i=0; i<pole.length; i++){ System.out.print("Zadej b[" + i + "]: "); pole[i] = sc.nextInt(); // nacteni } } static void vynulujPole(int [] pole) { for(int i=0; i<pole.length; i++){ pole[i] = 0; // zmena pole - vynulovani } } static void vypisPole(String s, int [] pole) { for(int i=0; i<pole.length; i++){ System.out.println(s + "[" + i + "] = " + pole[i]); // výpis }} Strana 8 (celkem 25)
public static void main(String[] args) { System.out.print("Zadej pocet prvku: "); int pocetPrvku = sc.nextInt(); int a [] = new int [pocetPrvku]; a = nactiPole(pocetPrvku); Zadej pocet // nacti(a); // dalsi moznost Zadej a[0]: vypisPole("a" , a); Zadej a[1]: System.out.println(Arrays.toString(a)); Zadej a[2]: vynulujPole(a); a[0] = 1 a[1] = 2 vypisPole("a" , a); System.out.println(Arrays.toString(a)); a[2] = 3 [1, 2, 3] } // tj. vypis pole a najednou a[0] = 0 } a[1] = 0
prvku: 3 1 2 3
a[2] = 0 [0, 0, 0]
Změna pole daného parametrem V metodě vynulujPole() jsme nevytvořili nové pole, ale vynulovali pole dané parametrem, obdobně v nacti(int pole[]). Proč to funguje? Jelikož metoda vynulujPole() dostala referenci na stejné pole, na které ukazuje proměnná a.
Kopie polí - použitím cyklu - metodou třídy System arraycopy(zdroj, odZdroj, kopie, odKopie, length);
Strana 9 (celkem 25)
Příklad: různé způsoby kopie pole -
pole prvni je prekopirováno do pole druhe do pole treti od indexu 0 jsou nakopírovány 2 prvky z pole prvni od indexu 2
import java.util.*; public class KopiePoli{ public static void main(String [] args){ int[] prvni = {2, 3, 1, 5, 10}; int[] druhe = new int[prvni.length]; int[] treti = new int[3]; System.out.println("prvni:" + Arrays.toString(prvni)); System.out.println("druhe:" + Arrays.toString(druhe)); System.out.println("Kopirovani "); for (int i = 0; i < prvni.length; i++){ // cyklem druhe[i] = prvni[i]; // celé prvni pole do druheho pole } // z prvniho od indexu 2 do tretiho od indexu 0, 2 hodnoty
System.arraycopy(prvni, 2, treti, 0, 2); System.out.println("prvni:" + Arrays.toString(prvni)); System.out.println("druhe:" + Arrays.toString(druhe)); System.out.println("treti:" + Arrays.toString(treti)); } prvni:[2, 3, 1, 5, 10] } druhe:[0, 0, 0, 0, 0] Kopirovani prvni:[2, 3, 1, 5, 10] druhe:[2, 3, 1, 5, 10] treti:[1, 5, 0] Strana 10 (celkem 25)
Příklad: Ze zadaných výšek zadaného počtu modelek spočtěte a vypište průměrnou výšku modelek a počet těch, které jsou vyšší, než spočtená průměrná výška. import java.util.*; public class Modelky { private static Scanner sc = new Scanner(System.in); static int[] nactiVysky(int pocet){ int [] pole = new int[pocet]; for(int i=0; i<pole.length; i++){ pole[i] = sc.nextInt(); } return pole; } static double spoctiPrumernouVysku(int [] pole){ int s = 0; for(int i=0; i<pole.length; i++){ s += pole[i]; } return (double)s/pole.length; } static int urciPocetVyskoveNadprum(int []pole, int prumer){ int pocet = 0; Zadej pocet modelek: 10 Zadej jednotlive vysky: for(int i=0; i<pole.length; i++){ 159 if(pole[i]>prumer){ 180 pocet++; 178 } 156 183 } return pocet; 185 } 181 public static void main(String[] args) { 179 System.out.print("Zadej pocet modelek: "); 175 173 int pocetModelek = sc.nextInt(); System.out.println("Zadej jednotlive vysky: "); Prumerna vyska: 174 Pocet s nadprumernou vyskou: 7 int vysky[] = nactiVysky(pocetModelek); int prumernaVyska = (int)spoctiPrumernouVysku(vysky); System.out.println("Prumerna vyska: " + prumernaVyska); System.out.print("Pocet s nadprumernou vyskou: "); System.out.println(urciPocetVyskoveNadprum(vysky, prumernaVyska)); } } Strana 11 (celkem 25)
Příklad: Samoobslužný výčep - evidence spotřeby piva import java.util.*; public class Hospoda { static private Scanner sc = new Scanner (System.in); static double spoctiSpotrebuPiva(double [] stul) { double spotreba = 0; Nacti spotrebu piva u stolu 1: 1 2 for(int i=0; i<stul.length; i++){ Nacti spotrebu piva u stolu 2: 2 3 spotreba += stul[i]; Vypis spotrebu piva u stolu 1 } [1.0, 2.0] = 3.0 return spotreba; Vypis spotrebu piva u stolu 2 [2.0, 3.0, 1.0, 4.0] = 10.0 } Vypis spotrebu piva celkem public static void main(String [] args){ 1: [1.0, 2.0] sc.useLocale(Locale.US); 2: [2.0, 3.0, 1.0, 4.0] 3: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] double [] stul1 = new double[2]; Celkova spotreba = 13.0 double [] stul2 = new double[4]; double [] stul3 = new double[6]; System.out.print("Nacti spotrebu piva u stolu 1: "); for(int i=0; i<stul1.length; i++){ stul1[i] = sc.nextDouble(); } System.out.print("Nacti spotrebu piva u stolu 2: "); for(int i=0; i<stul2.length; i++){ stul2[i] = sc.nextDouble(); } System.out.println("Vypis spotrebu piva u stolu 1"); System.out.print(Arrays.toString(stul1)); System.out.println(" = " + spoctiSpotrebuPiva(stul1)); System.out.println("Vypis spotrebu piva u stolu 2"); System.out.print(Arrays.toString(stul2)); System.out.println(" = " + spoctiSpotrebuPiva(stul2));
1 4
System.out.println("Vypis spotrebu piva celkem"); System.out.println("1: " + Arrays.toString(stul1)); System.out.println("2: " + Arrays.toString(stul2)); System.out.println("3: " + Arrays.toString(stul3)); double celkem = spoctiSpotrebuPiva(stul1) + spoctiSpotrebuPiva(stul2) + spoctiSpotrebuPiva(stul3); System.out.println("Celkova spotreba = " + celkem); }} Strana 12 (celkem 25)
Pole reprezentující množinu - pole typu boolean - je-li prvek součástí množiny, má hodnotu true - není-li součástí množiny, má hodnotu false
Úloha: vypsat všechna prvočísla menší nebo rovna zadanému max Prvočíslo - přirozené číslo, které je dělitelné (beze zbytku) právě dvěma různými přirozenými čísly, a to číslem jedna a sebou samým (tedy 1 není prvočíslo)
2, 3, 5, 7, 11, 13, 17, 19, 23, 29,...
Čínský algoritmus – je číslo prvočíslem? Zjisti, zda N je dělitelem čísla 2N-2: je-li, pak N je prvočíslo není-li, pak N není prvočíslo (funguje pro množinu přípustných dat: ≤ 340)
Eratosthenovo síto - jednoduchý algoritmus pro nalezení všech prvočísel menších než zadaná horní mez - pojmenování po řeckém matematikovi Eratosthenovi z Kyrény (276 –194 př.n.l.)
Strana 13 (celkem 25)
Eratosthenovo síto
¨
Algoritmus:
Vytvoříme množinu obsahující přirozená čísla od čísla 2 do max.
Z množiny vypustíme všechny násobky čísla 2.
Najdeme nejbližší číslo k tomu, jehož násobky jsme v předchozím kroku vypustili, a vypustíme všechny násobky tohoto čísla.
Opakujeme předchozí krok tak dlouho, dokud číslo, jehož násobky jsme vypustili, není větší než max .
Čísla, která v množině zůstanou, jsou hledaná prvočísla. ukázat (obrázek) běh algoritmu pro max=20
Časová složitost algoritmu: O(N*log(log N)), kde N je horní mez rozsahu Pro reprezentaci množiny čísel použijeme pole prvků typu boolean Prvek pole mnozina[x] bude udávat, zda číslo x: - v množině je (true) - v množině není (false) Strana 14 (celkem 25)
public class Sito { static final int MAX = 17; static boolean [] vytvorMnozinu (int max){ boolean [] mnozina = new boolean [max+1]; for(int i=0; i< mnozina.length; i++){ mnozina[i] = true; } return mnozina; } static void sito (boolean [] mnozina){ int max = (int) Math.sqrt(mnozina.length); for(int i=2; i<=max; i++){ if(mnozina[i] == false){ continue; } for(int j=2*i; j<mnozina.length; j += i){ mnozina[j] = false; } } } static void vypisPrvocisla (boolean [] mnozina){ for(int i=2; i<mnozina.length; i++){ if(mnozina[i]){ System.out.print(i + ", "); } } System.out.println(); } public static void main(String [] args){ boolean [] prvocisla = vytvorMnozinu(MAX); sito(prvocisla); vypisPrvocisla(prvocisla); }
2, 3, 5, 7, 11, 13, 17,
Strana 15 (celkem 25)
Příklad: Obraťte v tomtéž poli pořadí hodnot prvků. Počet <1,10> i hodnoty <-15,15> prvků vygenerujte náhodně.
import java.util.*; public class ObraceniPole { private static Random r = new Random(); static final int MAX_HODNOTA =15; static void obratPole(int[] pole) { int pom; for (int i=0; i<pole.length/2; i++) { pom = pole[i]; pole[i] = pole[pole.length-1-i]; pole[pole.length-1-i] = pom; } } static int[] naplnPole(){ int pocetPrvku = r.nextInt(MAX_HODNOTA -1) + 1; int [] pole = new int[pocetPrvku]; for(int i=0; i<pole.length; i++){ pole[i] = r.nextInt(2*MAX_HODNOTA)-MAX_HODNOTA; } return pole; } public static void main(String[] args) { int[] vstupniPole = naplnPole(); System.out.println(Arrays.toString(vstupniPole)); obratPole(vstupniPole); System.out.println(Arrays.toString(vstupniPole)); } [-3, -14, 5, -14, 0, -8, -8, 8, 7, 8] } [8, 7, 8, -8, -8, 0, -14, 5, -14, -3] Strana 16 (celkem 25)
Vícerozměrná pole, matice - přístup prostřednictvím více indexů - práce jako s jednorozměrnými poli (prvky jsou opět pole – pole s nestejnou délkou řádek) - deklarace stejná, pouze více rozměrů ([]) Příklad: Celočíselné dvourozměrné pole [] [] pole [1] pole [2]
pole [0]
1
8
0 1 2
4
2
9
1
0
1
0
1
2 3
00
1 1
null
null
33
44 $
22
3
pole
int[][] pole = new int [5][]; pole[0] = new int [2]; pole[0][0] = 2; pole[0][1] = 4; pole[1] = new int[2]; pole[1][0] = 1; pole[1][1] = 8; pole[2] = new int[4]; pole[2][0] = 2; pole[2][1] = 9; pole[2][2] = 1; pole[2][3] = 3;
2
4
1
8
2
9
1
3
? ?
Strana 17 (celkem 25)
Příklad: Obdélníková matice (m řádek, n sloupců) int m = 3; int n = 4; int [][] matice = new int [m][n];
Rozměry matice matice.length = počet řádků matice[0].length = počet sloupců
Inicializace matice 3x3 int [][] mat = {{1,0,0},{0,1,0},{0,0,1}}; b11 b12 b13 b14 a11 a12 a13 a a a b21 b22 b23 b24 21 22 23 b b b b 31 32 33 34 Př.: Součin matic a11b11 a12b21 a13b31 c12 c13 c14 a b a b a b c c c 21 11 22 21 23 31 22 23 24 import java.util.*; public class SoucinMatic { static private Scanner sc = new Scanner(System.in); /* static int c[][] = new int [3][4]; static int a[][] = {{1, 1, 1, 1, 1}, {1, 1, 1, 1, 1}, {1, 1, 1, 1, 1}}; static int b[][] = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}; */ Strana 18 (celkem 25)
static int [][] nactiMatici(int radky, int sloupce){ int [][] matice = new int[radky][sloupce]; for (int i = 0; i < matice.length; i++){ for (int j = 0; j < matice[i].length; j++) { matice[i][j] = sc.nextInt(); } } return matice; } static void vypisMatici(int [][] matice){ for (int i = 0; i < matice.length; i++){ for (int j = 0; j < matice[i].length; j++) { System.out.print(matice[i][j] + " "); } System.out.println(); } } static int [][] vynasobMatice(int[][] a, int [][] b){ int [][] c = new int[a.length][b[0].length]; for (int i = 0; i < a.length; i++) { for (int j = 0; j < b[i].length; j++) { int s=0; for (int k = 0; k < a[i].length ; k++){ s += a[i][k] * b[k][j]; } c[i][j] = s; } } return c; } Strana 19 (celkem 25)
public static void main(String[] args) { int m = sc.nextInt(); int n = sc.nextInt(); int p = sc.nextInt(); int [][] a = new int [m][n]; int [][] b = new int [n][p]; int [][] c = new int [m][p]; a = nactiMatici(m,n); b = nactiMatici(n,p); c = vynasobMatice(a, b); vypisMatici(a); vypisMatici(b); vypisMatici(c);
2 3 4 1 1 1 1 1 1 1 1 1 1 3 3
1 1 1 1 1 1 1 1 1 1 3 3
1 1 1 1 1 1 1 1 1 1 3 3
A 1 1 1
1 1 1 3 3
B
C
} } Poznámka: Ochrana před použitím indexu mimo rozsah pole Použít příkaz assert
assert (index>=0 && index
Dynamické rozšiřování pole* Před započetím práce s polem – určení velikosti Komplikace – budoucí potřeba většího pole - kdy ? - kolik ?
Řešení - test indexu pole a následné dynamické rozšíření - technika rozšíření pole = programová sekvence Myšlenka je založena na tom, že původní pole a bude „referencováno“ též proměnnou x a na proměnné a vytvoříme větší pole, např. dvakrát tak velké jako bylo pole původní. Hodnoty prvků pole a jsou teď implicitně nastaveny na 0 (pole je objekt). Původní hodnoty tudíž zkopírujeme z pole x. Pro ilustraci přiřadíme hodnoty i ostatním prvkům pole a.
a 0
1
2
3
0
1
2
3
0
1
2
3
x
x a 4
5
6
7
Strana 21 (celkem 25)
Ilustrace postupu: public class DynamickePole { import java.util.*; public static void main (String[] args) { int maxN = 4; int[] a = new int[maxN]; // naplneni stavajiciho pole for(int i = 0; i < a.length; i++) { a[i] = i; } // rozsireni pole na dvojnasobek int[] x = a; a = new int[2*a.length]; // kopie hodnot prvku z puvodniho pole for(int i = 0; i < x.length; i++) { a[i] = x[i]; } // doplneni dalsich hodnot do rozsireneho pole for(int i = maxN; i < a.length; i++) { a[i] = i; } // vypis pole System.out.println(Arrays.toString(a)); } } Z kódu je patrné, že není výhodné přidávat často pouze po jednom prvku, ale jednou za čas a větší počet prvků. [zdroj: Dynamické rozšíření pole - PPA2 eBook] Upozornění (informatici): Pokud se však jedná o přidělení paměti, a je přidělen velký úsek paměti, je nevhodné rozšiřovat o 100%, ale přidělit jen úsek potřebné velikosti! Strana 22 (celkem 25)
Praktický příklad použití pole Vytvořte algoritmus pro generování jednoho sloupce tiketu Sportky (např. 6 čísel ze 49 možných). Výstupem bude požadovaný počet různých čísel vybraných počítačem (čísla můžeme vzestupně seřadit). Postup: pro generování čísel použijeme náhodný generátor, nutno ověřovat, zda čísla vkládaná do pole nejsou stejná (nutno vždy porovnat se všemi dosud vygenerovanými čísly v poli – tj. pole neprocházíme celé), pokud nejsou stejná, uložíme vygenerované číslo do pole, pokud jsou stejná, generujeme další číslo a vše opakujeme, dokud jich není požadovaný počet, pak pole seřadíme a vypíšeme.
import java.util.*; public class Sportka { private static Random r = new Random(); public static void main(String [] args){ int pocetVsazenychCisel = 6; int zKolikaCisel = 49; int cisla [] = new int[pocetVsazenychCisel]; int p = -1; // ukazatel pro vkladani do pole cisla int cislo = 0; // promenna pro vygenerovanou hodnotu do { // cyklus pro generovani daného poctu cisel boolean dupl = false; // indikace: cislo neni/je v poli cislo = r.nextInt(zKolikaCisel) + 1; // generovani for (int i=0; i<=p; i++){ // overovani, zda v poli je if(cislo == cisla[i]){ dupl = true; break; // opusteni cyklu for } } if(!dupl){ // nebylo-li tam, vložíme ho cisla[++p] = cislo; } } while(p < pocetVsazenychCisel-1); // dokud nejsou vsechna Arrays.sort(cisla); // javovska knihovni metoda pro razeni System.out.println(Arrays.toString(cisla)); // vypis } }
[6, 17, 19, 22, 27, 35] Strana 23 (celkem 25)
Zajímavý je ještě způsob ověřování duplicity vygenerovaného čísla. Další možností je vytvoření logického pole takové velikosti, kolik je čísel, ze kterých vybíráme. Index v poli bude představovat hodnotu čísla a hodnota v poli bude true, v případě, že číslo již bylo vygenerováno, nebo false, pokud ne. Na začátku tedy budou mít prvky pole hodnotu false (mají ji po vytvoření pole implicitně), vygenerujeme-li nějaké číslo, před vložením hodnoty true na číselný index v poli zkontrolujeme pouze jeden prvek pole a nikoliv všechny dosud vygenerované prvky. Nakonec vložíme hodnoty indexů s hodnotou true do nově vytvořeného pole (délky počtu vsazených čísel), pole máme navíc už seřazené a můžeme jej vypsat.
Upravený kód: import java.util.*; public class SportkaLepe { private static Random r = new Random(); public static void main(String [] args){ int pocetVsazenychCisel = 6; int zKolikaCisel = 49; boolean generovana [] = new boolean [zKolikaCisel+1]; int p = 0; // pocitame vygenerovana cisla do { int cislo = r.nextInt(zKolikaCisel) + 1; if(!generovana[cislo]){ // jeste tam neni generovana[cislo] = true; //je platne p++; // zapocteme ho } } while(p < pocetVsazenychCisel); int cisla [] = new int[pocetVsazenychCisel]; p = 0; // index pro pridavani hodnot for(int i=1; i<=zKolikaCisel; i++){ if(generovana[i]) // je-li tam true cisla[p++] = i; // pridame index(tj. hodnota cisla) } // vypis vzestupne serazeneho pole
}
System.out.println(Arrays.toString(cisla)); } [12, 19, 23, 37, 39, 49] Strana 24 (celkem 25)
Příklad: Poraďte pasáčkovi.
Strana 25 (celkem 25)