Helsingin yliopisto / Tietojenkäsittelytieteen laitos / 581326-3 Java-ohjelmointi
Copyright © 2008 Arto Wikla. Tämän oppimateriaalin käyttö on sallittu vain yksityishenkilöille opiskelutarkoituksissa. Materiaalin käyttö muihin tarkoituksiin, kuten kaupallisilla tai muilla kursseilla, on kielletty.

Java-ohjelmointi, harjoitukset 5.6.- 19.6.

Kaikki ohjelmointitehtävät on tarkoitus tehdä tietokoneella!

1. harjoitukset to 5.6.

Nämä ensimmäiset harjoitukset kertaavat Ohjelmoinnin perusteet -kurssin sisältöä. Tehtävät samalla myös esittelevät Java-ohjelmointi-kurssinn esitietovaatimuksia... Tämän verran siis Javaa oikeastaan on osattava jo ennen tätä kurssia! Eivät nämä tehtävät toki ihan helppoja ole Ohjelmoinnin perusteet -kurssin juuri suorittaneillekaan!

Aiheita: matriiseja, suunnittelua ja toteustusta, olioita taulukon alkioina, peruskäsitteitä, ...

  1. [Tämä tehtävä liittyy Ohjelmoinnin perusteet -kurssin oppimateriaalin lukuun 2.8 Taulukko-olioista]
    Laadi yksityisiä luokkametodeja ("pääohjelman pikku apulaisia"), jotka saavat parametrina kokonaislukumatriisin, jonka tyyppi on int[][]. Varaudu myös 0:n alkion kokoisiin taulukoihin. Metodi
    1. etsii matriisin alkoista arvoltaan suurimman ja palauttaa sen arvonaan; jos matriisi sisältää nolla alkiota, metodi palauttaa arvon nolla (tämä tapa viestiä tyhjästä matriisista voi olla harhaanjohtava, miksi?)
    2. asettaa matriisin jokaisen alkion arvoksi indeksien erotuksen (esimerkiksi alkio, jonka indeksit ovat [2][4] saa arvokseen -2)
    3. selvittää, löytyykö parametrina annettu luku matriisista; jos löytyy, metodi palauttaa arvon true, muuten false

  2. [Tämä tehtävä liittyy Ohjelmoinnin perusteet -kurssin oppimateriaalin lukuun 2.6 Luokista ja olioista]
    Luokan Opiskelija määrittely alkaa seuraavasti:
    public class Opiskelija {
    
      private String etunimi;
      private String sukunimi;
      private int koepisteet;       // saa olla vain 0-50
      private int harjoituspisteet; // saa olla vain 0-10
    
      public Opiskelija(String etunimi, String sukunimi) {
        this.etunimi = etunimi;
        this.sukunimi = sukunimi;
        this.koepisteet = 0;
        this.harjoituspisteet = 0;
      }
      //---------------------------
      public String getEtunimi() {
        return this.etunimi;
      }
      public String getSukunimi() {
        return this.sukunimi;
      }
      public int getPistesaalis() {
        return this.koepisteet + this.harjoituspisteet;
      }
      //---------------------------
      ...
    
    Täydennä luokkaa metodein

    Voit ohjelmoida luokkaan muitakin hyödyllisiä metodeita.

    Havainnollista Opiskelija-olioiden käyttötapaa luokkaan sijoitettavalla pääohjelmalla.

    Huom: Asettavat ja ottavat aksessorit on nimetty Javan omassa kalustossa hyvin johdomukaisesti etuliitteillä "set" ja "get", esim. setValue, getValue. Asettavalle aksessorille luonteva suomalainen nimeämistapa olisi asetaArvo, mutta hyvää ottavan aksessorin nimeä on vaikeampi keksiä: otaArvo, annaArvo, haeArvo, ... Mikään noista ei ole kovin hyvä. Tässä tehtävässä käytetty englannin ja suomen sekoittaminenkin voi jotakuta häiritä. Pohdi asiaa. Mikä olisi mielestäsi paras ja selkein tapa?

  3. Käytetään edellisen tehtävän luokkaa: Määrittely
    
        Opiskelija[] opiskelijat = new Opiskelija[9];
    
    asettaa muuttujan arvoksi yhdeksänalkioisen taulukon, jonka alkiot voivat saada arvokseen Opiskelija-olioita. Esimerkiksi lause
        opiskelijat[6] = new Opiskelija("Pekka", "Puupää");
    
    
    asettaa taulukon seitsemännen alkion arvoksi sellaisen Opiskelija-olion, jolle
       opiskelijat[6].getEtunimi() 
    
    on arvoltaan "Pekka" ja
       opiskelijat[6].getPistesaalis()
    
    on alkuarvoltaan 0

    Laadi sovellus, joka pyytää opiskelijoiden tiedot ja tulostaa ne pistejärjestyksessä arvosanoineen. Saman pistemäärän saaneet opiskelijat tulostetaan "aakkosjärjestyksessä". Käytä järjestämisen perusteena Opiskelija-luokan metodia compareTo. Toteuta tietojen kysely, järjestäminen ja tulostaminen yksityisinä luokkametodeina, "pääohjelman pikku apulaisina".

    Tulostuksen ulkoasu on seuraavanlainen:

    Tulos   Nimi
    
    5  50   Juonio, Jussi
    5  50   Mainio, Matti
    4  46   Vemmelsääri, Väiski
    3  42   Ankka, Aku
    3  42   Ankka, Taavi
    3  40   Puupää, Pekka
    2  39   Hirmuinen, Harald
    1  31   Hopo, Hessu
    0  15   Lipponen, Pekka
    
    

  4. Selvitellään vähän käsitteitä! (Copyright © Joni Salmi)
    Ovatko seuraavat väitteet totta vai tarua?
    1. Kommentit ovat turhia kääntäjälle.
    2. Kommentit ovat turhia.
    3. Ohjelmakoodin sisentäminen on turhaa kääntäjälle.
    4. Ohjelmakoodin sisentäminen on turhaa.
    5. Arvolla on aina tyyppi.
    6. Muuttujalla on aina tyyppi.
    7. Muuttujaan on aina sijoitettu arvo.
    8. Arvo on aina sijoitettu muuttujaan.
    9. Muuttujan voi esitellä sijoittamatta siihen arvoa.
    10. Esittelemättömään muuttujaan voi sijoittaa arvon.
    11. 3.14 on arvo.
    12. 3.14 on tyyppi.
    13. 3.14 on muuttuja.
    14. int-tyyppisen muuttujan arvo voi olla negatiivinen.
    15. double tarkoittaa kaksoistarkkuuden liukulukutyyppiä.
    16. double-tyyppisen muuttujan arvo voi olla negatiivinen.
    17. Kaksoistarkkuuden liukuluku on suunnilleen sama asia kuin desimaaliluku.
    18. Totuusarvoinen muuttuja voi saada arvokseen vain luvun nolla tai yksi.
    19. Lausekkeilla on aina arvo.
    20. Lausekkeilla on aina tyyppi.
    21. Lauseilla on aina arvo.
    22. Lauseilla on aina tyyppi.

2. harjoitukset ma 9.6.

Aiheita: syötön ja tulostuksen ohjaamista, varottavia esimerkkejä, omia työkaluja, taulukko olion kenttänä, ... i/o:n kertausta, merkkien käsittelyä, käsitteiden tarkentamista

  1. Unix/Linux-ympäristössä ja Windowsin DOS-ikkunassa ohjelman syöttötiedot voidaan lukea näppäimistön sijaan tiedostosta, kun käytetään ns. standardisyöttövirran uudelleenohjausta:
         java Ohjelma < tiedosto
    
    Samoin ohjelman tulosteet voidaan ohjata tiedostoon kuvaruudun sijasta:
         java Ohjelma > tiedosto
    
    Myös molemmat voidaan tehdä:
         java Ohjelma < tiedosto1 > tiedosto2
    

    Laadi ohjelma Humanisoi, joka tekee syöttötiedostosta sellaisen kopion, jossa jokainen numeromerkki on korvattu kauniilla tähtimerkillä '*'. Ohjelma suoritetaan komennolla:

         java Humanisoi < alkuteksti.txt > humanoitu.txt
    

    Vihjeitä

  2. Olkoon int a = -3; ja int i = 5;

    Selvitä i:n ja a:n arvo seuraavien sijoituslauseiden jälkeen. Ajatellaan että lauseet suoritetaan erillisinä, ei peräkkäin. Mitään muuta ei tehdä määrittelyiden ja lauseen välissä. Varaudu selittämään miksi arvot muodostuvat sellaisiksi kuin muodostuvat, älä tyydy vain selvittämään arvoja tietokoneella.

            a)      a = ++i;
            b)      a = i++;
            c)      a = --i;
            d)      a = i--;
            e)      a += i++;
            f)      a *= ++i + i++;
            g)      a += i++ - --i;
            h)      a -= (i++ - --a) + (++a + i--);
            i)      a += (i = ++a) - (a -= i--);
    
    
    Mitä mieltä olet tällaisesta ohjelmoinnista? Tämä tehtävä on kuin rokotus; sen on tarkoitus tuottaa "vasta-aineita", jotta tuollainen ohjelmointityyli ei pääsisi jatkossa vaivaamaan...

  3. & 8.
    [Tämä tehtävä liittyy Ohjelmoinnin perusteet -kurssin oppimateriaalin lukuihin 2.7 String-olioita ja char-arvoja ja 2.8 Taulukko-olioista]

    Kun jokin ohjelmointikielen väline vaikuttaa helppokäyttöiseltä ja joustavalta, kyseessä on se, että joku jossakin on toteuttanut, ohjelmoinut, tuon helppouden! Eikä se välttämättä ole ollut helppoa...

    Luokassa String on monenlaisia välineitä merkkijonojen käsittelyyn. Kerran luotu String-olio tunnetusti ei kuitenkaan voi koskaan muuttua, ne ovat synnyttyään muuttumattomia, "immutaabeleita". Ohjelmoi ja testaa oma merkkijonoluokka OmaString muutettavien merkkijononojen toteutukseksi. Tehtävän ratkaisemisessa on pyrittävä välttämään roskienkerääjän ylensyöttämistä. Itse asiassa Java-APIssa on luokat StringBuilder ja StringBuffer muutettavien merkkijonojen käsittelyyn, mutta asioiden tekeminen omin käsin on opettavaista!

    Luokan OmaString määrittely alkaa:

     public class OmaString {
    
       public static final int MAKSIMIPITUUS = 100; // pisin sallittu merkkijono 
                                                    // ("final" tarkoittaa vakiota);
                                                    // tätä voi kysyä luokan ulkopuolelta
                                                    // OmaString.MAKSIMIPITUUS
    
       private char[] mjono; // merkkijononon esitys char-taulukkona
       private int pituus;   // montako alkioita mjono:n alusta on käytössä
       ...
    
    Luokassa on konstruktorit:

    Luokka tarjoaa aksessorit:

    Kirjoita pääohjelma, joka esittelee monipuolisesti OmaString-olioiden käyttöä.

3. harjoitukset ke 11.6.

Aiheita: luokkia ja kenttiä, luokkamuuttujia ja ilmentymämuuttujia, mallinnusta, suunnittelua

  1. Alkueläin on yksinkertainen, mutta silti hyvin yksilöllinen olento. Jokaisella alkueläimellä on yksikäsitteinen syntymässä saatu järjestysnumero, ns. yksilöllisyys, joka ei koskaan voi muuttua, eikä kukaan muu voi koskaan saada samaa yksilöllisyyttä.

    Alkueläimen perimä muodostuu kolmestakymmenestä nukleotidistä, joista kukin voi olla arvoltaan 'A', 'C', 'G' tai 'T'. Alkueläin lisääntyy joko jakautumalla tai pariutumalla toisen alkueläimen kanssa. Jakautumalla syntynyt alkueläin on yksilöllisyyttään lukuunottamatta täydellinen kopio vanhemmastaan. Pariutumalla syntynyt alkueläin perii vanhempiensa perimien yhdistelmän siten, että kunkin nukleotidin kohdalla molempien vanhempien nukleotidi on yhtä todennäköinen (=0.5). Toisinaan alkueläimen perimään voi tapahtua myös mutaatio, joka muuttaa alkueläimen yhden nukleotidin toiseksi.

    Mallinna alkueläin luokkana Alkuelain.

    Yksilöllisyyden voi toteuttaa siten, että luokkamuuttuja (private static int otuslaskuri) laskee luotujen ilmentymien määrää ja jokainen luotava olio saa ilmentymävakionsa (final int yksilöllisyys) arvoksi tuon laskurin arvon luontihetkellä. Yhden geenin arpajaiset voi toteuttaa ehdolla (Math.random()<0.5).

    Luokassa on ainakin seuraavat välineet:

    Laadi pääohjelma tai erillinen pääohjelmaluokka, joka esittelee Alkueläin-olioiden käyttöä.

  2. Laadi ohjelma Geenilaboratorio alkueläintutkimukseen. Laboratoriossa on säiliö 100 alkueläimelle. Ohjelma tarjoaa ainakin palvelut: Ohjelma on määritelty tarkoituksellisen epämääräisesti Täsmennä se järkeväksi. Dokumentoi ratkaisusi. Todellisuudessa on pikemminkin sääntö kuin poikkeus, että ohjelmoijan saamat määrittelyt ovat ainakin osittain epämääräisiä. On hyödyllistä oppia täsmentämään ohjelman toiminta, ei vain ohjelmoida ja katsoa, mitä sattuu syntymään... Normaalisti noista tarkennuksista tietenkin neuvoteltaisiin ohjelman tilaajan kanssa.

    Toteuta ohjelman toimintalogiikka ns. komentotulkkina (ks. kirjan kappale 3.4.4., s. 126, WWW-materiaalin 3.4:n kohta komentotulkki ). Huomaa ettei komentotulkkilogiikka välttämättä edellytä switch-lauseen käyttämistä.

  3. Kirjan kappaleessa 4.3.3., s. 172, WWW-materiaalissa 4.3:n kohta "Luokka tietueena", henkilötietue määritellään kovin vanhanaikaisesti. Kehittele henkilötietojen esittämiseen tyylikäs luokka kapseloinnin ja abstraktin tietotyypin hengessä. Luentomateriaalin esimerkin kentät ika ja pituus pituus eivät ole tarpeellisia. Esitettävät tiedot ovat nimi, osoite ja merkkijonona esitetty luonnehdinta henkilöstä. Etu- ja sukunimi esitetään erikseen. Osoite muodostuu katuosoitteesta, postinumerosta, postitoimipaikasta ja mahdollisesta valtion nimestä.

  4. Kirjan kappaleessa 4.2.5., s. 163, WWW-materiaalissa 4.2:n kohta "Nelikenttä", on lueteltu esimerkkejä static/ei-static- ja private/public-määriteltyjen kenttien ja metodien käyttötavoista. Laadi toimivia ohjelmaesimerkkejä, jotka esittelevät havainnollisesti kaikki kahdeksan eri tapausta.

4. harjoitukset pe 13.6.

Aiheita: kirjastoluokka, periytyminen, abstrakti luokka, rajapintaluokka, polymorfismi, ...

  1. Toteuta kirjastoluokkana välineitä muotoiltuun tulostukseen: Metodit
          public static void tulVas(arvo, int leveys)
          public static void tulOik(arvo, int leveys)
    
    tulostavat arvon kenttään jonka leveys on leveys. Parametri arvo voi olla int, String, char- tai boolean. Metodeista ensimmäinen tulostaa arvon kentän vasempaan laitaan, jälkimmäinen oikeaan. Metodit eivät vaihda riviä! Jos arvo on kenttää leveämpi, kenttää laajennetaan, arvoa ei katkaista (Tämä on turvallisempaa! Miksi?)

  2. & 15.
    Tossueläin on muokkautunut monien hämmästyttävien mutaatioiden ja lukemattomien sukupolvien myötä alkueläimestä, ks. tehtävä 9. Tossueläimessä alkueläimen rakenne (yksilöllisyys ja perimä) on sellaisenaan säilynyt, mutta lisäksi tossueläimelle on on jostain syystä syntynyt sukupuoli, jonka määrää yksi uusi nukleotidi (mahdolliset arvot 'A', 'C', 'G' ja 'T').

    Tuo lisäperimä määrää sukupuolen siten, että A- ja C- tossueläimet ovat naaraita, G- ja T- tossueläimet koiraita.

    Tossueläin ei voi lisääntyä jakautumalla, eikä sitä vielä osata kloonata. Pariutumisessa tossueläimen alkueläimeltä kotoisin oleva perimä määräytyy samoin kuin alkueläimellä. Sukupuoligeeni määräytyy pariutumisyrityksen seurauksena seuraavasti (kirjain tarkoittaa lapsen perimän sukupuolen määräävän nukleotidin arvoa):

        vanhemmat   lapsi
        A  ja  G      A
        A  ja  T      T
        C  ja  G      C
        C  ja  T      G
    
    Muilla yhdistelmillä lasta ei tietenkään synny.

    Mallinna tossueläin luokkana Tossuelain, joka on luokan Alkuelain aliluokka. Käytä mahdollisimman paljon hyväksi yliluokan määrittelyitä. Ohjelmoi luokkaan ainakin metodit:

    Huom: Jos Alkuelain-luokkasi perimätaulukko oli private - niinkuin hyvä lähtökohta on - tämän tehtävän "geenien käsittelyssä" tulee ongelmia: Vaikka aliluokka periikin yliluokkansa privaattikaluston, se ei pääse siihen käsiksi!! Voit harkita Alkuelain-luokan private-määritellyn taulukon muuttamista protected-määritellyksi; tällöin kenttään pääsee käsiksi aliluokasta (ja omasta pakkauksesta). Tai voit pitää kentän ennallaan ja täydentää Alkuelain-luokkaa sopivilla "geeniteknologisilla" lisäaksessoreilla. Nämä on tietenkin luontevaa määritellä näkymään tasolla protected!

    Laadi myös pieni ohjelma, joka havainnollistaa Tossuelain-olioiden käyttöä. Jos haluat, jaksat ja ehdit, voit toki laajentaa tehtävän 10 Geenilaboratorion tossueläintutkimukseen sopivaksi.)

    Huom: Harjoitusten alkueläimillä ja tossueläimillä ei taida olla paljonkaan tekemistä todellisen biologian kanssa! ;-)

  1. Kehittele ja konkretisoi luvuissa 4.1 ja 4.5 esitetty esimerkki luokista ja periytymisestä. Toteuta ja testaa luokka Elain ja sen aliluokat Kissa, Nauta ja Hevonen sekä kahden viimeksimainitun aliluokat Lehmä ja Tamma. Mallinna tällä kertaa olioiden ominaisuuksia ja toimintatapoja, ei genetiikkaa. Käytä mielikuvitustasi, mutta muista, että harjoittelemme periytymisen mekanismeja, emme karjatilan hoitoa.

    Vaatimuksia ja vihjeitä:

5. harjoitukset ti 17.6.

Aiheita: lisää periytymisestä ja rajapintaluokista...

  1. & 18.
    Tehtävässä 7&8 toteutettiin muutettava merkkijono luokkana OmaString. Numerojono voidaan nähdä yleisen merkkijonon erikoistapauksena. Erikoista luokasta OmaString luokka Numerojono, jonka ilmentymät ovat siis muutettavia numerojonoja.

    Numerojonoja voidaan konstruoida ainoastaan parametrittomalla konstruktorilla:

      public Numerojono()  
    
    Konstruktori luo tyhjän numerojonon, siis tyhjän merkkijonon.

    Jotkin aksessorit ovat perittyinä sellaisinaan käyttökelpoisia, toiset täytyy korvata uudella jonon numeerisuuden säilyttämiseksi. Lisäksi tarvitaan yksi uusi aksessori

      public int value()
    
    joka palauttaa arvonaan this-numerojonon esittämän kokonaisluvun. Tyhjällä numerojonolla ei ole numeerista arvoa. Metodi palauttaa tuossa tilanteessa arvon -1. (Numerojonot voivat esittää ainoastaan ei-negatiivisia lukuja.)

    Vihjeitä:

  1. & 20.
    Javassa on valmis rajapintaluokka Comparable erilaisten järjestystä edellyttävien yleisten tietorakenteiden toteuttamiseen. Se vaatii ja lupaa metodin compareTo, joka on kurssilaisille tuttu ainakin String-luokasta. Harjoitellaan vastaavaa tekniikkaa "omin käsin"!

    Rajapintaluokka Vertailtava olkoon

       public interface Vertailtava {
         public boolean pienempi(Vertailtava toinen);  // this-olio < toinen-olio
         public boolean isompi(Vertailtava toinen);    // this-olio > toinen-olio
         public boolean yhtäSuuri(Vertailtava toinen); // this-olio = toinen-olio
       } 
    
    Muokkaa oppimateriaalin luokka Pikkuvarasto (ks. luku2) ja tehtävän 7&8 luokka OmaString sellaisiksi, että ne toteuttavat rajapintaluokan Vertailtava. Päätä itse (ja määrittele täsmällisesti!), mitä näissä luokissa tarkoittavat järjestys ja yhtäsuuruus. (Varastojen järjestys voisi olla vaikkapa sellainen, että tuotenimien String-suuruusjärjestys on ensisijainen ja tuotteen määrä toissijainen järjestysperuste.)

    Huom: Pikkuvarastojen vertailumetodien parametrin käsittelyssä on yksi ongelma, parametrin tyyppi. Sen pitää olla Vertailtava, mutta tämä tyyppi ei sisällä Pikkuvaraston niitä ominaisuuksia, joihin vertailu voi perustua. Ratkaisu on eksplisiittinen tyyppimuunnos, "cast":

    public boolean pienempi(Vertailtava toinen) {
      Pikkuvarasto toka = (Pikkuvarasto)toinen;
      // nyt toka on kunnon Pikkuvarasto, jonka ominaisuuksia
      // pääsee käyttämään
      ...
    

    Ohjelmoi luokkametodi järjestä, joka saa parametrinaan Vertailtava[]-tyyppisen taulukon ja järjestää sen nousevaan järjestykseen.

    Metodin oikea käyttötapa on sellainen, jossa taulukkoon on viety vain keskenään saman tyyppisiä olioita. Jos taulukossa on vaikkapa sekaisin Pikkuvarasto- ja OmaString-olioita, käy huonosti! Miksi? Voisiko asialle tehdä jotakin? Onko mielestäsi Java-kielen tämä ominaisuus hyvä vai huono? Voisivatko asiat olla toisin? Miten? (Javan versio 1.5 toi kieleen ns. geneeriset tyypit, käännösaikaiset tyyppiparametrit, joiden avulla tämä ongelma voidaan voittaa tyylikkäästi.)

    Laadi myös pieni ohjelma, joka havainnollistaa järjestä-metodin oikeaa käyttöä ja myös erityyppisten olioiden sekoittamisen kauheita seurauksia.

6. harjoitukset to 19.6.

Aiheita: tiedostoja, poikkeuksia, geneeristen tietorakenteiden käyttöä, kurssikysely

  1. Luentomateriaalin luvun 5.1 kohdassa "Virheiden käsittelyä", http://www.cs.helsinki.fi/u/wikla/Ohjelmointi/Sisalto/5/PoiLuk.html#9, on pohdiskeltu erilaisia tapoja hoidella virhetilanteita erityisesti olioita konstruoitaessa.

    Täydennä, toteuta ja suorita tietokoneella luentomateriaalin yksinkertaisia ohjelmaesimerkkejä siten, että ne havainnollistavat OmaOlio-luokan määrittelyä ja käyttöä siten, että konstruoinnin epäonnistuminen virheellisten parametrien takia hoidetaan a) erityisellä onkoKunnossa-tyyppisellä aksessorilla, b) staattisella luontimetodilla, c) tarkistettuja (checked) poikkeuksia heittäen, d) tarkistamattomia (unchecked) poikkeuksia heittäen. Pohdi millaisiin tilanteisiin eri tavat soveltuvat. (Tähän havainnollistus- ja pohdintatehtävään ei tule esimerkkiratkaisua.)

  2. Laadi ohjelma EtsiSanoja merkkijonon etsimiseen tekstitiedostosta. Ohjelmalle annetaan ensin tekstitiedoston nimi komentoriviparametrina. Etsittäviä merkkijonoja ohjelma kysyy käyttäjältä. Komentoriviparametrin ja tiedoston puuttumisesta on annettava virheilmoitus. Ohjelma tulostaa kuvaruudulle rivinumeroin ne tiedoston rivit, joihin sisältyy haettava merkkijono. Ohjelman suoritus päättyy kun kysytään tyhjää merkkijonoa.

    Jos esimerkiksi Juhanin Ahon romaanista Rautatie (tiedosto Rautatie.txt) etsitään sanoja, tulos voi näyttää seuraavalta:

    Mitä merkkijonoa etsitään tiedostosta Rautatie.txt?
    veturi
    551: veturin, joka vaunuja vetää, sen panee kanssa höyry liikkeelle. Siipien
    3215: --Etumaiset on suuremmat ... veturin pyörät ... toiset pienemmät,
    Mitä merkkijonoa etsitään tiedostosta Rautatie.txt?
    kännykkä
    Mitä merkkijonoa etsitään tiedostosta Rautatie.txt?
    koira
    838: --Kyllä oli, koira vieköön, liikaa kehumista! Jos oikein pistokkaalla
    841: niin kyllä, koira vieköön, jälelle jäisi raskas rumilas, vaikka kuinka
    Mitä merkkijonoa etsitään tiedostosta Rautatie.txt?
    
    

  3. Toteuta luokka SananSeuraajat, tietorakenne, johon voidaan tallettaa pareja (sana, sanaluettelo). Luokka tarjoaa ainakin palvelut:

    Kirjoita luokkaan myös yksinkertainen pääohjelmametodi, joka havainnollistaa luokan ilmentymien luomista ja käyttämistä.

    Vihjeitä: Seuraajaluettelotietorakenteen toteutuksessa kannattaa käyttää sellaista HashMap-oliota, joka esittää assosiaatioita String-merkkijonon ja siihen liittyvän ArrayList<String>-olion välillä. Luentomateriaalin pikku esimerkistä voi saada ideoita ja uskonvarmuutta rakenteiden sisältämien rakenteiden toteuttamiseen:

    import java.util.*;
    
    public class HAEsimerkki {
    
      public static void main(String[] args) {
    
        HashMap<String, ArrayList<String>> seuraajat =
            new HashMap<String,ArrayList<String>>();
    
        ArrayList<String> sanoja = new ArrayList<String>();
    
        sanoja.add("kissa");
        sanoja.add("hiiri");
        sanoja.add("hevonen");
    
        seuraajat.put("eläimiä", sanoja);
    
        ArrayList<String> lukuja = new ArrayList<String>();
        lukuja.add("134");
        lukuja.add("-23");
        lukuja.add("9871");
    
        seuraajat.put("lukuja", lukuja);
    
        System.out.println(seuraajat);
      }
    }
    
    
    Esimerkkiohjelma tulostaa toString()-metodin valinnan polymorfismin ansiosta:
    {lukuja=[134, -23, 9871], eläimiä=[kissa, hiiri, hevonen]}
    

  4. Laadi edellisen tehtävän luokkaa SananSeuraajat hyväksi käyttäen ohjelma, joka selvittää annetussa tekstitiedostossa kaikkien sanojen välittömät seuraajasanat. "Sanoiksi" lasketaan tässä tehtävässä kaikki Scanner-luokan next()-metodin antamat String-oliot.

    Ohjelma kysyy ensin tiedoston nimen ja tarjoaa sitten palvelun yksittäisen sanan seuraajien selvittämiseen. Testitarkoituksia varten myös koko seuraajaluettelo on syytä tulostaa.

    Testiaineistoa ohjelman kokeiluun (kannattanee käyttää versioita, joista välimerkit on poistettu):

  5. Vastaa kurssikyselyyn osoitteessa http://ilmo.cs.helsinki.fi/kurssit/servlet/Valinta. Muista myös lähettää lomake! Lähetysnäppäin on lomakkeen lopussa. Tähän kysymykseen vastataan yksilönä ja anonyymisti. Tehtävä myös rastitetaan opiskelijoittain, ei opintopiireittäin. Ja rastin saa kirjoittaa, jos on todella vastannut kyselyyn! Opiskelijaan luotetaan tässä-(kin) asiassa! Koetta koskeviin kysymyksiin ei tietenkään voi vastata, mutta kysely tehdään kuitenkin jo nyt, jotta saadaan varmistettua hyvä vastausprosentti. Vastauksilla ihan oikeasti on merkitystä laitoksen opetusta kehitettäessä!


Takaisin kurssin pääsivulle.