Ilkka Koivistoinen 13.02.2002 | |
Edellinen |
Taulukko on jono samaa tietotyyppiä tai olioita olevia muistipaikkoja. Esimerkiksi edellä ollut char merkkijono[] = new char[20]; on 20 kertaa yhden merkin pituinen muistialue, jonka paikkoihin viitataan indeksin i avulla esimerkiksi merkkijono[i-1]. Ensimmäinen taulukon muistipaikka on paikassa merkkijono[0], toinen paikassa merkkijono[1] jne.
int luvut[] = new int[200] varaa muistia 200 int –tyypin verran (siis 200 * 32 bittiä).
Seuraavassa esimerkissä on tehty 5 kokonaisluvun taulukko ja tulostettu se.
Esimerkki 23.
import Lue;
public class E23
{
public static void main (String args[])
{
int[] taulu =
{3,2,5,6,3};
System.out.println("taulu[1] = " + taulu [1]);
System.out.println("taulu[2] = " +
taulu [2]);
System.out.println("taulu[3] = " + taulu [3]);
System.out.println("taulu[4] = " +
taulu [4]);
System.out.println("taulu[5] = " + taulu [5]);
// ja sitten sama for –silmukalla
int i;
for (i = 1; i <=
5; i++)
System.out.println("taulu["+i+"] = " + taulu [i]);
}
}
Saitko virheilmoituksen java.lang.ArrayIndexOutOfBoundsException? Tämä aiheutui siitä, että yritit tulostaa muistipaikkaa taulu[5]. Kuitenkin 5:s muistipaikka on taulu[4]:ssä. Tämä johtuu siitä, että java aloittaa indeksoinnin aina 0:sta. Korjaa edellistä ohjelmaa siten, että indeksit ovat 0,..,4. Java siis tarkistaa ajoaikaiset taulukon indeksit. ( for (i = 0; i < 5; i++) )
taulu[0] | taulu[1] | taulu[2] | taulu[3] | taulu[4] |
Eräs tapa välttää sekaannus muistin käytössä on käyttää length -muuttujaa, joka ilmoittaa taulukon pituuden eli talletettujen numeroiden määrän taulukossa. Esimerkiksi for -silmukka voidaan toteuttaa seuraavasti
int taulu = new int[100];
for (int i=0;i<taulu.length;i++) …; // taulu.length on nyt 5
Tällöin silmukkaindeksin karkaaminen yli viimeisen arvon on mahdotonta.
Esimerkki 24.
Tehdään kaksiulotteinen taulukko
// kaksiulotteinen taulukko
int[][]
matriisi=new int[10][10];
for ( i=0;
i<taulu.length; i++)
for ( j=0; j<taulu[i].length; j++)
matriisi[i][j] = j+i+1;
// tulostus
for (i=0;
i<taulu.length ;i++)
System.out.print(taulu[i]+" ");
System.out.println("\n");
for (i=0;
i<taulu.length ;i++)
{
for (j=0; j<taulu[i].length; j++)
System.out.print(matriisi[i][j]+" ");
System.out.println();
}
}
}
Java ei suoraan tue moniulotteisia taulukoita, mutta ne luodaan taulukkona, jonka alkiona on taulukko. Tätä voidaan jatkaa vaikka kuinka moneen sisäkkäiseen indeksiin asti. Edellisessä esimerkissä oli kaksinkertainen silmukka. Tutki tarkkaan, että ymmärrät sen toimintaperiaatteen.
Esimerkki 25.
Tähtikolmio
public class E25
{
public static
void main (String args[])
{
int max = 10;
String[] merkkijonot=new
String[max];
int i,j;
// Tehdään tähtikolmio
for (j=0; j<max;
j++) // j < merkkijonot.length olisi
parempi
{
for
(i=0; i<=j; i++)
System.out.print("*");
System.out.println();
}
// Tehdään kirjaintaulukko
for (i=0;
i<max; i++)
merkkijonot[i] = "abcdefghij";
for (i=0;
i<max; i++)
System.out.println(merkkijonot[i]);
// Tehdään kirjainkolmio
for (i=0 ;
i<max ; i++)
{
for (j=0; j<i; j++)
System.out.print(merkkijonot[i].charAt(j));
System.out.println();
}
}
}
{Jos olet opetellut esim. pascalia, niin lue seuraava: Taulukkoja käsiteltäessä indeksin alkaminen 0:sta tuottaa usein paljon hankaluuksia. Tämän voi aina kiertää määrittelemällä taulukon todelliseksi kooksi yhtä suurempi, mitä tarvitaan ja jättämällä 0:s rivi tai sarake käsittelemättä.]
Silmukkarakenteiden yhteydessä taulukot ovat mitä parhain mahdollinen talletusmuoto ja seuraavissa esimerkeissä on yritetty havainnollistaa niiden käyttöä silmukkarakenteiden kanssa.
Esimerkki E26
import Lue;
public class E26 // Tarkista laskimella, että
ohjelmasi laskee oikein!!!
// Luetaan näppäimistöltä n lukua ja lasketaan
niiden keskiarvo ja keskihajonta
{
public static
void main (String args[])
{
int n;
System.out.println("Monenko
luvun keskiarvo lasketaan");
n=Lue.kluku();
while (n<0 || n>100)
{
System.out.println("Lukujen määrän pitäisi olla välissä 0 - 100. Anna
uudestaan");
System.out.println("Monenko luvun keskiarvo lasketaan");
n=Lue.kluku();
}
int i, j, max
= n; // max määrittää taulukon
pituuden
double[] luvut=new double[max]; //
double summa,
karvo,khajonta;
for (i=0; i<max; i++)
{
System.out.print("Anna "+i+".s luku ");
luvut[i]=Lue.dluku();
}
summa = 0.0D;
//keskiarvo
for (i=0;
i<max; i++)
summa=summa+luvut[i];
karvo=summa/max;
//keskihajonta
summa=0.0D;
for (i=0;
i<max; i++)
summa=summa+Math.pow(karvo-luvut[i],2); //pow(x,2) on x toiseen
khajonta=Math.sqrt(summa/max);
//neliöjuuri
//Tulostus
System.out.println("Tulos:\nLukujen");
for(i=0;i<max;i++)System.out.print(luvut[i]+"
");System.out.println();
System.out.println("tunnusluvut ovat:\nLukuja: "+max+"\nKeskiarvo on : "+karvo
+
"\nKeskihajonta :
"+khajonta);
}
}
Esimerkki 27.
import Lue;
public class E27
// Luetaan näppäimistöltä n
lukua ja tulostetaan niistä suurin
{
public static void main (String args[])
{
int n;
System.out.println("Montako
lukua annat");
n=Lue.kluku();
while (n<0
|| n>100)
{
System.out.println("Lukujen määrän pitäisi olla välissä 0 - 100. Anna
uudestaan");
System.out.println("Montako lukua annat");
n=Lue.kluku();
}
int max,i;
int[]
luvut = new int[n];
for (i=0;
i<n; i++)
{
System.out.print("Anna "+(i+1)+".s luku ");
luvut[i]=Lue.kluku();
}
max=-10000; // Laita tilalle
-maxinteger, kun saat sen selville
// toinen parempi ratkaisu on asettaa
max = luvut[0]: ja kelata taulukko läpi toisesta alkiosta
alkaen
for
(i=0; i<n; i++)
if
(luvut[i]>max)
max=luvut[i];
//Tulostus
System.out.println("Tulos:\nLuvuista");
for(i=0;i<n;i++)
System.out.print(luvut[i]+" ");
System.out.println();
System.out.println("suurin on "+max);
}
}
Esimerkki 28.
import java.util.Random; // satunnaislukuja varten
import
Lue;
public class E28 // Arvotaan 1000
kokonaislukua ja tulostetaan ne
{
public static
void main (String args[])
{
Random SatunnaisLuku = new
Random(); // Tyyppiä random oleva satunnaislukugeneraattori
int
i,j,tmp,n=1000;
int[] taulukko=new int[n];
for (i=0;
i<n; i++)
/*
SatunnaisLuku.nextDouble() palauttaa double-tyyppisen luvun välillä [0,1[.
Huomaa, että 1 ei
kuulu
tähän
väliin.
SatunnaisLuku.nextDouble()*n antaa arvoksi double-luvun välillä 0 <= x <
n
ja (int) ottaa siitä kokonaisosan (pyöristys vai
katkaisu?)
*/
taulukko[i] = (int) (SatunnaisLuku.nextDouble()*n);//satunnainen kokonaisluku
välilllä 0 <= x < n
//Tulostus
System.out.println("Tulos\nSatunnaisluvut ovat");
for (i=0;
i<n; i++)
System.out.print(taulukko[i]+" ");
System.out.println()
}
}
Esimerkki 30.
Kuplalajittelualgoritmi. Esimerkki sisäkkäisistä silmukoista
import java.util.Random; // satunnaislukuja varten
import Lue;
public class E29
// Arvotaan 1000 kokonaislukua ja tulostetaan ne lajiteltuna
{
public static void main (String args[])
{
Random SatunnaisLuku = new Random(); // Tyyppiä random oleva satunnaisluku
int i,j,k,tmp,n=1000;
int[] taulukko=new int[n];
for (i=0; i<n; i++)
taulukko[i] = (int) (SatunnaisLuku.nextDouble()*n);//satunnainen kokonaisluku välilllä 0 <= x < n//Tulostus
System.out.println("Tulos\nSatunnaisluvut ovat");
for(i=0; i<n; i++)
System.out.print(taulukko[i]+" ");
System.out.println();//Lajittelu
for (i=0; i<n-1; i++)
{
k=i;
for (j=i+1 ; j<n ; j++)
if (taulukko[j]>taulukko[k])
k=j;// Suoritetaan vaihto jos tarpeellista
if (i != k)
{
tmp=taulukko[i];
taulukko[i]=taulukko[k];
taulukko[k]=tmp;
}
}//Tulostus lajittelun jälkeen
System.out.println("Tulos\nSatunnaisluvut ovat lajiteltuna");
for (i=0; i<n; i++)
System.out.print(taulukko[i]+" ");
System.out.println();
}
}
Käy lajittelualgoritmi huollella läpi. Sen idea on jakaa lukujono kahtia alku ja loppuosaan, missä alun k alkiota ovat järjestyksestä ja loppuosan k+1,..,n alkioista haetaan suurin, joka vaihdetaan k+1:n alkion kanssa. Lisää arvottavien lukujen määrää ensin 10000 ja sitten 100000 jne. Jätä tulostus pois kunhan olet varmistunut, että ohjelma toimii ja testaa. Kuinka nopea koneesi java –tulkilla oikeastaan onkaan?
Taulukon alkioiden poisto ja lisäys on käsitelty olio-ohjelmoinnin kurssin esimerkissä 40.
Seuraavassa on tehtäviä, jotka lähtevät helpommista ja päätyvät varsin hankaliin ohjelmointitehtäviin. Jätä väliin ne tehtävät, joissa et ymmärrä matemaattista kontekstiä, ne on tarkoitettu laajan matematiikan pitemmälle ehtineille opiskelijoille.
Vastaukset
Ilkka Koivistoinen 13.02.2002 | |
Edellinen |