Cvičenia: 3. týždeň

Cieľom cvičení tretieho týždňa (praktického aj teoretického) je vyskúšať si cykly, metódy vracajúce hodnoty a jednoduchú práci s reťazcami.

Na začiatok

  • Preskúmajte rôzne funkcie, ktoré poskytuje Math (nájdete ich tak, že do Google zadáte Math Java 6).
  • Čo nakreslí nižšie uvedená metóda zahada?
public void zahada() {
        for (int i=0; i<256; i++) {
                Color c = new Color(i, 100, 100);
                this.setPenColor(c);
                this.setPosition(i, 0);
                this.moveTo(i, 150);
        }
}
Nájdite v tejto metóde miesto, kde sa vytvorí objekt triedy Color. Koľko parametrov ma použitý konštruktor? Akého typu je premenná c?
  • Do triedy MojaKorytnacka pridajte metódu, ktorá nastaví náhodnú farbu kresliaceho pera.
  • Do triedy MojaKorytnacka pridajte metódu sustredneKruhy s parametrom polomer, ktorá nakreslí "nekonečnú" postupnosť vnorených sústredných kruhov. "Nekonečnú" znamená, že útvary, ktoré nie je vidieť, už nekreslíme. Prvý (najväčší) kruh nech má polomer určený parametrom polomer. Každý ďalší (vnorený) kruh, nech má polomer, ktorý je 80% z polomeru toho predošlého. Farby kruhov nech sa postupne cyklicky striedajú: červená, modrá, šedá.
public void sustredneKruhy(double polomer) {

}
  • Upravte predošlú metódu tak, aby vrátila súčet obsahov skutočne nakreslených kruhov.

Korytnačie počty

  • Vytvorte triedu Poctarka rozširujúcu triedu Turtle s nasledujúcimi metódami:
    • min vráti menšie z čísel cislo1 a cislo2
    • mocnina vypočíta nk
    • faktorial vypočíta n!
    • pocetDelitelov vráti počet celočíselných deliteľov čísla n
    • jePrvocislo vráti, či je číslo n prvočíslom
    • pocetCifier vráti počet cifier čísla n
    • nerastuceCifry - vráti, či cifry čísla tvoria nerastúcu postupnosť. Cifry čísla 44220 tvoria nerastúcu postupnosť, ale čifry čísla 2231 nie (3 je väčšie ako naľavo od neho nachádzajúca sa cifra 2)
    • maCifru - vráti, či zápis čísla n obsahuje cifru c
    • NSD vráti najväčšieho spoločného deliteľa čísel a a b (neskôr sa naučíme aj efektívny Euklidov algoritmus)
    • NSN vráti najmenší spoločný násobok čísel a a b
public double min(double cislo1, double cislo2)
public long mocnina(int n, int k)
public long faktorial(int n)
public int pocetDelitelov(int n)
public int pocetCifier(int n)
public boolean jePrvocislo(int n)
public boolean maCifru(byte c, int n)
public boolean nerastuceCifry(int n)
public int NSD(int a, int b)
public int NSN(int a, int b)

Korytnačka vo svete znakových reťazcov

  • Na čo slúžia objekty triedy String? Akou metódou nám objekt triedy String vie povedať dĺžku reťazca, ktorý uchováva? Akým spôsobom sa vieme objektov triedy String "pýtať" na jednotlivé znaky reťazca?
  • Čo je to referencia? Čo znamená, že parametrom metódy je referencia na objekt nejakej triedy (napr. String)?
  • Vytvorte triedu Znakarka rozširujúcu triedu Turtle s nasledujúcimi metódami:
    • pocetVyskytov vráti počet výskytov znaku znak v reťazci referencovanom parametrom s
    • jePalindrom vráti, či reťazec referencovaný parametrom s je palindróm, t.j. číta sa rovnako zľava doprava ako aj zprava doľava: abcba, accaacca sú palindrómy
    • maDvojmedzeru vráti, či reťazec referencovaný parametrom s obsahuje 2 za sebou idúce medzery
public int pocetVyskytov(String s, char znak)
public boolean jePalindrom(String s)
public boolean maDvojmedzeru(String s)

Ďalšie úlohy

  • Naučte korytnačky triedy MojaKorytnacka metódu pomalyStep, ktorá spraví to isté, čo step, ale krok korytnačky bude zložený z malých spomalených krôčikov. Vznikne tak efekt plynulého kreslenia čiar. Metóda nech má 2 parametre: dĺžka, o ktorú sa ma korytnačka posunúť, a rýchlosť, akou sa má korytnačka posunúť v pixeloch za sekundu. Pre pekný efekt animácie pripravte pohyb tak, že za každým malým krôčikom korytnačka zastaví na 50 milisekúnd (1 sekunda / 24 obrázkov je asi 50 ms).
  • Naučte korytnačky triedy Hrac metódu biliard, ktorá bude realizovať nasledovný algoritmus:
    • korytnačka príkazom this.setRangeStyle(RangeStyle.BOUNCE); nastaví, aby sa odrážala od hranice kresliaceho plátna
    • korytnačka na náhodných súradniciach nakreslí čierny kruh (dieru) s polomerom 10. X-ová aj Y-ová súradnica kruhu nech je náhodné číslo z intervalu <20, 280) (predpokladáme štandardnú kresliacu plochu s rozmermi 300 x 300).
    • kým sa korytnačka nedostane do vnútra vygenerovaného čierneho kruhu (diery) jej pohyb sa riadi týmito pravidlami:
      • každý krok korytnačky je krok aktuálnym smerom dĺžky 3 (za každým krokom pozastavíme program na pár milisekúnd napr. príkazom JPAZUtilities.delay(50))
      • každých 300 krokov sa korytnačka náhodne otočí
public void biliard()

Pre fajnšmekrov

  • Do triedy Poctarka pridajte metódu najCifra, ktorá vráti najväčšiu cifru v zadanom čísle.
  • Kalkulačka sa nám pokazila a jediné operácie, ktoré dokáže zrealizovať sú pripočítanie jednotky k poslednému výsledku (číslu na displeji) a vynásobenie posledného výsledku dvomi. Na začiatku je displeji číslo 0. Vytvorte metódu (v triede Poctarka), ktorá pre zadané číslo vráti minimálny počet operácii, ktoré musíme vykonať, aby sme na displeji zobrazili parametrom zadané číslo n.

Math.pow?

Math.pow je užitočná metóda na vyrátanie mocniny čísla s desatinnou čiarkou. Konkrétne Math.pow(a, b) vráti ab. Všimnime si však jej hlavičku:

double Math.pow(double a, double b)

Keďže exponent je typu double, túto metódu môžeme použiť aj na vypočítanie neceločíselných mocnín. Príklad: Math.pow(3.5, 0.25) vypočíta štvrtú odmocninu z čísla 3.5.

To, že táto metóda pracuje s číslami s desatinnou čiarkou, je tak jej silnou stránkou, ale pri nevhodnom použití aj slabou stránkou. Totiž čísla s desatinnou čiarkou majú limitovanú presnosť.

Príkladom nevhodného použitia tejto metódy je počítanie celých mocnín celých čísel. Vyskúšajte tento kód (napr. v metóde main triedy Spustac):

int a = 13;
int b = 15;

// Klasický výpočet násobením
long vysledok = 1;
for (int i = 0; i < b; i++) {
        vysledok = vysledok * a;
}
System.out.println(vysledok);

// Výpočet s využitím Math.pow a pretypovania
vysledok = (long) Math.pow(a, b);
System.out.println(vysledok);

Pre doplnenie 1315 = 51185893014090757, čo je menej ako maximálna hodnota pre long 9223372036854775807, t.j. nedôjde tu k pretečeniu.