wiki:ohj2k10vk1T4
Last modified 8 years ago Last modified on 2010-04-14 01:03:21

1)

a) Mitä seuraava aliohjelma yrittää tehdä? (2p)

    public static int[ ][ ] teeJuttu(int[ ][ ] a, int b)
    {
        int[ ][ ] c;
        for(int i; i<a.length; i++)    for(int j; j<a.length; j++) c[j][i] = a[j][i] * b;
        return c;
    }

b) Mitä siinä on mielestäsi vialla, jos mitään? (2p)

c) Toteuta itse vastaava metodi, mutta paremmin. Perustele (lyhyesti) miksi oma tapasi on parempi. (2p)

Kyseessähän on siis metodi, joka koettaa kertoa kokonaislukumatriisin kokonaisluvulla.

Puutteita ovat:

-Muuttujia ei alusteta eikä matriisille anneta kokoa,

-Muuttujat on nimetty ihan miten sattuu,

-Koodia ei ole jäsennelty oikeastaan mitenkään,

-Koodia ei ole kommentoitu,

-Indeksit menevät kertoessa ristiin, eli rivi-indeksiä käytetään sarakkeisiin ja päinvastoin,

-Jälkimäisen for-silmukan ehtolauseena pitäisi olla a[i].length.

Koodi ei sellaisenaan käänny, koska muuttujia (c, i ja j) ei alusteta. Koodi se ei käy matriisin kaikkia alkioita läpi jos matriisi ei ole neliömuotoinen, ja matriisia läpikäydessä saattaa tulla ArrayIndexOutOfBoundsException?. Koodin lukeminen on hankalaa jäsennyksen, dokumentaation puutteen sekä muuttujien ja aliohjelman epäselvien nimien seurauksena.

Jos käsiteltävät matriisit ovat isoja, ei palautusta varten kannata välttämättä luoda uutta matriisia, vaan kannattaa ennemmin tehdä muutokset vanhaan, jos tämän tekeminen on sallittua. Toisinaan vanhan matriisin säilyttäminen on kuitenkin suotavaa, ja tällöin uusi matriisi on pakko luoda.

For-silmukassa olisi hyvä olla aaltosulut, mutta ohjelma toimii ilmankin (tämä oli eräs koodin jäsennyksen epäkohdista). Joidenkin mielestä return-lauseen sijainnissa oli jotain vikaa, mutta näin ei kuitenkaan ole asian laita.

Alla hieman selkeämpi versiointi aiheesta:

            public static int[][] kerroMatriisiKokonaisluvulla2(int[][] matriisi, int kokonaisluku)
            {
            	int[][] tulosMatriisi = new int[matriisi.length][];
            	for (int rivi = 0; rivi < matriisi.length; rivi++)
            	{
            		tulosMatriisi[rivi] = new int[matriisi[rivi].length];
            		for (int sarake = 0; sarake < matriisi[rivi].length; sarake++) {
            			tulosMatriisi[rivi][sarake] = matriisi[rivi][sarake] *kokonaisluku;
           			}
            	}
            	return tulosMatriisi;
            }

Homman voi tehdä myös esim. näin, jos alkuperäiseen matriisiin saa tehdä muutoksia. Alkuperäisessä metodissa näin ei kuitenkaan tehty, joten metodi ei säilytä alkuperäistä toiminnallisuutta sellaisenaan, joskaan matriisi ei myöskään ollut "final". Vastaavasti metodi ei kuitenkaan luo toista matriisia, joten muistin käytön kannalta toteutus on tehokkaampi.

            public static int[][] kerroMatriisiKokonaisluvulla(int[][] matriisi, int kokonaisluku)
            {
            	for (int rivi = 0; rivi < matriisi.length; rivi++)
            	{
            		for (int sarake = 0; sarake < matriisi[rivi].length; sarake++) {
            			matriisi[rivi][sarake] *= kokonaisluku;
            		}
            	}
            	return matriisi;
            }

C-kohdan perusteluiksi riitti se, että kertoi parannelleensa jotain b) kohdan puutteita. Pelkkä "koska tämä toimii" tai "tämä on parempi" ei itsessään riittänyt.