Osah 5. přednášky: 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 Tato tematika je zpracována v Záznamy přednášek: str. 91-110 Prolém: Proveďte jednoduchou analýzu zadaného textu (četnost výskytu písmen). Zadání a nástin řešení ude uveden na konci přednášky. Přednášky KIV/PPA1, A. Netrvalová, 2010 5. přednáška
Pole - motivace Úkol zjistit četnost číslic v jednořádkovém textu. int nula = 0; int jedna = 0; int dva = 0;... int osm = 0; int devet = 0; Řešení pomocí přepínače = zdlouhavé, otížná modifikace, např. pro písmena,... NE!!! String text = sc.nextline(); int i=0; while(i<text.length()){ char znak = text.charat(i); if(znak >= '0' && znak <= '9'){ switch (znak){ case '0': nula++; reak; case '1': jedna++; reak; case '2': dva++; reak;... case '8': osm++; reak; case '9': devet++; reak; default: 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 16)
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: tyden = new int [7]; Deklarace a vytvoření současně: datovytyp[] jmenopole = new datovytyp [velikostpole]; Příklad: doule [] teplota = new doule[5]; Inicializace Užitím cyklu: 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 16)
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 [ ] ; V tom 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 16)
Lze přiřadit jedné referenční proměnné pole jinou referenční proměnnou pole, ale tato pole musí ýt stejného typu Po přiřazení pak oě proměnné referencují 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í mezi dvěma poli není v Javě definováno, je řešeno prostřednictvím kopie pole (viz dále). Nyní můžeme použít pole pro již dříve uvedený příklad na výpočet četnosti číslic. Strana 5 (celkem 16)
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 class ForEach { pulic static void main(string[] args) { pulic class ForEach { pulic static void main(string[] args) { int pole [] [] = = {1,2,3,4,5; int int soucet soucet = = 0; 0; for(int i :pole) { for(int i :pole) { soucet += i; soucet += i; System.out.println("soucet = " + soucet); 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 = 15 Strana 6 (celkem 16)
Pole - parametr či návratová hodnota Reference pole může ýt parametrem metody (metoda vypispole()) či návratovou hodnotou (metoda nactipole()) - viz následující příklad. import java.util.*; pulic class PoleParametrANavrat { static private Scanner sc = new Scanner(System.in); static int [] nactipole(int pocet, Scanner sc){ //zde int[] pole = new int [pocet]; for(int i=0; i<pole.length; i++){ System.out.print("Zadej a[" + i + "]: "); pole[i] = sc.nextint(); return pole; static int [] vynulujpole(int [] pole){ // zmena pole for(int i=0; i<pole.length; i++){ pole[i] = 0; return pole; static void vypispole(string s, int [] pole){ //zde for(int i=0; i<pole.length; i++){ System.out.println(s + "[" + i + "] = " + pole[i]);... pokračování na dalším slajdu Strana 7 (celkem 16)
pulic static void main(string[] args) { System.out.print("Zadej pocet prvku: "); int pocetprvku = sc.nextint(); int a [] = new int [pocetprvku]; a = nactipole(pocetprvku, sc); vypispole("a" + a); System.out.println(Arrays.toString(a)); vynulujpole(a); vypispole("a" + a); System.out.println(Arrays.toString(a)); // vypis pole a najednou //System.out.println(Arrays.toString(a)); Změna pole daného parametrem V metodě vynulujpole() jsme nevytvořili nové pole, ale vynulovali pole dané parametrem. Proč to funguje? Protože metoda vynulujpole() dostala referenci na stejné pole, na které ukazuje proměnná a. Kopie polí 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] - použitím cyklu - metodou třídy System arraycopy(zdroj, odzdroj, kopie, odkopie, length); Strana 8 (celkem 16)
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 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++){ druhe[i] = prvni[i]; 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 9 (celkem 16)
Pole reprezentující množinu - pole typu oolean, je-li prvek součástí množiny, má hodnotu true, není-li součástí má hodnotu false Úloha: vypsat všechna prvočísla menší neo rovna zadanému max 2, 3, 5, 7, 11, 13, 17, 19, 23, 29,... 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. Pro reprezentaci množiny čísel použijeme pole prvků typu oolean prvek mnozina[x] ude udávat, zda číslo x v množině je (true) neo není (false) Strana 10 (celkem 16)
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(); Strana 11 (celkem 16)
pulic static void main(string [] args){ oolean [] prvocisla = vytvormnozinu(max); sito(prvocisla); vypisprvocisla(prvocisla); 2, 3, 5, 7, 11, 13, 17, 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ů ([]) Odélníková matice o m řádcích a n sloupcích int m = 3; int n = 4; int [][] matice = new int [m][n]; Inicializace matice int [][] matice = {{1,0,0,{0,1,0,{0,0,1; Rozměry matice matice.length = počet řádků matice[0].length = počet sloupců Strana 12 (celkem 16)
Příklad: 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 12 c 22 32 c 12 22 13 c 23 33 c 13 23 14 c 24 34 c 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 13 (celkem 16)
static int [][] nactimatici(scanner sc, 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 14 (celkem 16)
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(sc, m,n); = nactimatici(sc, n,p); c = vynasomatice(a, ); vypismatici(a); vypismatici(); vypismatici(c); 2 3 4 1 1 1 // A 1 1 1 1 1 1 1 // B 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 // C 3 3 3 3 Strana 15 (celkem 16)
Prolém Proveďte jednoduchou analýzu zadaného textu. První řádek vstupu osahuje kladné celé číslo n (1 n 1000). Toto číslo představuje počet následujících řádek vstupu. Dalších n řádek uď neude osahovat žádný znak neo ude osahovat jeden či více znaků (přípustné jsou i mezery). Tyto řádky tvoří text, který má ýt analyzován. Můžete předpokládat, že písmena se v textu jsou pouze z anglické aecedy. Každý řádek výstupu ude osahovat jedno velké písmeno, následované mezerou a kladným celým číslem, které vyjadřuje počet, kolikrát se toto písmeno ojevilo v textu. Velká a malá písmena jsou považována za totožná. Kromě písmen neudou vyhodnocovány žádné jiné znaky. Písmena musí ýt na výstupu seřazena sestupně podle jejich četnosti výskytu, tzn. nejfrekventovanější písmeno ude na prvním řádku a poslední řádek ude osahovat nejméně frekventované písmeno. Pokud ude existovat více písmen se stejnou frekvencí výskytu, pak udou řazena vzestupně podle aecedy. Pokud se písmeno v textu nevyskytlo, nesmí se ojevit ani na výstupu. Prolém je možno automaticky validovat na: http://uva.onlinejudge.org/ Co je nutno udělat? - registrace, pokud již zaregistrováni nejste - přečíst zadání (10008 What is Cryptanalysis) - napsat zdrojový kód - odevzdat zdrojový kód - pozor třída i souor je nutno pojmenovat Main! - kontrola validace, održíte i validační e-mail Strana 16 (celkem 16)