Arto Wikla 2011. Materiaalia saa vapaasti käyttää itseopiskeluun. Muu käyttö vaatii luvan.

Ohpe-harjoitukset s2011: 3/6 (19.-23.9.)

(Muutettu viimeksi 19.9.2011, sivu perustettu 5.9.2011.)

Nämä harjoitukset liittyvät oppimateriaalin lukuihin 1 Algoritmeja: 24-34.

Kaikki harjoitustehtävät on syytä tehdä. Jotkin tehtävät on merkitty keltaisella värillä. Ne ovat ehkä hieman muita haastavampia. Ilman niitäkin harjoituksista voi saada maksimipisteet, mutta ne lasketaan silti mukaan harjoituspisteitä määrättäessä – ne voivat siis korvata joitakin haasteettomampia tehtäviä tms. Mutta ennen kaikkea noista keltaisista tehtävistä sitä vasta oppiikin!

Huom:

Taulukon indeksointia ja alkioiden läpikäyntiä

Tässä harjoitellaan oppimateriaalin kohtaa 1 Algoritmeja: aliluvut 24-26.

Laadi tämän kohdan ohjelmat sellaisiksi, että ne toimivat kaiken kokoisilla taulukoilla. Kokeile siis muitakin kuin esimerkkitaulukkoja. Vaihda tässä vaiheessa vain taulukon määrittelyä ohjelmassasi. Arvojen lukeminen taulukkoon aloitetaan vasta seuraavassa kohdassa. Tulosta tämän alikohdan ohjelmissa standarditulosvirtaan eli käytä System.out.println- ja System.out.print-operaatioita.

EkaJaVika.java

Tee ohjelma joka tulostaa taulukon ensimmäisen ja viimeisen alkion. Jos taulukko on esimerkiksi int[] taulukko = {5,11,3,84,2};, ohjelma tulostaa:

Ensimmäinen: 5
Viimeinen:   2

Jos taulukko on int[] taulukko = {-1, 3, 2, 7};, ohjelma tulostaa:

Ensimmäinen: -1
Viimeinen:   7

Keskimmainen.java

Tee ohjelma joka tulostaa taulukon keskimmäisen alkion. Mikä on keskimmäinen, jos alkioita on parillinen määrä? Voit päättää asian itse.

AlkioidenSumma.java

Tee ohjelma, joka tulostaa taulukon alkiot ja alkoiden summan.

Jos taulukko on esimerkiksi int[] taulukko = {5,11,3,84,2};, ohjelma tulostaa:

Taulukon alkiot:
5
11
3
84
2
Summa: 105

Jos taulukko on int[] taulukko = {-1, 3, 2, 7};, ohjelma tulostaa:

-1
3
2
7
Summa: 11

VikastaEkaan.java

Jos taulukko on esimerkiksi int[] taulukko = {5,11,3,84,2};, ohjelma tulostaa:

Taulukon alkiot käänteisessä järjestyksessä:
2
84
3
11
5

Jos taulukko on int[] taulukko = {-1, 3, 2, 7};, ohjelma tulostaa:

Taulukon alkiot käänteisessä järjestyksessä:
7
2
3
-1

Pilkkutulostus.java

Tulosta taulukon alkiot tyylikkäästi siten, että niiden väliin tulee pilkku ja välilyönti. Huomaa, että lopussa ei saa olla pilkkua; virkkeethän päättyvät pisteeseen.

Taulukon alkiot ovat 5, 11, 3, 84, 2.

OnkoLukuTaulukossa1.java

Ohjelmassasi on taulukko, jossa on arvoja. Ohjelma kysyy ponnahdusikkunan avulla käyttäjältä lukua ja selvittää, onko luku taulukossa. Suoritus esimerkkitaulukolla int[] taulukko = {1, 53, 2, 3, 100};

kuva

Löytyy!

Syötteitä taulukkoon tutkittaviksi

Tässäkin harjoitellaan oppimateriaalin kohtaa 1 Algoritmeja: aliluvut 24-26.

LueJaTulosta7.java

Lue ponnahdusikkunaa käyttäen taulukkoon int[] luvut = new int[7] seitsemän kokonaislukua ja tulosta luetut luvut kauniisti standarditulosvirtaan:

Syötit luvut: 1, 32, 6, 8, 12, 17, 22.

Huom: Älä kirjoita seitsemään kertaan Pop.kysyInt! Sen sijaan käytä for-lausetta.

OnkoLukuTaulukossa2.java

Ohjelmassasi on taulukko, jossa on arvoja. Ohjelma kysyy käyttäjältä lukua ja jatkaa kyselyä niin kauan, kunnes käyttäjä arvaa jonkin taulukossa olevan luvun. Suoritus esimerkkitaulukolla int[] t = {1, 53, 2, 3, 100, 9, 53}:

kuva kuva kuva kuva kuva kuva

SyotaJaArvaa.java

Yhdistä kahden edellisten tehtävien ratkaisut yksinkertaiseksi tietokonepeliksi: Ensin ohjelma pyytää käyttäjältä seitsemän kokonaislukua ja sijoittaa ne 7-alkioisen taulukon alkioiden arvoksi. Sen jälkeen (toinen) käyttäjä alkaa arvailla lukuja edellisen tehtävän tapaan.

Ohjelma keskustelee käyttäjien kanssa ponnahdusikkunoin.

Arvauspeli

Kehittelemällä edellisten tehtävien ideoita voit toteuttaa yksinkertaisen, mutta jo ihan oikean tietokonepelin: Ensin ohjelma pyytää syötettävien lukujen lukumäärän pelinjohtajalta ja sitten itse luvut. Sovitaan että tässä pelissä sallittuja ovat vain luvut 1–21, muut hylätään. Sama luku saa esiintyä useampaankin kertaan.

Tämän jälkeen pelaaja istuu koneen ääreen ja peli alkaa. Pelaaja yrittää arvata koneelle syötettyjä lukuja. Peli päättyy, kun pelaaja arvaa jonkin pelinjohtajan syöttämistä luvuista, ja tulos on tarvittujen arvauskertojen lukumäärä.

Pelinjohtaja:

kuva kuva kuva kuva kuva kuva

Ja näin jatkuu, kunnes kaikki luvut on annettu:

kuva

Sovitaan että pelinjohtaja syötti luvut 11, 17, 6, 8, 12 ja 17.

Sitten on pelaajan vuoro.

Epäonnistunut arvaus:

kuva kuva

Tyhmään arvaukseen vahvempi palaute:

kuva kuva kuva kuva

kuva kuva

Viimeinkin osuu:

kuva kuva

Kun saat ohjelman muuten kuntoon, mieti miten käyttäjän Cancel- tai ylärastiklikkaukseen tulisi suhtautua. Jos jaksat, toteuta myös haluamasi suhtautumistavat.

Merkkijonotaulukoita

Tässä harjoitellaan oppimateriaalin kohtaa 1 Algoritmeja: aliluvut 27-28.

OnnitteleTasavuotisia.java

Käytetään merkkijonotaulukkoa ja kokonaislukutaulukkoa rinta rinnan. Kurssimateriaalissa on esimerkki:

String[] henkilot = {"Matti", "Maija", "Pekka", "Liisa"};
int[]    ika      = {   29,      22,     19,       27};

Kirjoita pieni ohjelma, joka tässä tietorakenteessa kasvattaa jokaisen henkilön ikää yhdellä ja onnittelee jokaista, joka täyttää tasavuosia. Onnentoivotukset saavat siis Matti ja Pekka.

NimetJaVuodet.java

Jatketaan edellisen tehtävän hengessä. Tee ohjelma, joka kysyy ensin henkilöiden lukumäärän, sitten yksitellen jokaisen henkilön nimen ja iän. Ohjelman tehtävänä on tulostaa nimet ja iät standarditulosvirtaan. Syötteet luetaan ponnahdusikkunoin.

Jos ohjelmalle vaikkapa syötetään lukumääräksi 4 ja sitten nimet ja iät: Matti, 29, Maija, 22, Pekka, 19, Liisa 27, ohjelma tulostaa:

Matti on 29-vuotias.
Maija on 22-vuotias.
Pekka on 19-vuotias.
Liisa on 27-vuotias.

Vihjeitä:

Ikapalvelu.java

Täydennetään edellistä ohjelmaa todelliseksi palveluksi. Aluksi ohjelma edellisen tehtävän ohjelman tapaan kysyy henkilöiden lukumäärän, sitten yksitellen jokaisen henkilön nimen ja iän. Tämän jälkeen ohjelma tarjoaa palvelun henkilöiden iän selvittämiseksi: Käyttäjä antaa nimen ja ohjelma ilmoittaa kyseisen henkilön iän tai tiedon siitä, ettei kysyttyä henkilöä löydy.

Käytä ponnahdusikkunoita ja päätä itse, miten ohjelmalle ilmaistaan palvelun käytön lopettaminen.

Vihje ja virike:

Metodi komentona – void-metodeita

Käytä tämän tehtäväsarjan toimittamiseen palautusautomaattia! Ohje sivun alussa.

Tässä harjoitellaan oppimateriaalin kohtaa 1 Algoritmeja: aliluvut 29-34. Lähdetään liikkeelle hyvin pienestä, mutta ei huolta, kyllä pian päästään pidemmälle.

Tahti1.java

Ohjelmoi parametriton metodi tahti1(), joka vain tulostaa yhden tähtimerkin (*) standarditulosvirtaan riviä vaihtamatta. Laadi myös pääohjelma, joka kutsuu tätä metodia.

Neuvo: Koko ohjelman rakenne on seuraavanlainen:

public class Tahti1 {

  // metodin määrittely:
  private static void tahti1() {
    // tänne tulee metodin vaativa toiminnallisuus
    // eli se yhden tähden tulostaminen ilman rivinvaihtoa
  }

  // pääohjelma
  public static void main(String[] args) {
    System.out.println("Tähtitesti");
    tahti1(); // metodin kutsuja
    tahti1();
    System.out.println("Moido!");
  }
}

Ohjelman tulostus:

Tähtitesti
**Moido!

TahtiN.java

Ohjelmoi int-parametrinen metodi tahtiN(int kpl), joka tulostaa parametrin ilmaiseman määrän tähtiä (*) standarditulosvirtaan riviä vaihtamatta. Jos parametri on nolla tai negatiivinen, mitään ei tulosteta. Laadi myös pääohjelma, joka kutsuu tätä metodia.

Neuvo: Koko ohjelman rakenne on seuraavanlainen:

public class TahtiN {

  // metodin määrittely:
  private static void tahtiN(int kpl) {
    // tänne tulee metodin toiminnallisuus
    // eli tähtirivin tulostaminen ilman rivinvaihtoa
  }

  // pääohjelma
  public static void main(String[] args) {
    tahtiN(5);  // metodin kutsu
    System.out.println("Ahaa!");
    tahtiN(14); // metodin kutsu
    System.out.println("Moido!");
  }
}

Ohjelman tulostus:

*****Ahaa!
**************Moido!

TahditaTeksti.java

Ohjelmoi yksiparamertinen metodi tahditaTeksti(String teksti), joka tulostaa standarditulosvirtaan parametritekstin ympäröitynä tähtimerkein. Esimerkki alla. Käytä hyväksi edellä ohjelmoitua metodia tahtiN(int kpl). Merkkijonon merkkien lukumäärän saa ns. lenght()-aksessorilla: muuttuja.lenght().

Neuvo: Koko ohjelman rakenne on seuraavanlainen:

public class TahtiN {

  // metodien määrittelyt:
  private static void tahtiN(int kpl) {
    // tänne tulee metodin toiminnallisuus
    // eli tähtirivin tulostaminen ilman rivinvaihtoa
  }
  private static void tahditaTeksti(String teksti) {
    // tänne tulee metodin toiminnallisuus
    // täältä kutsutaan metodia tahtiN(int kpl)
  }

  // pääohjelma
  public static void main(String[] args) {
    tahditaTeksti("Tervetuloa!");  // pääohjelma siis kutsuu metodia
    tahditaTeksti("ABC");          // tahditaTeksti, joka puolestaan
    tahditaTeksti("Hei hei!");     // kutsuu metodia tahtiN
  }
}

Ohjelman tulostus:

***************
* Tervetuloa! *
***************
*******
* ABC *
*******
************
* Hei hei! *
************

TahditaTekstit.java

Ohjelmoi yksiparamertinen metodi tahditaTekstit(String[] teksti), joka tulostaa standarditulosvirtaan parametrina saadun merkkijonotaulukon jokaisen merkkijonon ympäröitynä tähtimerkein. Esimerkki alla. Käytä hyväksi edellä ohjelmoituja metodeja tahtiN(int kpl) ja tahditaTeksti(String teksti).

Neuvo: Koko ohjelman rakenne on seuraavanlainen:

public class TahtiN {

  // metodien määrittelyt:
  private static void tahtiN(int kpl) {
    // tänne tulee metodin toiminnallisuus
    // eli tähtirivin tulostaminen ilman rivinvaihtoa
  }
  private static void tahditaTeksti(String teksti) {
    // tänne tulee metodin toiminnallisuus
    // täältä kutsutaan metodia tahtiN(int kpl)
  }
  private static void tahditaTekstit(String[] teksti) {
    // tänne tulee metodin toiminnallisuus
    // täältä kutsutaan metodia tahditaTeksti(String teksti)
  }

  // pääohjelma
  public static void main(String[] args) {
    String [] tekstit = {"Tervetuloa", "ABC", "Hei hei!"};
    tahditaTekstit(tekstit);  // pääohjelma siis kutsuu metodia
                              // tahditaTekstit, joka puolestaan
                              // kutsuu metodia tahditaTeksti, joka
                              // kutsuu metodia tahtiN
  }
}

Ohjelman tulostus:

***************
* Tervetuloa! *
***************
*******
* ABC *
*******
************
* Hei hei! *
************

Jakaja.java

Ohjelmoi metodi private static void jaonTulos(int eka, int toka), joka tulostaa jakolaskun seuraavan esimerkin mukaisesti.

128 / 8 = 16.0
5 / 3 = 1.66666666666667

Laadi myös pääohjelma, joka esittelee metodin käyttöä.

Huom: (21.9.) Jos käytät tarkistusautomaattia, anna metodille nimeksi jakolasku. On nimittäin kuulemma helpompi kirjoittaa tämä viesti tänne kuin muuttaa automaattia. ;-)

Metodi arvon laskijana – lasketaan arvo ja arvolla on tyyppi

Käytä tämän tehtäväsarjan toimittamiseen palautusautomaattia! Ohje sivun alussa.

Tässäkin harjoitellaan oppimateriaalin kohtaa 1 Algoritmeja: aliluvut 29-34.

YmpyranKeha.java

Tee metodi private static double keha(...), joka palauttaa arvonaan ympyrän kehän (piirin) pituuden. Säde annetaan double-parametrina. Piin mahdollisimman tarkan double-arvon saat kirjastosta: Math.PI. Niin, se kaava taisi olla "kaks'pii'är"...

Neuvo: Koko ohjelman rakenne olkoon seuraavanlainen:

public class PiiArToiseen {

  // metodin määrittely:
  private static double keha(double sade) {
    // täältä palautetaan laskettu arvo return-lauseella
  }

  // pääohjelma
  public static void main(String[] args) {
    double saatuSade = Pop.kysyDouble("Anna säde!");
    double piiri = keha(saatuSade);  // metodin kutsu
    System.out.println(piiri);

    saatuSade = Pop.kysyDouble("Anna säde!");
    piiri = keha(saatuSade);  // metodin kutsu
    System.out.println(piiri);
  }

Kun ohjelmalle syötetään luvut 20.0 ja 1.0, saadaan tulostus:

125.66370614359172
6.283185307179586

Vastaluku.java

Ohjelmoi int-tyyppinen metodi vastaluku, joka laskee parametrina annetun kokonaisluvun vastaluvun. Tämä tarkoittaa, että positiivinen luku muuttuu negatiiviseksi ja päinvastoin.

Laadi myös pääohjelma, joka esittelee metodin käyttöä.

KahdenKarvo.java

Ohjelmoi double-tyyppinen metodi kahdenKarvo, joka laskee kahden parametrina annetun liukuluvun keskiarvon.

Laadi myös pääohjelma, joka esittelee metodin käyttöä.

OnPariton.java

Ohjelmoi boolean-tyyppinen metodi onPariton, joka palauttaa arvon true, jos parametrina annettu kokonaisluku on pariton. Muuten metodi palauttaa arvon false.

Laadi myös pääohjelma, joka esittelee metodin käyttöä.

Huomaa että totuusarvoista metodia kutsutaan siellä, missä totuusarvoja muutenkin käytetään! Siis esimerkiksi if- tai while-lauseen ehdossa. Siis tähän tyyliin:

...
int luku = ...
...
if (onPariton(luku))
  ...
else
  ...
while (onPariton(luku)) {
  ...
}

Arvosanajakauma vaiheittain ohjelmoituna

Käytä tämän tehtäväsarjan toimittamiseen palautusautomaattia! Ohje sivun alussa.

Edelleen harjoitellaan oppimateriaalin kohtaa 1 Algoritmeja: aliluvut 29-34.

Ohjelmoidaan arvosanajakauman laskenta vaiheittain. Arvosanat ovat: 0, 1, 2, 3, 4 ja 5. Nolla tarkoittaa hylättyä.

Arvosanajakauma.java

Laadi metodi private static int[] arvosanaMaarat(), joka kysyy ponnahdusikkunan avulla opettajalta arvosanojen määrät yksi kerrallaan; ensin 0-arvosanojen lukumäärän, sitten 1-arvosanojen lukumäärän, jne.

Metodin tyyppi on siis int[], mikä tarkoittaa, että metodi itse luo arvosanojen lukumäärää varten 6-alkioisen int-taulukon, kyselee arvosanojen lukumäärät, asettaa ne taulukkoon ja lopuksi palauttaa tuon taulukon return-lauseella. Metodi siis näyttää tältä:

private static int[] arvosanaMaarat() {
  int[] arvMaarat = new int[6];
  // kysele yksitellen arvosanojen lukumäärät ja vie ne taulukkoon
  return arvMaarat;
}

Ohjelmoi myös itse luokka ja metodin käyttöä esittelevä pääohjelma tyyliin:

public class Arvosanajakauma {

  private static int[] arvosanaMaarat() {
    ...
  }

  // pääohjelma
  public static void main(String[] args) {
    int[] maarat;
    maarat = arvosanaMaarat();
    // tulosta taulukot tiedot siististi
  }
}

Jos opettaja vaikkapa syöttää lukumäärät 3, 3, 7, 2, 7, 10, ohjelma tulostaa tyyliin:

Arvosanat:
0: 3 kpl
1: 3 kpl
2: 7 kpl
3: 2 kpl 
4: 7 kpl
5: 10 kpl

Arvosanajakauma.java

Täydennä luokkaa metodilla private static double hyvPros(int[] arvosanajakauma), joka saa parametrinaan arvosanajakaumataulukon ja joka laskee hyväksyttyjen prosentuaalisen määrän kurssin kaikista osallistujista.

Täydennä ohjelman edellinen varsio seuraavan kaltaiseksi:

public class Arvosanajakauma {

  private static int[] arvosanaMaarat() {
    ...
  }

  private static double hyvPros(int[] arvosanajakauma) {
    // prosentin laskenta
  }

  // pääohjelma
  public static void main(String[] args) {
    int[] maarat;
    maarat = arvosanaMaarat();
    // tulosta taulukot tiedot siististi
    System.out.println("Hyväksyttyjä " + hyvPros(maarat) + "  % osallistujista");
  }
}

Edellisen kohdan esimerkissä tulostus voisi näyttää tältä:

Arvosanat:
0: 3 kpl
1: 3 kpl
2: 7 kpl
3: 2 kpl 
4: 7 kpl
5: 10 kpl

Hyväksyttyjä 90.625 % osallistujista

Arvosanajakauma.java

Täydennä luokka Arvosanajakauma tehtävän 4.2 metodilla private static void tahtiN(int kpl) ja viimeistele arvosanajakauman tulostusohjelma toimimaan seuraavaan tyyliin (sama esimerkkisyöte kuin edellä):

Arvosanat:
0: 3 kpl
1: 3 kpl
2: 7 kpl
3: 2 kpl 
4: 7 kpl
5: 10 kpl

Hyväksyttyjä 90.625 % osallistujista

Arvosanajakauma:
5: **********
4: *******
3: **
2: *******
1: ***
0: ***

Huom: Älä ihmeessä rasita pääohjelmaa tähtirivien tulostamisen yksityiskohdilla! Laadi (ja nimeä!) tähän tarkoitukseen sopiva metodi, jota siis kutsutaan pääohjelmasta:

public class Arvosanajakauma {
  ...
  // pääohjelma
  public static void main(String[] args) {
    int[] maarat;
    maarat = arvosanaMaarat();
    // tulosta taulukot tiedot siististi
    // tulosta hyväksyttyjen prosentti
    // tulosta arvosanajakauma
  }
}

Työkalu seuraavaan keltaiseen tehtävään

Toteuta metodi private static int maaritteleArvosana(int pisteet), jolle annetaan pisteet ja joka palauttaa pisteitä vastaavan arvosanan. Metodi ei siis itse tulosta mitään, kunhan vain laskee. Arvosana lasketaan seuraavasti: 30-34 pistettä: 1, 35-39: 2, 40-44: 3, 45-49: 4, 50-60 : 5 ja alle 30 pistettä on hylätty.

Muista miten arvosanan määräämisen logiikkaa harjoiteltiin jo ensimmäisen viikon tehtävässä 4.5!

Arvosanajakauma.java

Kehittele arvosanajakauman laskevasta ohjelmasta lopulta "ihan oikea" palvelu: Aluksi opettaja syöttää opiskelijoiden koepistemäärät. Kukin syötetty koepistemäärä muutetaan vastaavaksi arvosanaksi tehtävän 6.4 metodilla. Jokainen näin selvitetty arvosana kasvattaa yhdellä arvosanojen lukumääriä laskevan taulukon oikeaa alkiota.

Esimerkkisuoritus:

Ensin opettaja syöttää ponnahdusikkunan avulla opiskelijoiden pistemäärät (0-60) ohjelmalle, vaikkapa 44, 35, 17, 56, 7, ..., 54, -1.

Negatiivinen syöttöluku lopettaa pisteiden syötön.

Tämän jälkeen ohjelma tulostaa:

Arvosanajakauma:
5: **********
4: *******
3: **
2: *******
1: ***
0: ***

Hyväksyttyjä 90.625 % osallistujista

Huomaa miten tässä monimutkainen ongelma ratkottiin pienempinä osaongelmina, jotka saatettiin yksi kerrallaan toimintakuntoon. Ohjelmointiongelmia kannattaa useimmiten lähestyä juuri tähän tyyliin!

Muista ohjelmoida tehtävää ratkoessasi tarpeen mukaan lisää omia metodeita: ei ole esimerkiksi mitään järkeä ohjelmoida pisteiden kyselyä suoraan pääohjelmaan!

Arvauspeli.java

Tämän viikon tehtävän 2.4 arvauspeli oli seuraavanlainen:

Ensin ohjelma pyytää syötettävien lukujen lukumäärän pelinjohtajalta ja sitten itse luvut. Sovitaan että tässä pelissä sallittuja ovat vain luvut 1–21, muut hylätään. Sama luku saa esiintyä useampaankin kertaan.

Tämän jälkeen pelaaja istuu koneen ääreen ja peli alkaa. Pelaaja yrittää arvata koneelle syötettyjä lukuja. Peli päättyy, kun pelaaja arvaa jonkin pelinjohtajan syöttämistä luvuista, ja tulos on tarvittujen arvauskertojen lukumäärä.

Arvauspeli on jo sen verran monimutkainen, että se toteuttaminen kaikkineen pääohjelmassa ei ole kovin viisasta eikä kaunista. Muokkaa siis ratkaisua siten, että ohjelmoit hyvä metodeita, joilla ohjelman toiminta saadaan selkeäksi.

Seuraavan kaltaiset metodit saattavat olla käyttökelpoisia:

Kehittele tarpeen mukaan muitakin metodeita.