Ohjelmointi 2 -- kesä 2006 -- Demo 7/11

Demonumero:7/11
Palautus:tiistaina 20.6.2006 klo 18 mennessä.
Laskennallinen tehtävämäärä:
 9 kpl.
Pisteitä saa korkeintaan:
 11 kpl.

(esim. 12 tehtyä kohtaa -> 11 pistettä Korppiin)

1:

(Merkkijonojen käsittelyä, String-luokan käyttöä)

Mikä (tai mitkä) Java 1.4.1:n (tai uudemman) String-luokan metodi sopisi seuraavan ongelman ratkaisemiseen ja miten (kirjoita malli kutsusta):

  1. Onko merkkijonossa jono muita kirjaimia kuin joukon k kirjaimet:

    jono="kissa" k="aik" -> on, k="aiks" -> ei ole
    
  2. Missä on jonon viimeinen '\':

    "C:\mytemp\ohj2\vesal\Koe.java"  -> 
    indeksi "osoittamaan" viimeiseen '\'-merkkiin, 
    eli jonon \Koe.java:n alkuun.
    
  3. Onko jonossa jokin kirjain joukosta k

    jono="kissa" k="ibm" -> on , k="pc"  -> ei ole
    
2:

(Merkkijonojen käsittelyä, String-luokan käyttöä)

Edelleen katso String-luokasta kuinka saataisiin vastaus kysymyksiin (kirjoita esimerkkikoodit, nyt voi olla ettei yksi rivi enää riitä):

  1. onko "  matti*  " sama kuin "Matti Nykänen"? (vastaus: on. Huomaa jokerimerkki, välilyönnit, sekä isot ja pienet kirjaimet)
  2. Paljonko jonossa "Kissa istuu puussa" on yhteensä merkkejä "a-j" tai "r-w" ("a-j" == "abcdefghij") (vastaus: 2*a + 2*i +5*s + 1*t + 4*u = 14)
3:

(Merkkijonojen käsittelyä)

Kirjoita funktio palindromi, joka palauttaa tiedon siitä (true=kyllä, false=ei) onko parametrinä välitetty SANA palindromi vai ei (esim "abba" on palindromi, "apua" ei ole, sanassa ei ole välilyöntejä tai muita erikoismerkkejä).

4:

(Merkkijonojen käsittelyä)

Kirjoita kaksi eri aliohjelmaa (toinen String-jonoille ja toinen StringBuffer-jonoille) tuhoa_lopusta, jotka loogisessa mielessä "poistavat" merkkijonon n viimeistä merkkiä (muista virhetilanteet!):

String s="Kissa istuu";
s = tuhoa_lopusta(s,3);           // => s = "Kissa is" 
StringBuffer sb = new StringBuffer("Kissa istuu");
tuhoa_lopusta(sb,3);              // => sb= "Kissa is" 
5:

("Numeerista matematiikkaa")

Kirjoita aliohjelmat (siis staattiset metodit perustaulukoiden käsittelyyn):

  • paras (palauttaa reaalilukutaulukon suurimman luvun)
  • huonoin (palauttaa reaalilukutaulukon pienimmän luvun)
  • summa (palauttaa reaalilukutaulukon summan).

Näitä käyttäen kirjoita aliohjelma summa_huonoin_ja_paras_pois, joka palauttaa reaalilukutaulukon summan kun siitä otetaan huonoin ja paras tulos pois (sopii esim. mäkikisan arvosteluun).

(Sori vaa; nyt pitäis olla jalkapallotehtäviä, mutta kesän kuumalla on hyvä ajatella talvilajeja...)

6:

("Numeerista matematiikkaa")

Edellisen tehtävän funktiota summa käyttäen kirjoita aliohjelma matriisin_summa, joka laskee 2-ulotteisen reaalilukumatriisin summan (muista että matriisi on taulukko riveistä!).

7:

(Tiedostojen käsittelyä)

(Edelliset tehtävät eivät ole välttämättömiä tämän toteuttamiseksi, vaikka toki niitä saa halutessaan käyttää. Ks. tarvittaessa luentoesimerkki.)

Tee ohjelma, joka lukee tiedostosta n x m -reaalilukumatriisin, laskee sen kaikkien alkioiden summan ja tulostaa seuraavasti:

Paikassa (1,1) on luku -0.758
Paikassa (1,2) on luku  1.718
Paikassa (1,3) on luku  4.228
... [tässä siis paljon vastaavia rivejä...]
Paikassa (15,17) on luku -0.001
Kaikkien lukujen summa on -141.4

Tallennusmuoto esimerkin kautta:

1.2 3.4 5.6 
7.8 9.0 1.2 

(= kukin tiedoston rivi on yksi matriisin rivi; rivin alkioiden välissä on yksi välilyönti; ensimmäisen rivin alkioiden määrä kertoo sarakkeiden määrän; rivien määrä tiedostossa kertoo rivien määrän)

Nyt ei (vielä) tarvitse huolehtia vääränmuotoisista syötteistä. Oletetaan, että mikään ei ole rikki ja tiedosto sisältää oikeanlaista dataa.

8:

(Tiedostojen käsittelyä)

Kirjoita Java-ohjelma joka tulostaa tiedoston koe.txt:

123456789012345678901234567890123456789012345678901234567890
Kissa istuu puussa
ja ihmettelee
mualiman menoa

sisällön siten, että kunkin rivin alkuun tulee rivinumero ja kustakin rivistä tulostetaan korkeintaan 40 merkkiä:

/* 01 */ 1234567890123456789012345678901234567890
/* 02 */ Kissa istuu puussa
/* 03 */ ja ihmettelee
/* 04 */ mualiman menoa

Toteuta muunnos tietovirtojen avulla, niin että sekä lähdetiedoston että kohdetiedoston virrat voi antaa parametreina muokkausalgoritmille. Tässä tehtävässä voi antaa suoraan koe.txt-tiedostosta luodun lukuvirran (ks. luentomalli) ja System.out-virran

9:

(Harjoitustyön vaihe 6)

Samalla, kun demot, käyn noutamassa harjoitustyöt sieltä, mihin ne aina palautetaan.

Tätä pistettä voi "anoa" palauttamalla vapaamuotoisen hakemuksen tekstitiedostona ja antamalla sen arvoksi yhden pisteen. Mainitse varmuuden vuoksi kaikkien työryhmän jäsenten nimet tiedostossa. Jokainen päivittää henkilökohtaisesti harkkatyönsä webiin.

Pisteen saa, jos työ selvästi näyttää etenevän jotakuinkin vaiheessa 6, eli ainakin on:

  • toimiva "prototyyppi", jota klikkailemalla näyttää siltä, että tietorakenteissa on sopivasti eloa: pystyy lisäämään alkoita listoihin ja pystyy tulostamaan näyttöön dataa, joka on selvästi muuttunut lisäyksen johdosta.
  • Tiedostosta lataaminen tai tiedostoon tallentaminen toimii.
  • jokaista pientä luokkaa pystyy ajamaan myös erikseen, eli yksikkötestit on toteutettu.
  • koodi on siistiä ja sopivasti javadoc-tyyppisesti kommentoitua

Vaikka tällaisesta voi saada pisteen demossa, haluan hyväksyä vaiheen 6 varsinaisessa ohjaustilanteessa naamasta naamaan!

Bonus-osio

B1-2:

("Numeerista matematiikkaa", indeksien laskemista, luokan sisäisen toteutuksen kapselointia)

Toteuta luokat YläkolmioMatriisi ja DiagonaaliMatriisi, jotka tallentavat yksiulotteiseen taulukkoon vain sen verran reaalilukuja kuin kyseinen n x n matriisityyppi sisältää. Toteuta saantimetodi getAlkio(i,j) siten, että sekä rivi- että sarakeindeksit annetaan, ja palautus on oikein (eli 0.0 tai sitten kyseisessä paikassa olevan ei-nollan alkion arvo. Asetus setAlkio(i,j) siten, että jos yritetään sijoittaa paikkaan, jossa voi olla vain 0.0, heitetään sopiva "runtime"-poikkeus, joka on peritty java.lang.IndexOutOfBoundsException -luokasta. (runtime-poikkeuksiahan ei tarvitse ilmoittaa throws-avainsanalla.)

Esimerkkejä matriisityypeistä, jos lineaarialgebrakurssi on vielä käymättä:

Yläkolmio 5x5 (vain diagonaalin yläpuoliset paikat tallennetaan):

0.0  1.3  2.1  3.4  6.7
0.0  0.0  4.0  3.2  6.8
0.0  0.0  0.0  2.1  7.43
0.0  0.0  0.0  0.0  2.0
0.0  0.0  0.0  0.0  0.0

Diagonaali 4x4 (vain diagonaalipaikat tallennetaan):

2.3   0.0   0.0   0.0
0.0   2.1   0.0   0.0
0.0   0.0  -1.2   0.0
0.0   0.0   0.0   194.7

Huomioitavaa:

  • muodostajalle voitava antaa parametrina taulukon koko. Yksiulotteisen taulukon luonti tapahtuu siellä.
  • tee myös metodit getRows ja getCols, joilla voidaan aiemmin luodun matriisin koko tietää. Nyt molemmat palauttavat saman, koska kyseessä on neliömatriisien erikoistyypit.
  • jotta testaaminen on mahdollista, pitää olla myös jonkinlainen tulostus. (Aina pitää ohjelmanpätkät testata!)
  • onko tullut vastaan sovelluksia (fyysikot, matemaatikot, huom!) joissa tällaisissa luokissa olisi järkeä? Mitä järkeä verrattuna täyteen taulukkoon?
B3:

("Numeerista matematiikkaa")

Mieti perintää ja rajapintoja. Miten lähtisit tekemään matriisikirjaston, joka ei heittäisikään poikkeusta sijoituksessa nollapaikkaan, vaan muutaisi sisäisen tallennusrakenteen uudenlaiseksi? Tarvitseeko matriisiluokan käyttäjän tietää, millaisessa taulukossa luvut sijaitsevat?

B4:

(Komentoriviparametrit ja niiden käsittely, käyttöjärjestelmän tarjoama ympäristö)

Laajenna tehtävän 8 vastausta siten, että komentoriviparametreina (eli argumentteina) voi antaa esim. --input=koe.txt --output=koe_rivinumeroitu.txt jolloin tulostetaan standardiulostulon sijasta tiedostoon koe_rivinumeroitu.txt. Jos argumenttia --input= ei ole annettu, ohjelman tulee lukea System.in-virrasta ja jos argumenttia --output= ei ole annettu, tulee tulostaa System.out``iin. Jos on annettu argumentti ``--help pitää tulostaa käyttöohje System.out-virtaan ja jos on jotakin muita argumentteja niin pitää antaa sopiva virheilmoitus System.err-virtaan.

(Suurin piirtein noin toimisi "käyttäjäystävällinen" komentoriviohjelma...)