Programovanie (2) v Jave
1-INF-166, LS 2017/18

Úvod · Pravidlá · Prednášky · Netbeans · Testovač · Test a skúška
· Vyučujúcich môžete kontaktovať pomocou e-mailovej adresy E-prg.png (bude odpovedať ten z nás, kto má príslušnú otázku na starosti alebo kto má práve čas).
· DÚ10 je zverejnená, odovzdávajte do stredy 16.5. 22:00.
· Bonusový projekt odovzdávajte do pondelka 21.5. 22:00 na testovači. Predvádzanie projektov bude po prvom termíne skúšky v stredu 23.5. (t.j. začneme medzi 11:45 a 12:00 v H6). Ak vtedy nemôžete prísť, kontaktujte vyučujúce, dohodneme iný termín.
· Opravný/náhradný test bude v pondelok 28.5. o 10:00 v F1-108. V prípade záujmu sa prihláste v AISe.
· Na termíny skúšok sa zapisujte v AIS. Termíny: streda 23.5. (riadny), štvrtok 7.6. (riadny alebo 1. opravný), streda 20.6. (1. alebo 2. opravný) plus v prípade potreby ešte jeden termín v poslednom týždni skúškového. Prípadné konflikty nám dajte vedieť čím skôr. Ďalšie informácie na stránke Test a skúška.


Cvičenia 17

Z Programovanie
Prejsť na: navigácia, hľadanie

Na testovači je príklad za jeden bonusový bod, ktorý sa dá odovzdávať do 22:00. Okrem toho riešte ďalšie príklady z tohto cvičenia, prípadne sa vráťte aj k príkladom z minulého týždňa.

Index riadkov

Na prednáške sme mali program, ktorý pomocou HashMap<String,Integer> spočítal počty výskytov slov na vstupe. Teraz chceme zmenenú verziu tohto programu, ktorá vypíše zoznam slov a pre každé slovo zoznam čísel riadkov, na ktorých sa toto slovo nachádza. Slová budú usporiadané podľa abecedy, riadky vzostupne. Ak je slovo na riadku viackrát, uvedie sa toto číslo iba raz. Odporúčame použiť TreeMap<String,TreeSet<Integer>>. Kostra nižšie už rozkladá vstup na riadky a riadky na slová.

Príklad vstupu a výstupu (vstup sú prvé tri riadky):

jeden dva tri jeden
jeden styri tri

Slovo dva sa vyskytuje na riadkoch: 1
Slovo jeden sa vyskytuje na riadkoch: 1 2
Slovo styri sa vyskytuje na riadkoch: 2
Slovo tri sa vyskytuje na riadkoch: 1 2

Kostra programu:

import java.util.*;
import java.io.*;  
public class Prog {
   public static void main(String[] args) throws IOException {

       //TODO: VAS KOD NA INICIALIZACIU MAPY TU

	BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

	int lineNumber = 0;  // pocitadlo cisel riadkov
	while (true) {
            // nacitame riadok do retazca
            String line = in.readLine();
            // skoncime, ked uzivatel zada prazdny riadok 
	    // alebo ked prideme na koniec vstupu (null)
            if (line == null || line.equals("")) { 
                break;
            }
	    lineNumber ++;

	    // inicializujeme scanner, ktory rozlozi riadok na slova
	    Scanner scanner = new Scanner(line);
	    while(scanner.hasNext()) {
		String word = scanner.next();
		// TODO VAS KOD NA SPRACOVANIE SLOVA TU

	    }
        }

	// TODO: VAS KOD NA VYPIS VYSLEDKU TU
   }
}

Metódy equals, hashCode, compareTo

Napíšte triedu Zlomok, ktorá bude implementovať zlomok s celočíselným čitateľom a menovateľom.

  • Triede spravte konštruktor a preťažte equals tak, aby správne testovala rovnosť zlomkov a hashCode tak, aby bol konzistentný s equals.
  • Vaša trieda by tiež mala implementovať interface Comparable s bežným porovnaním zlomkov podľa veľkosti.
  • Prekryte aj metódu toString aby vrátila reťazec typu "a/b"
  • Skúšajte zlomky vkladať do TreeSet a HashSet a skontrolujte, že dostávate správne výsledky.
  • Pre jednoduchosť môžete predpokladať, že čitateľ aj menovateľ sú kladné a že nedôjde k pretečeniu rozsahu čísla typu Integer pri aritmetických operáciách.
  • Môže sa vám zísť Euklidov algoritmus na nájdenie najväčšieho spoločného deliteľa:
    // ratame nsd(a,b)
    while(b != 0) {
        int x = a % b;
        a = b;
        b = x;
    }
    // vysledok je v premennej a

Generické statické metódy

  • Napíšte generickú statickú metódu prienik, ktorá dostane dve SortedSet (s tým istým typom prvkov E) a vráti SortedSet obsahujúcu ich prienik, t.j. prvky, ktoré sa nachádzajú v oboch.
    • Najskôr funkciu naprogramujte pomocou iterácie cez jednu vstupnú množinu a volaním contains na druhú.
    • Komplikovanejší ale efektívnejší program dostanete použitím iterátorov na obe množiny, ktoré budete postupne posúvať algoritmom podobným na merge (iterátory pre SortedSet vracajú prvky v utriedenom poradí).
      • Potrebujete si tiež pamätať aktuálny prvok z každej množiny, lebo po volaní next sa už späť k tomu istému prvku nedostanete.

Metóda remove

Trieda ArrayList (ale aj LinkedList a iné triedy implementujúce List) má dve metódy s menom remove, ale s iným typom parametra

Úloha:

  • Zistite experimentovaním, ktorá z metód remove sa vykoná v nasledujúcom kóde.
  • Zmeňte kód tak, aby sa zavolala opačná forma metódy remove.

Pozor, podobná zámena metód môže byť zdrojom zákernej chyby v programe.

import java.util.ArrayList;
public class Prog {
    public static void main(String[] args) {
        Integer[] tmp = {3,2,1};
        ArrayList<Integer> a = new ArrayList<Integer>(Arrays.asList(tmp));
        System.out.println("Pred remove:" + a);
        a.remove(1);
        System.out.println("Po remove: " + a);

    }
}