Ohjelmointi 1, syksy 2007 -- Demo 3

Tehtävät julkaistaan:
 Tiistain luennolla 25.9.2007
Palautus viimeistään:
 2.10.2007 klo 18
100% tehtävistä tarkoittaa:
 8 kpl tehty

Tuotetaan Java-ohjelmia; vielä erittäin yksinkertaisia algoritmeja. Harjaannutetaan lauseiden ja lohkojen käyttöä. Toistaiseksi ei vielä tehdä poikkeuksenkäsittelyä eikä syötteen tarkistusta, vaikka se tulee myöhemmin erittäin tärkeäksi. Pidetään tarvittavan APIn koko rajattuna toistaiseksi. Meillä on oliot System.in, System.out sekä luokat Scanner ja tässä demossa opastettava Random.

Contents

Ehtolause

Tehtävä 1: ''Asiantuntijaohjelma''

Tee "päätöspuu" -asiantuntijatyökalu eläinten tunnistamiseen ehtolauseita käyttäen. Eläimestä on tehty havaintoja, joissa on kyllä/ei -vastaus. Käyttäjän syötteeksi oletetaan kokonaisluku. Ohjelman toiminta:

Tunnistan eläimen. Kerro havaintosi:
Onko sillä siivet (0==ei, 1==on)?1
Onko sillä nokka (0==ei, 1==on)?0
Käsittääkseni olet nähnyt sudenkorennon.

Toinen ajo:

Tunnistan eläimen. Kerro havaintosi:
Onko sillä siivet (0==ei, 1==on)?0
Onko sillä evät (0==ei, 1==on)?0
Onko sillä tuntosarvet (0=ei, 1==on)?1
Käsittääkseni olet nähnyt etanan.

Piirteet, joiden perusteella tunnistetaan kuusi erilaista elukkaa:

siivet on -> nokka on -> lokki
siivet on -> nokka ei -> sudenkorento
siivet ei -> evät on -> hauki
siivet ei -> evät ei -> tuntosarvet on -> etana
siivet ei -> evät ei -> tuntosarvet ei -> kaljapullo kädessä ei
                                                    -> kirahvi
siivet ei -> evät ei -> tuntosarvet ei -> kaljapullo kädessä on
                                                    -> iloinen fuksi

Valintalause

Tehtävä 2: ''Aloittelijan opastusohjelma ohjelmoinnissa käytettyihin erikoismerkkeihin.''

Tee ohjelma, joka kyselee käyttäjältä merkkejä ja kertoo aina merkille selityksen suomeksi. Kysyminen ja tulkitseminen eri aliohjelmiin. Kysymistä on toistettava kunnes käyttäjä syöttää ison X-kirjaimen (sovitaan että "X==eXit"). Käytä merkin selittävässä aliohjelmassa switch-lausetta char-tyyppiselle parametrille.

Alla on merkit ja nimet, jotka ohjelmasi osaa selittää:

Merkit   Selitys
0-9      "Numero"
a-f      "Pieni kirjain; mahdollisesti heksadesimaalinumero"
"        "Lainausmerkki; käytetään Javassa merkkijonoliteraalin syntaksissa"
'        "Heittomerkki; käytetään Javassa merkkiliteraalin syntaksissa"
`        "Gravis-aksentti (engl. 'backtick'); tulee tutuksi shelleissä"
~        "Tilde eli 'matomerkki'; kuvaa unixissa kotihakemistoa"
@        "At eli 'ät-merkki'; sähköpostiosoitteissa, Javadocissa ja NH:ssa"
\        "kenoviiva; Windowsissa hakemistonimien välissä"
/        "kauttaviiva; Unixeissa ja WWW:ssä hakemistonimien välissä"
{        "vasen aaltosulje; aloittaa monessa ohjelmointikielessä lohkon"
}        "oikea aaltosulje; päättää monessa ohjelmointikielessä lohkon"

Koodi syntynee aika helposti copy-pastaamalla ylläoleva teksti Java-koodiisi ja lisäämällä tarvittavat Javan rakenteet ympärille. Merkkijoukot 0-9 ja a-f joudut avaamaan useiksi caseiksi. Tekstieditorin copy-paste -toiminto auttaa varmasti.

Sisäkkäisiä toistoja

Tehtävä 3:

Tee aliohjelma, joka tulostaa konsoliin minkä tahansa kokoisen kokonaislukujen kertotaulun, ts. seuraava voisi olla aliohjelman tuloste:

2x4 kertotaulu:

1 2 3 4
2 4 6 8

Yhtä hyvin seuraavakin voisi olla:

6x3 kertotaulu:

1 2 3
2 4 6
3 6 9
4 8 12
5 10 15
6 12 18

(Ei tarvitse miettiä kaunista asemointia, kunhan rivinvaihdot ovat aina oikeassa kohdassa tulostetta ja vierekkäisten lukujen välillä on välilyönti. Tarvinnet sisäkkäiset for-silmukat ja PrintStream-luokan metodien print() ja println() käyttöä sopivasti.)

Yhdistelmiä erilaisista lauseista

Tehtävä 4:

Fibonaccin lukujono F_n määritellään seuraavasti:

F_0 = 0
F_1 = 1
F_i = F_{i-1} + F_{i-2}, kun i>1

toisin sanoen nollas luku on 0, ensimmäinen luku on 1, ja toisesta luvusta alkaen i:nnes luku saadaan aina summaamalla kaksi edellistä toisiinsa. Lukujono alkaa siis 0, 1, 1, 2, 3, 5, 8, 13, ...

Tee long-tyyppisen luvun palauttava aliohjelma, joka laskee parametrina annettavan indeksin mukaisen Fibonaccin luvun käyttäen silmukka- ja ehtorakenteita tarkoituksenmukaisesti. Tee myös pääohjelma, josta testaat aliohjelmaa erilaisilla lukuarvoilla ja tulostat aliohjelman palauttamia lukuja. Ylimääräisenä pohdintana: Miten isoilla N:n arvoilla homma toimii oikein? Miksei isommilla?

Tehtävä 5:

Tee tällainen "numeroarvauspeli":

  • Aluksi pelaajalta kysytään kokonaislukujen arvoväli, jolta ohjelman tulee valita satunnainen luku.

  • Sitten peliohjelma valitsee satunnaisluvun kyseiseltä väliltä. Ohje:

    // Tämä luo uuden satunnaislukugeneraattorin:
    java.util.Random generaattori = new java.util.Random();
    
    // Tuottaa satunnaisen kokonaisluvun joukosta {0,1,...,27} (huom rajat!):
    int satluku = generaattori.nextInt(28);
    
  • Sitten pelaajaa pyydetään arvaamaan, mikä se valittu luku on, kunnes arvaus menee oikein.

  • Jos arvaus on väärin, peli antaa vihjeen, esim.:

    Arvaa luku>12
    Eipä. Luku on pienempi kuin arvauksesi!
    Arvaa luku>6
    Eipä. Luku on suurempi kuin arvauksesi!
    Arvaa luku>9
    Oikein! Miten keksitkin! Olitpa nokkela!
    

Tehtävä 6:

Viime demossa teit aliohjelman, joka muuntaa Celsius-asteina annetun lämpötilan Fahrenheit-asteiksi. Tee muutoksia:

  • Korjaa ensin ohjelmasi mallivastauksen mukaiseksi (malli julkaistaan piakkoin demon 2 deadlinen jälkeen kurssin demo-nettisivulla). Opi mahdollisista virheistäsi :-).
  • Sitten toteuta for-silmukkaa käyttäen pääohjelma, joka tulostaa neljän desimaalin tarkkuudella Fahrenheit-asteet Celsius-astemäärille 0.0, 0.1, 0.2, ... ,10.0 eli 101 riviä Fahrenheitteja.

API-dokumentaation lukeminen

Tehtävä 7:

Vastaa tähän oikeaoppisena tekstitiedostona. Kurssilla tullaan käymään läpi merkkijono-olioiden käyttöä jo ensi viikolla. Tutustu jo ennakkoon String-luokan dokumentaatioon, ja vastaa suomeksi seuraaviin kysymyksiin:

  1. Miten String-tyyppisen merkkijono-olion sisällön voi muuttaa vaikka tilasta "Matti" tilaan "Maija"?

  2. Kuinka monta erilaista tapaa on luoda uusi String-luokan olio new-operaattoria käyttämällä?

  3. Oletetaan, että sinulla on käytössäsi String-tyyppinen viitemuuttuja nimeltä jono, joka viittaa merkkijonoon. Millaisen metodikutsun kirjoitat lausekkeeseesi, kun haluat sijoittaa siihen kohtaan merkkijonon seitsemännentoista merkin alusta lukien.

    HUOM: Javassa indeksointi alkaa 0:sta mm. merkkijonoissa; indeksi 0 tarkoittaa ensimmäistä alkiota ja indeksi 1 toista jne!

  4. Merkkijono on kuten kohdassa c. Millaisen metodikutsun kirjoitat, kun haluat saada tietää, montako merkkiä merkkijonossa kaiken kaikkiaan on.

Javan API-dokumentaatio oli siis tuolla, pistä kirjanmerkkeihin jos ei ole jo: http://java.sun.com/javase/6/docs/api/

Tehtävä 8:

Käyttäen tehtävän 7 tietoa String-oliosta, ja sitä että Scanner-olion avulla voi lukea syötteestä merkkijonon metodilla nextLine(), tee ohjelma, joka kysyy käyttäjältä merkkijonon, ja tulostaa sen merkit yksi kerrallaan seuraavasti:

Merkkijonosi 1. merkki oli 'A'
Merkkijonosi 2. merkki oli 'p'
Merkkijonosi 3. merkki oli 'u'
Merkkijonosi 4. merkki oli 'a'
Merkkijonosi 5. merkki oli '!'

Bonussektori

Bonussektorin tekemällä voi saada demoprosentiksi yli 100%! Tässä tehtävässä käsiteltävä asia ei ole Ohjelmointi 1:n sisältöä, mutta periaatteessa varmasti jo ymmärrettävissä.

Tehtävä 9: Rekursion idea.

Tee rekursiivinen eli itseään kutsuva aliohjelma, joka laskee n:nnen Fibonaccin luvun kutsumalla itseään tyyliin:

return fib(n-1) + fib(n-2);

Varmista, että n:n arvot 0 ja 1 käsitellään oikein! Luonnollisesti tee taas pääohjelma, jossa kokeilet aliohjelman käyttöä.

Lisää java-koodisi alkukommenttiin seuraavat pohdinnat:

  • montako kertaa yhteenlasku-operaattori suoritetaan, kun lasket rekursiota käyttäen 6:nnen Fibonaccin luvun
  • onko tämä hyvä tapa laskea Fibonaccin luku? Miksi on tai miksi ei?