Osah 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 int jedna = 0; int dva = 0;... int osm = 0; int devet = 0; // reprezentuji citace vyskytu cislic Řešení pomocí přepínače = Toto zdlouhavé, je sice funkční, otížná modifikace, ale ne efektivní! Takto např. nedělat!!! pro písmena, (lépe... NE!!! viz slide 19) String text = sc.nextline(); // nacteni textu (radky) int i=0; while(i<text.length()){ // dokud jsou nezpracovane znaky char znak = text.charat(i); // prirad i-ty znak retezce if(znak >= '0' && znak <= '9'){ switch (znak){ // pouzitim prepinace case '0': nula++; reak; case '1': jedna++; reak; case '2': dva++; reak; //... case '8': osm++; reak; case '9': devet++; reak; default: /* System.out.println("Chya"); */ reak; 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); d123y 662098 0: 1 1: 1 2: 2 3: 1 4: 0 5: 0 6: 2 7: 0 8: 1 9: 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: liovolný, 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 ojektem) 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: doule[]teplota = new doule[5]; Inicializace proměnná udávající počet prvků pole - užitím cyklu: teplota for (int i = 0; i < teplota.length; i++) teplota[i] = 37 + (doule)i/10; - výčtem hodnot: doule [] teplota = {37.0, 37.1, 37.2, 37.3, 37.4; Strana 3 (celkem 25)
Mechanismus vytváření pole, reference Deklarace má tento efekt: int [ ] a = new int[3]; lokální proměnné a se přidělí paměťové místo v zásoníku, které však neosahuje 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é olasti rezervuje (alokuje) úsek potřený 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á, chyí ještě počet prvků. Pozor: referenční proměnnou lze deklarovat i ez vytvoření pole int [] ; null V tomto případě se zavede referenční proměnná, která má nedefinovanou hodnotu, jde-li o lokální proměnnou, neo 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í ýt stejného typu. Po přiřazení oě 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 alíčku util (viz dále). Strana 5 (celkem 25)
Příklad: Pole - deklarace, inicializace, vytvoření pulic class PoleVytvoreni { static int [] ; // inicializace: null static int [] c = {1, 0, 7, 4, 5; // inicializace pulic static void main (String [] args){ System.out.println("c = " + Arrays.toString(c)); System.out.println(" = " +Arrays.toString()); int [] a ; // reference, chyi incializace //System.out.println(Arrays.toString(a)); // nelze a = null; // ALE POZOR!!! System.out.println("ref c:" + c); // kam ukazuje System.out.println("ref :" + ); 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] = null ref c:[i@1d9742 ref :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.*; pulic class CetnostCislicPole { static private Scanner sc = new Scanner(System.in); pulic static void main(string[] args) { int cetnost [] = new int[10]; String s = sc.nextline(); int k=0; while(k<s.length()) { char znak = s.charat(k++); if(znak >= '0' && znak <= '9'){ cetnost[(znak - (int)'0')]++; for (int i=0; i<cetnost.length; i++) { System.out.println(i + ": " + cetnost[i]); Poznámka: příkaz for each přístup postupně ke všem prvkům pulic pulic class class ForEach { { pulic pulic static static void void main(string[] args) { int pole int pole [] = []{1,1,1,1,1; = {1,2,3,4,5; int soucet int soucet = 0; = 0; for(int for(int i :pole) i :pole) { { soucet soucet += += i; i; System.out.println("soucet = " + soucet); Toto je ok! 110w2 t3383g476 0: 1 1: 2 2: 1 3: 3 4: 1 5: 0 6: 1 7: 1 8: 1 9: 0 System.out.println("soucet = " + soucet); soucet = 15 soucet = 5 Strana 7 (celkem 25)
Pole - parametr či návratová hodnota Reference pole může ýt: - parametrem metody (metoda vypispole()) - návratovou hodnotou (metoda nactipole()) Příklad import java.util.*; pulic 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 [" + 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)
pulic static void main(string[] args) { System.out.print("Zadej pocet prvku: "); int pocetprvku = sc.nextint(); int a [] = new int [pocetprvku]; a = nactipole(pocetprvku); // nacti(a); // dalsi moznost vypispole("a", a); System.out.println(Arrays.toString(a)); vynulujpole(a); vypispole("a", a); System.out.println(Arrays.toString(a)); // tj. vypis pole a najednou Změna pole daného parametrem V metodě vynulujpole() jsme nevytvořili nové pole, ale vynulovali pole dané parametrem, odoně 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 Zadej pocet prvku: 3 Zadej a[0]: 1 Zadej a[1]: 2 Zadej a[2]: 3 a[0] = 1 a[1] = 2 a[2] = 3 [1, 2, 3] a[0] = 0 a[1] = 0 a[2] = 0 [0, 0, 0] - metodou třídy System arraycopy(zdroj, odzdroj, kopie, odkopie, length); Strana 9 (celkem 25)
Příklad: různé způsoy 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.*; pulic class KopiePoli{ pulic 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.*; pulic 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 doule spoctiprumernouvysku(int [] pole){ int s = 0; for(int i=0; i<pole.length; i++){ s += pole[i]; return (doule)s/pole.length; static int urcipocetvyskovenadprum(int []pole, int prumer){ int pocet = 0; for(int i=0; i<pole.length; i++){ if(pole[i]>prumer){ pocet++; return pocet; pulic static void main(string[] args) { System.out.print("Zadej pocet modelek: "); int pocetmodelek = sc.nextint(); System.out.println("Zadej jednotlive vysky: "); int vysky[] = nactivysky(pocetmodelek); Zadej pocet modelek: 10 Zadej jednotlive vysky: 159 180 178 156 183 185 181 179 175 173 Prumerna vyska: 174 Pocet s nadprumernou vyskou: 7 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: Samooslužný výčep - evidence spotřey piva import java.util.*; pulic class Hospoda { static private Scanner sc = new Scanner (System.in); static doule spoctispotreupiva(doule [] stul) { doule spotrea = 0; for(int i=0; i<stul.length; i++){ spotrea += stul[i]; return spotrea; pulic static void main(string [] args){ sc.uselocale(locale.us); doule [] stul1 = new doule[2]; doule [] stul2 = new doule[4]; doule [] stul3 = new doule[6]; System.out.print("Nacti spotreu piva u stolu 1: "); for(int i=0; i<stul1.length; i++){ stul1[i] = sc.nextdoule(); System.out.print("Nacti spotreu piva u stolu 2: "); for(int i=0; i<stul2.length; i++){ stul2[i] = sc.nextdoule(); System.out.println("Vypis spotreu piva u stolu 1"); System.out.print(Arrays.toString(stul1)); System.out.println(" = " + spoctispotreupiva(stul1)); System.out.println("Vypis spotreu piva u stolu 2"); System.out.print(Arrays.toString(stul2)); System.out.println(" = " + spoctispotreupiva(stul2)); Nacti spotreu piva u stolu 1: 1 2 Nacti spotreu piva u stolu 2: 2 3 1 4 Vypis spotreu piva u stolu 1 [1.0, 2.0] = 3.0 Vypis spotreu piva u stolu 2 [2.0, 3.0, 1.0, 4.0] = 10.0 Vypis spotreu piva celkem 1: [1.0, 2.0] 2: [2.0, 3.0, 1.0, 4.0] 3: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Celkova spotrea = 13.0 System.out.println("Vypis spotreu piva celkem"); System.out.println("1: " + Arrays.toString(stul1)); System.out.println("2: " + Arrays.toString(stul2)); System.out.println("3: " + Arrays.toString(stul3)); doule celkem = spoctispotreupiva(stul1) + spoctispotreupiva(stul2) + spoctispotreupiva(stul3); System.out.println("Celkova spotrea = " + celkem); Strana 12 (celkem 25)
Pole reprezentující množinu - pole typu oolean - 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ší neo rovna zadanému max Prvočíslo - přirozené číslo, které je dělitelné (eze zytku) právě dvěma různými přirozenými čísly, a to číslem jedna a seou 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 2 N -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 osahující přirozená čísla od čísla 2 do max. Z množiny vypustíme všechny násoky čísla 2. Najdeme nejližší číslo k tomu, jehož násoky jsme v předchozím kroku vypustili, a vypustíme všechny násoky tohoto čísla. Opakujeme předchozí krok tak dlouho, dokud číslo, jehož násoky jsme vypustili, není větší než max. Čísla, která v množině zůstanou, jsou hledaná prvočísla. Časová složitost algoritmu: ukázat (orázek) ěh algoritmu pro max=20 O(N*log(log N)), kde N je horní mez rozsahu Pro reprezentaci množiny čísel použijeme pole prvků typu oolean Prvek pole mnozina[x] ude udávat, zda číslo x: - v množině je (true) - v množině není (false) Strana 14 (celkem 25)
pulic class Sito { static final int MAX = 17; static oolean [] vytvormnozinu (int max){ oolean [] mnozina = new oolean [max+1]; for(int i=0; i< mnozina.length; i++){ mnozina[i] = true; return mnozina; static void sito (oolean [] 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 (oolean [] mnozina){ for(int i=2; i<mnozina.length; i++){ if(mnozina[i]){ System.out.print(i + ", "); System.out.println(); pulic static void main(string [] args){ oolean [] prvocisla = vytvormnozinu(max); sito(prvocisla); vypisprvocisla(prvocisla); 2, 3, 5, 7, 11, 13, 17, Strana 15 (celkem 25)
Příklad: Oraťte v tomtéž poli pořadí hodnot prvků. Počet <1,10> i hodnoty <-15,15> prvků vygenerujte náhodně. import java.util.*; pulic class OraceniPole { private static Random r = new Random(); static final int MAX_HODNOTA =15; static void oratpole(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; pulic static void main(string[] args) { int[] vstupnipole = naplnpole(); System.out.println(Arrays.toString(vstupniPole)); oratpole(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 [0] 2 4 0 1 1 8 0 1 pole [2] 2 9 1 3 0 1 2 3 null null 0 1 2 3 4 $ 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: Odé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; Př.: Součin matic a a a a 11 21 11 21 11 11 a a 12 22 a a 12 22 a a 13 23 21 21 a a 13 23 11 21 31 31 31 c c 12 22 32 12 22 c c 13 23 33 13 23 c c 14 24 34 14 24 import java.util.*; pulic 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 [][] = {{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 [][] vynasomatice(int[][] a, int [][] ){ int [][] c = new int[a.length][[0].length]; for (int i = 0; i < a.length; i++) { for (int j = 0; j < [i].length; j++) { int s=0; for (int k = 0; k < a[i].length ; k++){ s += a[i][k] * [k][j]; c[i][j] = s; return c; Strana 19 (celkem 25)
pulic static void main(string[] args) { int m = sc.nextint(); int n = sc.nextint(); int p = sc.nextint(); int [][] a = new int [m][n]; int [][] = new int [n][p]; int [][] c = new int [m][p]; a = nactimatici(m,n); = nactimatici(n,p); c = vynasomatice(a, ); vypismatici(a); vypismatici(); vypismatici(c); 2 3 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 A B C Poznámka: Ochrana před použitím indexu mimo rozsah pole Použít příkaz assert assert (index>=0 && index<a.length): "\nchya: index = " + index + " je mimo meze: [0.." + a.length + "]"; Podroněji o ladění programů - na přednášce č. 7 Strana 20 (celkem 25)
Dynamické rozšiřování pole* Před započetím práce s polem určení velikosti Komplikace udoucí potřea 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 ude referencováno též proměnnou x a na proměnné a vytvoříme větší pole, např. dvakrát tak velké jako ylo pole původní. Hodnoty prvků pole a jsou teď implicitně nastaveny na 0 (pole je ojekt). Původní hodnoty tudíž zkopírujeme z pole x. Pro ilustraci přiřadíme hodnoty i ostatním prvkům pole a. a x 0 1 2 3 x 0 1 2 3 a 0 1 2 3 4 5 6 7 Strana 21 (celkem 25)
Ilustrace postupu: pulic class DynamickePole { import java.util.*; pulic 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 dvojnasoek 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řené 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 ude požadovaný počet různých čísel vyraný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.*; pulic class Sportka { private static Random r = new Random(); pulic 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 oolean 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; reak; // opusteni cyklu for if(!dupl){ // neylo-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ůso ověřování duplicity vygenerovaného čísla. Další možností je vytvoření logického pole takové velikosti, kolik je čísel, ze kterých vyíráme. Index v poli ude představovat hodnotu čísla a hodnota v poli ude true, v případě, že číslo již ylo vygenerováno, neo false, pokud ne. Na začátku tedy udou 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.*; pulic class SportkaLepe { private static Random r = new Random(); pulic static void main(string [] args){ int pocetvsazenychcisel = 6; int zkolikacisel = 49; oolean generovana [] = new oolean [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)