Side 1 av 9 NTNU Norges teknisk-naturvitenskapelige universitet BOKMÅL Fakultet for fysikk, informatikk og matematikk Institutt for datateknikk og informasjonsvitenskap Sensurfrist: 15. juni Eksamen i fag SIF8005 Programmering Torsdag 10. mai 2001 kl 0900-1400 Hjelpemidler A2: Kalkulator ikke tillatt Bestemte trykte hjelpemidler tillatt: * Winder & Roberts: Developing Java Software * Lervik & Havdal: Programmering i Java * Lewis & Loftus: Java Software Solutions * Lemay & Cadenhead: Teach Yourself Java 2 in 21 Days * Lemay & Cadenhead: Lær Java 2 på 21 dager * IDI: Løsningsforslag til Øving 4, SIF8005, vår 2001 Faglig kontakt under eksamen: Førsteamanuensis Guttorm Sindre, tlf. 94479 Universitetslektor Steinar Line, tlf. 9086 4408 Merk: All programmering på eksamen skal foregå i Java. Prosentsatser viser hvor mye hver oppgave teller innen settet. Innen en oppgave teller de ulike deloppgaver likt, med mindre annet er angitt. Lykke til!
Side 2 av 9 Oppgave 1 (30%) Gitt følgende tre klasser Person, Student og Ansatt: public class Person{ private String navn; private int alder; public Person(String navn, int alder){ this.navn=navn; this.alder=alder; public String hentnavn(){ return navn; public int hentalder(){ return alder; public class Student extends Person{ private int studentnr; private int linjer; //representerer ca antall kodelinjer //studenten har programmert i løpet av studiet public Student(String navn, int alder, int studentnr){ super(navn, alder); this.studentnr=studentnr; linjer=0; public int hentstudentnr(){ return studentnr; public void oeklinjer(int oekning){ linjer = linjer + oekning; public int hentlinjer(){ return linjer; public class Ansatt extends Person{ private int ansattnr; private static int nyttansattnr; public Ansatt(String navn, int alder){ super(navn, alder); this.ansattnr=nyttansattnr; nyttansattnr++; public int hentansattnr(){ return ansattnr; Vi skal i denne oppgaven gradvis endre på fila Verden.java og din oppgave blir å svare på spørsmålene underveis. ALT I DENNE OPPGAVEN KOMPILERER OG KJØRER. DET ER FORSTÅELSEN AV HVA PROGRAMMET GJØR SOM ER SENTRALT. a) (3%) Hvilken tilknytning har Student-klassen og Ansatt-klassen til Person-klassen? Svar med en kort setning.
Side 3 av 9 b) (4%) Hva blir utskrift på skjermen etter å ha kjørt java Verden hvis Verden.java ser slik ut? Student en = new Student("Kari", 23, 13424); en.oeklinjer(45); System.out.println(en.hentLinjer()); Student to = en; en.oeklinjer(300); System.out.println(en.hentLinjer()); System.out.println(to.hentLinjer()); //main //klassen DE NESTE DELOPPGAVENE VISER HVER EN NY VERSJON AV VERDEN.JAVA. GLEM DERFOR HELE TIDEN DE FOREGÅENDE c) (4%) Hva blir utskrift på skjermen etter å ha kjørt java Verden hvis Verden.java ser slik ut? Person enperson = new Student("Kari", 23, 13424); Student enstudent = (Student)enPerson; enstudent.oeklinjer(5000); Ansatt enansatt; if (enstudent.hentlinjer()>=4000){ String navn = enperson.hentnavn(); int alder = enperson.hentalder(); enansatt = new Ansatt(navn, alder); else{ enansatt = new Ansatt("Jonas", 28); System.out.println("Nummer: "+enansatt.hentansattnr()); System.out.println("Navn: "+enansatt.hentnavn()); System.out.println("Alder: "+enansatt.hentalder()); //main //klassen d) (4%) Hva blir utskrift på skjermen etter å ha kjørt java Verden hvis Verden.java ser slik ut? Person en = new Student("Hans", 20, 32543); Person to = new Ansatt("Erik", 29); Person[] perstab = new Person[2]; perstab[0]=en; perstab[1]=to; for(int i=0; i<2; i++){ if (perstab[i] instanceof Ansatt){ int nr = ((Ansatt)persTab[i]).hentAnsattNr(); System.out.println("Ansattnr: "+nr); else { int nr = ((Student)persTab[i]).hentStudentNr(); System.out.println("Studentnr: "+nr); //main //klassen
Side 4 av 9 e) (3%) Innfører to nye klasser Verdensomseiler og Koordinat.. Hva slags type tilknytning vil du si disse to klassene har seg imellom? Svar med en kort setning. public class Verdensomseiler extends Person{ private Koordinat minkoordinat; public Verdensomseiler(String navn, int alder, int breddegrad, int lengdegrad){ super(navn, alder); minkoordinat= new Koordinat(breddegrad, lengdegrad); public void settkoordinat(int breddegrad, int lengdegrad){ minkoordinat= new Koordinat(breddegrad, lengdegrad); public Koordinat hentkoordinat(){ return minkoordinat; public String hentnavn(){ return "Selveste "+super.hentnavn(); public class Koordinat{ private int breddegrad; private int lengdegrad; public Koordinat(int breddegrad, int lengdegrad){ this.breddegrad=breddegrad; this.lengdegrad=lengdegrad; public int hentbreddegrad(){ return breddegrad; public int hentlengdegrad(){ return lengdegrad; f) (4%) Klassene Verdensomseiler og Koordinat benyttes i de neste to deloppgavene. Hva blir utskriften på skjermen etter å ha kjørt java Verden hvis Verden.java ser slik ut? Verdensomseiler seilern = new Verdensomseiler("Thor", 84, 34, 61); Koordinat koord = seilern.hentkoordinat(); System.out.println(koord.hentBreddegrad()); System.out.println(koord.hentLengdegrad()); //main //klassen g) (4%) Hva blir utskrift på skjermen etter å ha kjørt java Verden hvis Verden.java ser slik ut? Verdensomseiler seilern = new Verdensomseiler("Thor", 84, 34, 61); System.out.println(seilern.hentNavn()); Person sammekaren = seilern; System.out.println(sammeKaren.hentNavn()); //main //klassen
Side 5 av 9 h) (4%) Hva blir utskrift på skjermen etter å ha kjørt java Verden hvis Verden.java ser slik ut? Verdensomseiler seilern = new Verdensomseiler("Thor", 84, 34, 61); Person sammekaren = seilern; ((Verdensomseiler)sammeKaren).settKoordinat(27, 90); Koordinat koord = seilern.hentkoordinat(); System.out.println(koord.hentBreddegrad()); System.out.println(koord.hentLengdegrad()); koord = ((Verdensomseiler)sammeKaren).hentKoordinat(); System.out.println(koord.hentBreddegrad()); System.out.println(koord.hentLengdegrad()); //main //klassen Oppgave 2 UML til programkode (15%) Skriv programkode for følgende UML-diagram. La samtlige metoder stå tomme (bare klammeparanteser { for de som behøver det. Programmet som skal lages skal være styreprogram for en ganske generell dyrerobothjerne som du har fått i oppgave å lage for IDI. antallbein-variabelen må være long for å få plass til antall bein i en laks som til tider kan være ganske mange. gaainn() gaaut() gaainn() gaaut() <<interface>> <<interface>> Husdyr Husdyr <<abstract>> Dyr <<abstract>> Dyr # antallbein : long # antallbein : long + <<abstract>> spis() + <<abstract>> + <<abstract>> hopp() spis() + <<abstract>> + <<abstract>> lagflere() hopp() : Dyr[] + <<abstract>> lagflere() : Dyr[] Forklaring til figuren Aksessmodifikatorer: - private + public # protected Hund Hund + sniff(annenhund : Hund) + sniff(annenhund : Hund) Katt Katt - antallliv : int - antallliv : int + mal() + mal() Laks Laks - glad : boolean - glad : boolean + svoem() + svoem()
Side 6 av 9 Oppgave 3: Feilfinning (25%) Programmet som følger under, og som består av de to klassene BingoSystem.java og Bong.java, har som oppgave å lage bonger til en bingohall. Hver bong har 5 rader og 5 kolonner, og hver rute skal inneholde et tilfeldig tall f.o.m. 1 t.o.m. 99. Til dette benyttes metoden random() fra Math-klassen som gir ut tilfeldig tall i intervallet [0.0, 1,0>. Dessuten gjelder følgende krav: 1) Alle de 25 tallene på en bong skal være ulike. 2) Tallene på bongen skal være sortert i stigende rekkefølge fra øvre venstre til nedre høyre hjørne, som f.eks: 7 13 19 24 25 28 37 38 45 46 48 49 57 58 60 62 63 64 68 79 82 86 88 93 99 Til hvert nye spill skal det kunne konstrueres et gitt antall nye bonger, dette antallet gis inn som parameter til BingoSystem-konstruktoren. Det er ikke stilt noe krav om å sjekke at ikke to bonger skal være like, da sannsynligheten for dette uansett er liten. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import java.util.arraylist; class BingoSystem { private ArrayList allebonger; public BingoSystem(int antall){ //skal konstruere gitt antall bonger på en tilfeldig måte //og legge disse i lista allebonger. ArrayList allebonger = new ArrayList(); for (i=0; i<antall; i++) { Bong b = new Bong(); allebonger.add(b); public void skrivbonger() { //skriver ut bongene som er laget int antall = allebonger.size(); System.out.println("Skriver de " + antall + " bongene:"); for (int i=0; i<antall; ++i) { (Bong) allebonger.get(i).skriv(); System.out.println(); //setter en blank linje før neste bong public static void main(string[] args) { //en enkel main-metode for å teste om det funker BingoSystem bs1 = new BingoSystem(6); bs1.skrivbonger(); BingoSystem bs2 = new BingoSystem(3); bs2.skrivbonger(); Linjenummer er satt inn slik at du lett kan referere til koden når du forklarer feil/rettinger.
Side 7 av 9 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 import java.util.arrays; class Bong { private int[] tall = new int[25]; //lagrer bongen internt som en 1D-tabell heller enn 2D, //dette er enklere mhp sortering o.l. private int antallhittil = 0; //antall tall funnet hittil public Bong() { //konstruktor, lager en sortert bong med 25 //forskjellige tall i intervallet [0, 99] while (antallhittil<25) { do { int nytttall = (int) (Math.random()*99); while (this.inneholder(nytttall)); antallhittil++; tall[antallhittil] = nytttall; Arrays.sort(tall); public void skriv(){ //skriver ut bongen i 2D, dvs. 5 rader, 5 kolonner for (int i=0; i<5; i++) { for (int j=0; j<5; j++) { System.out.print(tall[i*4+j] + " "); System.out.println(); private boolean inneholder(int n) { //sjekker om en helt eller delvis konstruert bong //inneholder tallet n boolean svar = false; for (int i=0; i<antallhittil; i++) { if (tall[i] == n) { svar = true; else svar = false; return svar; Programkoden inneholder feil. Merk at selv om du ikke skulle få til alt på a) eller b), kan du likevel ha mulighet til å avdekke noen av feilene i c). a) Programkoden gir noen kompileringsfeil. Feilmeldingene kommer på følgende linjer i klassen BingoSystem (uthevet i koden): i) for (i=0; i<antall; i++) { ii) (Bong) allebonger.get(i).skriv(); og på følgende linjer i klassen Bong: iii) while (this.inneholder(nytttall)); iv) tall[antallhittil] = nytttall; Som et ekstra hint kan det opplyses at de to siste feilmeldingene inneholder teksten cannot resolve symbol nytttall Forklar hva kompileringsfeilene skyldes og hvordan de enklest mulig kan rettes. (Du skal i denne deloppgaven kun konsentrere deg om å rette de nevnte kompileringsfeilene, ikke i samme slengen andre feil du måtte se).
Side 8 av 9 b) Når feilene i a) er rettet, vil programmet likevel ikke kjøre feilfritt. Du får følgende feilmelding under kjøring: i) Exception in thread "main" java.lang.arrayindexoutofboundsexception at Bong.<init>(Bong.java:17) ii) Exception in thread "main" java.lang.nullpointerexception at BingoSystem.skrivBonger(BingoSystem.java:16) Feil ii) vil først vise seg etter at feil i) er rettet. Forklar hva som er feil, og hvordan det kan rettes. Når feilene i b) er rettet, slik at programmet kjører uten feilmelding, vil det likevel være en del feil/svakheter som gjør at det ikke fungerer som det skal: i) Det første tallet på bongen blir av og til null, skulle aldri være lavere enn 1. ii) Det hender at samme tall forekommer flere ganger på en bong. iii) Høye tall (f.eks. over 90) forekommer langt sjeldnere enn statistisk forventet, tall over 95 ble overhodet ikke observert selv med et stort antall bonger. iv) Utskriften blir stygg der ensifrede tall inngår, fordi disse tar mindre plass. Den nedenstående bongen illustrerer de nevnte problemene. Forklar hva feilene skyldes (hvilke programsetninger) og hvordan de kan rettes. 0 4 9 21 22 22 27 30 36 41 41 46 49 52 53 53 56 57 57 58 58 61 78 80 88 Oppgave 4 (30%) Det skal lages et program som kan hjelpe et rederi til å holde orden på skipene sine og hvilke turer disse har vært og er booket til. Da det ikke er mulig å lage et fullstendig program for dette på en liten eksamen, vil vi fokusere på visse funksjoner som systemet skal kunne utføre, nemlig følgende: * Registrere nye turer * Beregne samlet omsetning for alle rederiets skip * Finne et ledig skip til en tur Det fins to typer turer, passasjerturer og fraktturer. For beregning av omsetning for en tur gjelder følgende regler: * For en frakttur avtales en pris per tonn, omsetningen kan dermed beregnes som antall tonn i frakten multiplisert med denne avtalte prisen. * For en passasjertur beregnes en billettpris per passasjer som antall nautiske mil multiplisert med 10 kroner, omsetningen kan dermed beregnes som antall passasjerer multiplisert med denne billettprisen. For å finne et ledig skip til en tur, må man forholde seg til følgende kriterier: * Skipet må være av riktig type. Passasjerturer kan kun utføres av passasjerskip, fraktturer kun av fraktskip.
Side 9 av 9 * For passasjerturer må skipets kapasitet (max antall passasjerer) være minst like stort som turens faktiske passasjerantall. For fraktturer må tilsvarende skipets max tonnasje være tilstrekkelig for den aktuelle lasten. * Det aktuelle skipet må være ledig i hele den perioden (fradato tildato) som turen gjelder, dvs. det må ikke allerede være booket til en annen tur i et overlappende tidsrom. (For å forenkle oppgaven noe, er det OK om du bare bruker int dagnr i stedet for å benytte en klasse som Date.) For at oppgaven ikke skal bli for omfattende, behøver du ikke tenke på grafisk brukergrensesnitt, filbehandling eller lignende, ei heller tastaturinput fra bruker. I stedet kan du ta utgangspunkt i nedenstående klasse som utløser de kallene som er relevante for deloppgavene b)-d). Det er lov å gjøre utdypende antagelser der oppgaveteksten er uklar. Disse må i så fall presiseres i besvarelsen. public class Rederi { //instansvariable utelatt, disse må du finne ut av selv public void registrernytur() { //oppretter en ny tur, men uten å finne skip til den //evt. argumenter til metoden utelatt //kode utelatt, jfr. deloppgave b) public int inntektalleskip() { //summen av omsetningen for rederiet, dvs. alle turer for alle skip //kode utelatt, jfr. deloppgave c) public void finnskiptiltur() { //booker et bestemt skip til en bestemt tur //evt. argumenter til metoden utelatt //kode utelatt, jfr. deloppgave d) public static void main(string[] args) { //her kunne vi laget en testdriver for systemet, //men dette er ikke en del av oppgaven a) Skisser UML-diagram for dette systemet. Ta med variabler og metoder i klassene. Du behøver kun å ta med de som er relevante for løsningen av b)-d). b) Deklarer de nødvendige instansvariable i klassen Rederi og skriv kode for registrernytur() dette trenger ikke være bare en metode, kan også være flere metoder med samme navn men ulik signatur. NB! I tillegg til å skrive kode i klassen Rederi, må du skrive de metodene som registrernytur() igjen kaller i andre klasser som du har definert. c) Skriv kode for inntektalleskip(). Som i b) må du også skrive metoder i andre klasser som denne igjen kaller. d) Skriv kode for finnskiptiltur(). Som i b) og c) må du også skrive metoder i andre klasser som denne igjen kaller.