Fakultet for teknologi Eksamensoppgave i IFUD1025 Programmering i Java Faglig kontakt under eksamen: Vuokko-Helena Caseiro Tlf.: +39 06 51 26 063 Eksamensdato: 4. mai 2016 Eksamenstid (fra - til): 9:00 13:00 Tillatte hjelpemidler: Alle skrevne og trykte hjelpemidler. Enkel numerisk kalkulator. Kalkulatoren kan maksimalt ha funksjonalitet tilsvarende Citizen SR270 College eller HP30S. Annen informasjon: Målform/språk: Bokmål Antall sider (uten forside): 5 Antall sider vedlegg: 1
Oppgave 1 ( 40 % ) Når man søker etter informasjon, må man gjerne taste inn et søkeord. Det kan da skje at man staver feil. Du skal lage en klasse Søkeordhjelper med søkeordet som objektvariabel. Når det i den inntastede teksten enten mangler noen tegn eller fins noen ekstra tegn, vil Søkeordhjelper-metoder greie å påvise at den inntastede teksten ligner på søkeordet. Eksempel: Vi ønsker å søke etter "PANNEKAKE". Hvis vi taster inn "PANKAKE" (som mangler noen tegn) eller "PANNNEKAKKE" (som har noen ekstra tegn), vil Søkeordhjelper-metoder kunne påvise at de ligner på søkeordet. "PAENKAKE" derimot ligner ikke fordi E og N er i gal rekkefølge. En tekst tynn er tynnere enn en tekst tykk hvis alle tegnene i tynn fins i tykk og tegnene i tynn kommer i samme rekkefølge i både tynn og tykk. Med andre ord: tynn er tynnere enn tykk hvis det for hver posisjon i i tynn går an å velge en posisjon i-tvilling i tykk slik at - tegnet i posisjon i i tynn er lik tegnet i posisjon i-tvilling i tykk, og - for hver posisjon i i tynn unntatt den siste, er i+1-tvilling større enn i-tvilling. Når tynn er tynnere enn tykk, sier vi også at tykk er tykkere enn tynn. Vedlegget i dette eksamenssettet inneholder String-metoder som kan komme til nytte. Eksemplet fortsatt: - "PANKAKE" er tynnere enn "PANNEKAKE" (velg posisjonene 0, 1, 2, 5, 6, 7, 8 i "PANNEKAKE" som tvillinger til hhv. 0, 1,, 6 i "PANKAKE"). - "PANNEKAKE" er tynnere enn "PANNNEKAKKE". - "PAENKAKE" er ikke tynnere enn "PANNEKAKE" fordi E-en og N-en kommer i annen rekkefølge. a) Begynn å lage klassen Søkeordhjelper for å representere et søkeord. Det skal være en objektvariabel søkeordet av type String. Lag en passende konstruktør. Eksemplet fortsatt: Vi lar søkeordet være "PANNEKAKE". b) Lag en Søkeordhjelper-metode private static boolean erdenførstetynnereenndenandre(string tynn, String tykk) som returnerer true hvis tynn er tynnere enn tykk, og false ellers. Eksemplet fortsatt: For tynn lik "PANKAKE" og tykk lik "PANNEKAKE" skal metoden returnere true. c) Lag en Søkeordhjelper-metode public boolean ertynnereenn(string inntastet) som returnerer true hvis søkeordet er tynnere enn inntastet, og false ellers. Eksemplet fortsatt: For inntastet lik "PANNNEKAKKE" skal metoden returnere true. d) Lag en Søkeordhjelper-metode public boolean ertykkereenn(string inntastet) som returnerer true hvis søkeordet er tykkere enn inntastet, og false ellers. Eksemplet fortsatt: For inntastet lik "PANKAKE" skal metoden returnere true. e) Lag en Søkeordhjelper-metode public boolean lignerpå(string inntastet) som returnerer true hvis enten søkeordet er tynnere enn inntastet, og inntastet er høyst dobbelt så langt som søkeordet eller søkeordet er tykkere enn inntastet, og søkeordet er høyst dobbelt så langt som inntastet. Ellers skal metoden returnere false. Eksemplet fortsatt: Metoden skal returnere true for "PANNE" og false for "PANN". 2
Oppgave 2 ( 60 % ) Vi ønsker å planlegger reiser. En reise består av noen flygninger. Hver flygning består av en avreise (et tidspunkt og et sted) og en ankomst (et tidspunkt og et sted). Eksempel: En reise består av følgende to flygninger. Alle tidspunkter er uttrykt i lokal tid. - Flygning 1: fra Tokyo 4. mai 2016 kl. 04:00 til Roma kl. 14:00 samme dag. - Flygning 2: fra Roma 4. mai 2016 kl. 16:00 til Lima kl. 02:00 neste dag Mellom de to flygningene er det altså en mellomlanding på to timer i Roma. Vi ønsker å kunne regne på det som har med tiden å gjøre. For eksempel: Hvor mye må klokka stilles om? Hvor lenge varer en flygning? Hvor lenge varer hele reisen? Er mellomlandingene passe lange? Regningen kompliseres litt av at klokka ikke er det samme overalt. Jordkloden er oppdelt i tidssoner. Tidssone x har et avvik på x hele timer fra sone 0. For eksempel er London i tidssone 0; Roma og Oslo er i tidssone 1 (en time foran tidssone 0); Tokyo er i tidssone 9; Lima er i tidssone -5. Når for eksempel klokka er 16:00 i London, er den 17:00 i Roma, 01:00 neste dag i Tokyo og 11:00 i Lima. Vi bestemmer oss for at vi ikke er interessert i informasjon om nøyaktig dato, som for eksempel 4. mai 2016. I stedet velger vi hva som skal være dag 0 og nummerer reisedagene. Dessuten bestemmer vi at klokkeslett alltid skal være heltall x slik at x 0 og x < 24; vi ser altså bort fra minutter. Vi vil angi et tidspunkt ved hjelp av en tidssone, en dag og et klokkeslett (tre heltall). Vi kunne ha laget en egen klasse for tidspunktet (med tre objektvariabler), men i stedet velger vi å lage TidOgSted-klassen (med fire objektvariabler: tre for tidspunktet og én for stedet). Eksemplet fortsatt: Vi velger å la reisen starte på dag 0. Da kan nå reisen uttrykkes slik: - Flygning 1: fra Tokyo i sone 9 på dag 0 kl. 4 til Roma i sone 1 på dag 0 kl. 14. - Flygning 2: fra Roma i sone 1 på dag 0 kl. 16 til Lima i sone -5 på dag 1 kl. 2. Vi vil etterhvert kunne regne ut blant annet følgende: - Under den første flygningen må klokka stilles 8 timer bakover; under den andre flygningen må den stilles 6 timer bakover. - Første flygning varer 18 timer og andre flygning varer 16 timer. Hele reisen varer 36 timer. - Mellomlandingen i Roma varer 2 timer. a) Begynn å lage klassen TidOgSted for å representere et tidspunkt og og et sted. Den første objektvariabelen skal angi stedet og de tre siste skal angi tidspunktet; vi skal altså ha sted av type String sone av type int dag av type int klokkeslett av type int slik at 0 klokkeslett < 24 Lag en passende konstruktør. Anta at sted og sone stemmer overens. Eksemplet fortsatt: Vi trenger fire TidOgSted-objekter: Det første med sted lik "Tokyo", sone lik 9, dag lik 0, klokkeslett lik 4; det andre med "Roma", 1, 0, 14; det tredje med "Roma", 1, 0, 16; det fjerde med "Lima", -5, 1, 2. b) Lag en TidOgSted-metode public int finnklokkeomstilling(tidogsted annet): Metoden skal returnere antall timer som klokka må stilles om når man reiser fra sone til annet-objektets sone. Antall timer skal være positivt når klokka må stilles framover 3
negativt når klokka må stilles bakover 0 hvis klokka ikke må stilles om Eksemplet fortsatt: For det første objektet med det andre objektet som argument (reise fra sone 9 til sone 1), skal metoden returnere -8 (fordi 1 9 = -8). For det andre objektet med det første objektet som argument (reise fra 1 til sone 9), skal metoden returnere 8 (fordi 9-1 = 8). Når vi regner på tid i klassen TidOgSted, er det nyttig å se tidspunktene som punkter langs en tallinje. Punktene er heltall, og vi vil kalle dem for «tallpunkter» (for å skille dem fra «tidspunkter»). For å omforme et gitt tidspunkt (sone, dag, klokkeslett) til et tallpunkt bruker vi formelen tallpunkt = 24 * dag + klokkeslett sone Klokkeslett 0 på dag 0 i sone 0 er nullpunktet. Det er slik at tallpunktet til et tidspunkt er lik antall timer forskjell mellom tidspunktet og nullpunktet slik at - tallpunktet er positivt hvis tidspunktet kommer etter nullpunktet, og - tallpunktet er negativt hvis tidspunktet kommer før nullpunktet, og - tallpunktet er 0 hvis tidspunktet er nullpunktet. Eksemplet fortsatt: Reisen kan nå uttrykkes slik: - Flygning 1: fra Tokyo ved tallpunkt -5 (fordi 24 * 0 + 4 9 = -5) til Roma ved tallpunkt 13 (fordi 24 * 0 + 14 1 = 13) - Flygning 2: fra Roma ved tallpunkt 15 (fordi 24 * 0 + 16 1 = 15) til Lima ved tallpunkt 31 (fordi 24 * 1 + 2 (-5) = 31). c) Lag en TidOgSted-metode private int finntallpunkt(): Metoden skal returnere dette tidspunktets tallpunkt. Eksemplet fortsatt: For det første objektet skal metoden returnere -5; for det andre 13; for det tredje 15; for det fjerde 31. d) Lag en TidOgSted-metode public int finnantalltimerdifferanse(tidogsted annet): Metoden skal returnere differansen mellom dette tidspunktet og annet-tidspunktet slik at returverdien er positiv hvis dette tidspunktet kommer før annet-tidspunktet, og returverdien er negativ hvis dette tidspunktet kommer etter annet-tidspunktet, og returverdien er 0 dersom tidspunktene er like. Eksemplet fortsatt: Hele reisen fra Tokyo til Lima (inkludert mellomlandingen i Roma) tar 36 timer. Så metoden skal returnere 36 for Tokyo-objektet med Lima-objektet som argument, og metoden skal returnere -36 for Lima-objektet med Tokyo-objektet som argument. Når to flygninger kommer etter hverandre, skal ventetiden mellom dem enten være så kort at passasjeren lett kan vente på flyplassen, eller så lang at passasjeren får god tid til å overnatte. Vi uttrykker dette mer presist som følger: La et første tidspunkt og sted (første flygnings tenkte ankomst) og et annet tidspunkt og sted (andre flygnings tenkte avreise) være gitt. Ventetiden er differansen mellom tidspunktene. Dette er en gjennomførlig mellomlanding hvis stedet er det samme og dessuten 4
- enten er ventetiden mellom tre og seks timer (passasjeren venter da på flyplassen) - eller ventetiden er minst 24 timer, men ikke mer enn et valgfritt antall timer (passasjeren overnatter). e) Lag en TidOgSted-metode public boolean gjennomførligmellomlanding(int maxovernatting, TidOgSted annet): Vurder ankomst ved dette tidspunktet på dette stedet og avreise ved annet-tidspunktet fra annet-stedet. Metoden skal returnere true hvis mellomlandingen er gjennomførlig når maxovernatting brukes som grense for ventetiden ved overnatting. Ellers skal metoden returnere false. Eksemplet fortsatt: Vurder ankomst som oppgitt i andre TidOgSted-objekt og avreise som oppgitt i tredje TidOgSted-objekt. Stedet er det samme (nemlig Roma), men ventetiden er bare på to timer. Så mellomlandingen er ikke gjennomførlig (uansett hva maxovernatting er). f) Lag en TidOgSted-metode public boolean gjennomførligmellomlandingutenovernatting(tidogsted annet): Vurder ankomst ved dette tidspunktet på dette stedet og avreise ved annet-tidspunktet fra annet-stedet. Metoden skal returnere true hvis mellomlandingen er gjennomførlig og den dessuten er slik at passasjeren slipper å overnatte. Ellers skal metoden returnere false. Vi oppgir klassen Flygning for å representere en flygning: class Flygning { private final TidOgSted avreise; private final TidOgSted ankomst; public Flygning(TidOgSted avreise, TidOgSted ankomst) { this.avreise = avreise; this.ankomst = ankomst; public TidOgSted getavreise() { return avreise; public TidOgSted getankomst() { return ankomst; /* * Er mellomlandingen mellom denne flygningen og flygning f2 gjennomførlig, og * og er den dessuten slik at passasjeren slipper å overnatte? */ public boolean gjennomførligmellomlandingutenovernatting(flygning f2) { return ankomst.gjennomførligmellomlandingutenovernatting(f2.getavreise()); // Flygning g) Begynn å lage klassen Reise for å representere en reise. En objektvariabel av type Flygning[] skal inneholde flygningene i den rekkefølgen de ønskes foretatt. Lag en passende konstruktør. h) Lag en Reise-metode public boolean gjennomførligemellomlandingerutenovernattinger(): Metoden skal returnere true hvis alle mellomlandingene er gjennomførlige og dessuten slik at passasjeren slipper å overnatte. Ellers skal metoden returnere false. 5
Vedlegg: Klassen java.lang.string Klassen benyttes til å håndtere strenger. Klassen er immutabel. Alle metoder med returtype String returnerer en referanse til et nytt objekt av denne klassen. Konstruktør: public String(String tekst) Metoder: public char charat(int indeks) Metoden returnerer tegnet på den gitte posisjonen (indeksen). Posisjonene nummereres fra og med 0. Hvis indeks er negativ eller større eller lik lengden på strengen, kastes unntaket IndexOutOfBoundsException. public int indexof(int tegn) public int indexof(int tegn, int fraindeks) public int indexof(string deltekst) public int indexof(string deltekst, int fraindeks) Metodene brukes til å søke etter et enkelt tegn eller en deltekst i strengen. Datatypen til parameteren tegn er int; du kan likevel sende inn et vanlig tegn (datatypen char) som argument. Metodene returnerer posisjonen til tegnet eller posisjonen til begynnelsen av delteksten. Dersom tegnet eller delteksten ikke eksisterer, returnerer metodene 1. Første posisjon i strengen har nummer 0. To av metodene tar fraindeks som argument; det gjør det mulig å begynne søket på en annen posisjon (indeks) enn 0. Dersom fraindeks er mindre enn 0, begynner søket i begynnelsen av strengen. Dersom fraindeks er større enn strengens lengde - 1, returneres 1. Dersom deltekst er lik null, kastes unntaket NullPointerException. public int length() Metoden returnerer antall tegn som strengen består av, inkludert alle blanke. public String substring(int startindeks) public String substring(int startindeks, int sluttindeks) Metodene returnerer en del av strengen. Den første metoden returnerer hele strengen fra og med startindeks, mens den andre returnerer strengen fra og med posisjon startindeks til og med posisjon (sluttindeks - 1). Ugyldige argumentverdier (eksempel: sluttindeks større enn strengens lengde) kaster unntaket IndexOutOfBoundsException. public String replace(char gmltegn, char nytttegn) Metoden returnerer en streng der alle forekomster av et bestemt tegn (første parameter) er erstattet med et annet tegn (andre parameter). public boolean startswith(string prefiks) Metoden tester om strengen starter med prefiks. Metoden returnerer true hvis prefiks er en delstreng av strengen fra og med posisjon 0, false ellers. public int compareto(string denandrestrengen) Metoden sammenligner to strenger i henhold til Unicode-rekkefølgen. Metoden returnerer en negativ verdi dersom strengen vi sender meldingen til, ligger foran denandrestrengen i rekkefølgen, en positiv verdi dersom den ligger etter, og 0 dersom strengene er like. Metoden kaster unntaket NullPointerException dersom denandrestrengen er lik null. Metoden fungerer ikke for æ, ø og å. public boolean equals(object detandreobjektet) Metoden returnerer true dersom strengene er like, ellers false. Metoden returnerer false også dersom detandreobjektet er null eller tilhører en annen klasse enn String. Metoden fungerer for æ, ø og å. 6