Föreläsning 4: Vektorer

I fysiken är en vektor en storhet med två eller tre komponenter. I datalogin är en vektor (eng. array) ett dataobjekt med flera komponenter av samma typ, inte nödvändigtvis tal. I alla javaprogram finns en vektor args omnämnd inom parentes efter main. Vi börjar med att se på den.

String[] args

Detta är en deklaration av en vektor args vars komponenter är av typen String. Hur många komponenterna är framgår inte av deklarationen. Det bestäms i själva verket inte förrän i körningsögonblicket. Om programmet Kolla körs igång med kommandot
    java Kolla vilka sjysta bananer!
blir dom tre extraorden komponenterna i vektorn args. Konstigt nog numreras vektorkomponenter 0,1,2,..., så i detta fall gäller
    args[0] = "vilka"
    args[1] = "sjysta"
    args[2] = "bananer!"
Det här är tre vanliga textobjekt som kan användas när som helst under körningen, till exempel så här:
    System.out.print("Raka " + args[2]);
Talet innanför hakarna kallas index, och för stort index ger felavbrott, till exempel i vårt fall args[3].

Andra vektorer

Med tomma hakar efter typnamnet deklarerar man en vektor.
    int[] heltalsvektor;
    char[] teckenvektor;
Variablerna args, heltalsvektor och teckenvektor är minnesutrymmen som bara rymmer en pekare till den plats i minnet där vektorns alla komponenter finns. Själva vektorn kan skapas på tre sätt.
  1. Med en vektorkonstant, alltså en komponentuppräkning inom måsvingar.
        heltalsvektor = {17, 666, 4711};
        teckenvektor = {'K', 'T', 'H'};
        String[] fras = {"En", "vektor", "med", "fem", "komponenter"};
    
  2. Med ett anrop till en funktion vars värde är en vektor.
        String[] fillista = (new File("datalogi")).list();
    
  3. Med ordet new, använt så här:
        // Plats för tre komponenter
        heltalsvektor = new int[3]; 
        // Hela årets regnmätningar
        double[] regn = new double[365]; 
    
I det sistnämnda fallet bör man ge komponenterna startvärden med en slinga av följande typ.
    for (int i = 0; i < 365; ++i) 
        regn[i] = 0.0;

Inläsning från fil till vektor

Vi tänker oss att filen data.reg innehåller personnummer och namn med en person per rad. Vi kan läsa in den i en vektor på följande sätt. Vektorn har plats för tusen personer, men vi utnyttjar bara n platser.
class Register1 {
    public static void main(String[] args) {
	String[] person = new String[1000];
	int n = 0;  /* antal personer */
	while (!Mio.eof()) { 
	    person[n] = Mio.getLine();
	    ++n;
	}
    }
}

För att Mio-anropen ska läsa från filen måste programmet startas med
    java Register1 < data.reg
En nackdel med det är att inte tangenterna kan användas för inmatning under körningen. Om man vill programmera in filinläsningen blir det krångligare. Man måste importera en objekttyp från paketet java.io.
import java.io.*;
class Register2 {
    public static void main(String[] args) {
	String[] person = new String[1000];
	int n = 0;  /* antal personer */
	BufferedInputStream datafil = Mio.openRead("data.reg");
	while (!Mio.eof()) { 
	    person[n] = Mio.getLine(datafil);
	    ++n;
	}
    }
}

Då kan man kosta på sej att först läsa igenom filen en gång för att få reda på antalet personer och sedan tillverka en vektor med just detta antal.
import java.io.*;
class Register3 {
    public static void main(String[] args) {
	BufferedInputStream datafil = Mio.openRead("data.reg");
	int n = 0;
	while(!Mio.eof(datafil)) {
	    Mio.getLine(datafil); 
	    ++n;
	}

	String[] person = new String[n];

	datafil = Mio.openRead("data.reg"); // Läs filen från början
	for (int i = 0; i < n; ++i)
	    person[n] = Mio.getLine(datafil);
    }
}

Linjär sökning i vektor

Att söka efter en person bland n personer kan ta lång eller kort tid beroende på hur stor otur man har. I genomsnitt måste man kolla n/2 personer innan man hittar den rätta. Om man söker efter någon som inte finns måste man alltid kolla alla n personerna innan man kan ge upp.

Dessa båda tal anger komplexiteten för algoritmen linjär sökning. Genomsnittlig komplexitet är n/2 och värstafallskomplexiteten är n. Om man använder en for-slinga är det viktigt att bryta den så snart man funnit vad man söker, annars blir det alltid värstafallskomplexitet!

    for(int i = 0; i < n; ++i) 
        if (pnr.equals(person[i].substring(0, 11))) {
            System.out.println(person[i].substring(11));
            break;
	}
Om vektorn är ordnad på personnummer finns en mycket snabbare algoritm som heter binär sökning.

Utskrift i fönster

Alla fönster, knappar, menyer, dialogrutor etc är objekt ur paketet java.awt och man måste alltså inleda javafilen med
    import java.awt.*;                                    
Om man sedan vill ha fram ett fönster med viss rubrik, färg och storlek och förse det med en knapp med viss text skriver man t ex så här.
import java.awt.*;

class RitaRuta {
    public static void main(String[] args) {
	Frame ruta = new Frame("Utmatningsfönster");
	ruta.setBackground(Color.yellow); // Behövs inte
	ruta.setSize(400, 60); // Bredd, höjd
	ruta.add(new Button("Denna text skrivs i rutan"));
	ruta.show();
    }
}

Särskilt användbar är dialogrutan för filval, som Weiss beskriver i avsnitt D.2.3.

^ Upp till kurssidan.


Sidansvarig: <efo@nada.kth.se>
Senast ändrad 6 november 2000
Tekniskt stöd: <webmaster@nada.kth.se>