Institutt for datateknologi og informatikk Eksamensoppgave i IFUD1025 Programmering i Java Faglig kontakt under eksamen: Vuokko-Helena Caseiro Tlf.: +39 06 51 26 063 Eksamensdato: 15. mai 2017 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: 0 Informasjon om trykking av eksamensoppgave Originalen er: 1-sidig 2-sidig svart/hvit farger skal ha flervalgskjema Kontrollert av: Dato Sign Merk! Studenter finner sensur i Studentweb. Har du spørsmål om din sensur må du kontakte instituttet ditt. Eksamenskontoret vil ikke kunne svare på slike spørsmål.
Oppgave 1 ( 38 % ) Møteplanlegger Et møte skal bli avholdt, og noen møtetider blir foreslått. Det gjelder å velge en møtetid som passer flest mulig. Eksempel: Det skal være et møte i Svaneklubben, som har sju medlemmer, og det blir foreslått tre mulige møtetider: - Mandag 15. mai: Da kan Vera og Kai. - Onsdag 17. mai: Da kan Lise og Aleksander. - Fredag 19. mai: Da kan Vera, Kai, Lise og Aleksander. De tre øvrige medlemmene kan ikke komme verken mandag, onsdag eller fredag. Dermed er det fredag som er det beste møtetidspunktet. Først skal du lage klassen Personliste for å representere de personene som én foreslått møtetid passer for. Senere skal du lage klassen Moeteplanlegger for å representere alle personlistene. a) Begynn å lage klassen Personliste. Det skal være tre objektvariabler: o tid av type String: et tidspunkt o navnene av type String[]: navnene til de personene som vi vet kan komme til tidspunktet tid. Navnene ligger fortløpende fra og med indeks 0 og til og med indeks antallnavn 1; resten av tabellen er ubrukt og inneholder null. o antallnavn av type int: antall navn registrert i navnene-tabellen Lag en konstruktør som tar en tid og høyst tenkelig antall møtedeltakere som argumenter. Tabellen navnene skal opprettes, men det skal ikke legges inn noen strenger. Eksemplet fortsatt: Ved å kalle konstruktøren tre ganger skal vi kunne få laget tre objekter: o I «mandagsobjektet» er tid ʺmandag 15. maiʺ, navnene.length er 7 og antallnavn er 0. o I «onsdagsobjektet» er tid ʺonsdag 17. maiʺ, navnene.length er 7 og antallnavn er 0. o I «fredagsobjektet» er tid ʺfredag 19. maiʺ, navnene.length er 7 og antallnavn er 0. b) Lag de tre Personliste-metodene gettid(), getnavnene() og getantallnavn(). c) Lag en Personliste-metode public boolean settkan(string navn) Metoden skal registrere at personen navn kan komme på tidspunkt tid. Metoden skal returnere true hvis registreringen gikk greit, false ellers. Eksemplet fortsatt: Ved å kalle mandagsobjektets settkan()-metode to ganger, skal vi kunne registrere at Vera og Kai kan komme mandag. Mandagsobjektet kan da illustreres slik: 2
d) Begynn å lage klassen Moeteplanlegger. Det skal være en objektvariabel: o personlistene av type Personliste[] Lag en konstruktør som tar to argumenter: de foreslåtte tidene og høyst tenkelig antall møtedeltakere. Eksemplet fortsatt: Vi skal kunne lage et Moeteplanlegger-objekt med mandagsobjektet i posisjon 0, onsdagsobjektet i posisjon 1 og fredagsobjektet i posisjon 2 i personlistene. Foreløpig er det ingen personnavn i disse objektene. e) Lag en Moeteplanlegger-metode public boolean settkan(int moeteindeks, String navn) som i element nummer moeteindeks i personlistene registrerer at personen navn kan komme. Metoden skal returnere true hvis registreringen gikk greit, false ellers. Eksemplet fortsatt: Med kallet settkan(0, ʺVeraʺ) skal vi få registrert at Vera kan komme på mandag. Med sju settkan()-kall til skal vi få registrert all informasjonen om hvem som kan komme når. Vi ønsker å sortere Personliste-objektene etter hvor mange navn som er registrert i dem, eller med andre ord etter hvor mange personer som kan komme til de foreslåtte tidene. f) Lag en Moeteplanlegger-metode public Personliste[] finnsortert() Metoden skal returnere en ny tabell med alle Personliste-objektene sortert i synkende rekkefølge etter antall registrerte navn. Metoden skal ikke endre tabellen personlistene. Tips: Du kan gjerne legge til en compareto()-metode i klassen Personliste. Eksemplet fortsatt: Siden det er på fredag flest kan komme (nemlig fire personer), skal fredagsobjektet komme først i den tabellen som blir returnert. Deretter kommer onsdags- og fredagsobjektet, likegyldig i hvilken rekkefølge. g) Lag en Moeteplanlegger-metode public Personliste finnbeste() som returnerer det Personliste-objektet som har flest navn registrert. Hvis det er flere slike objekter, så returner et eller annet av dem. Eksemplet fortsatt: Metoden skal returnere fredagsobjektet. 3
Oppgave 2 ( 62 % ) Myntautomat Denne oppgaven er tenkt gjennomført uten tabeller. Men du kan likevel bruke tabeller, hvis du vil. Med mynter mener vi i denne oppgaven norske kroner av valørene 20, 10, 5 eller 1, altså 20-kroner, 10-kroner, 5-kroner og 1-kroner. En myntbeholdning er en samling av mynter. I deloppgavene 2b) 2e) skal du lage metoder for å finne verdien av en beholdning, for å legge sammen to beholdninger, for å fjerne en del av en beholdning og for å beregne vekslepenger av en beholdning. Eksempel på en myntbeholdning: Myntbeholdningen består av én 20-krone, to 10-kroner, tre 5- kroner og to 1-kroner. a) Begynn å lage klassen Myntbeholdning. Det skal være fire objektvariabler: o ant20 av type int: antall 20-kroner o ant10 av type int: antall 10-kroner o ant5 av type int: antall 5-kroner o ant1 av type int: antall 1-kroner Lag en konstruktør med fire parametre. Lag get-metoder. Eksemplet fortsatt: Ved å kalle konstruktøren med de fire argumentene 1, 2, 3 og 2 skal vi kunne lage denne beholdningen. En myntbeholdnings verdi er summen av alle myntenes valører. b) Lag en Myntbeholdning-metode public int finnverdi() som returnerer denne beholdningens verdi. Eksemplet fortsatt: Metoden skal returnere 57 fordi 1 * 20 + 2 * 10 + 3 * 5 + 2 * 1 = 57. c) Lag en Myntbeholdning-metode public void leggtil(myntbeholdning andre) som legger myntene i andre-beholdningen til denne beholdningen. Eksemplet fortsatt: Hvis andre består av tre 20-kroner og to 5-kroner, skal ant20 økes til 4 og ant5 til 5. ant10 og ant1 skal ikke endres. En myntbeholdning b er en delbeholdning av en myntbeholdning a hvis det er slik at for hver valør v er antall v-kroner i b mindre eller lik antall v-kroner i a. Vi oppgir en Myntbeholdning-metode som returnerer true hvis denne beholdningen er en delbeholdning av andre, og false ellers: public boolean erdelbeholdningav(myntbeholdning andre) { return ant20 <= andre.getant20() && ant10 <= andre.getant10() && ant5 <= andre.getant5() && ant1 <= andre.getant1(); } 4
d) Lag en Myntbeholdning-metode public boolean trekkfra(myntbeholdning andre) Hvis andre er en delbeholdning av denne beholdningen, så skal metoden trekke andre fra denne beholdningen og returnere true. Ellers skal metoden returnere false. Tips: Kall erdelbeholdningav() med riktig argument. Eksemplet fortsatt: Hvis andre består av én 10-krone og to 1-kroner, skal ant10 minskes til 1 og ant1 til 0. ant20 og ant5 endres ikke. Hvis andre består av fire 5-kroner og én 1-krone, skal metoden ikke gjøre noe annet enn å returnere false. Vi ønsker oss en metode som kan beregne vekslepenger (en delbeholdning) av en gitt beholdning. Metoden skal ta som argument det beløpet, ønsketbeløp, som den skal prøve å utbetale. Det er ikke sikkert at det fins noen delbeholdning med verdi nøyaktig lik ønsketbeløp, så det metoden faktisk skal gjøre er å finne en delbeholdning med verdi så nær oppunder ønsketbeløp som mulig. e) Lag en Myntbeholdning-metode public Myntbeholdning beregnvekslepenger(int ønsketbeløp) Metoden skal returnere et Myntbeholdning-objekt vekslepengene med verdi veksleverdi slik at o vekslepengene er en delbeholdning av denne beholdningen, og o veksleverdi er så stor som mulig, men slik at veksleverdi ønsketbeløp, og o ingen annen delbeholdning med verdi lik veksleverdi består av færre mynter enn vekslepengene. Legg merke til at metoden ikke skal være en mutasjonsmetode. Tips 1: Bygg opp vekslepengene ved først å ta så mange 20-kroner som mulig, deretter så mange 10-kroner som mulig og så videre. Tips 2: Du kan muligens få bruk for metoden min() fra java.lang.math: public static int min(int a, int b) returnerer det minste av de to tallene a og b. Eksemplet fortsatt (ant20 er 1, ant10 er 2, ant5 er 3, ant1 er 2): La ønsketbeløp være 14. Da skal vekslepengene bestå av én 10-krone og to 1-kroner. Så veksleverdi er lik 12. Legg merke til at det ikke fins noen delbeholdning med verdi lik 13 kr eller 14 kr. Legg også merke til at for at vekslepengene skal bestå av så få mynter som mulig, foretrekker vi én 10-krone framfor to 5-kroner. En myntautomat tar imot mynter som betaling for en vare. Bare hvis automaten mottar nok penger blir det mulig å gjennomføre salget. Inni automaten blir myntene lagret i automatens mage. Automaten har også et rom kalt munnen, som bare brukes til å oppbevare kundens mynter mens det er et salg på gang. Et salg foregår slik: Kunden velger en vare til en bestemt pris og legger mynter på automaten. Foreløpig havner disse myntene i munnen. Salget avsluttes enten med at det blir gjennomført, eller med at kunden får pengene sine tilbake. Eventuell gjennomføring av salget foregår slik: Alle de myntene som er i munnen blir flyttet til magen. Vekslepengene beregnes som i deloppgave 2e) og fjernes fra magen. 5
Eksempel på et salg som blir gjennomført: Kunden velger en sjokolade til 6 kr og legger på en 20- krone, som havner i munnen. Salget skal gjennomføres, så mynten blir deretter flyttet fra munnen til magen. Kunden skal helst ha 14 kr tilbake. Anta at magen er som i eksemplet i deloppgave 2e). Da får kunden en 10-krone og de to 1-kronene i vekslepenger, slik vi så. Eksempel på et salg som ikke blir gjennomført: En kunde velger en brus til 32 kr og legger på tre 10- kroner, som havner i munnen. Så ombestemmer kunden seg og vil ikke kjøpe brusen likevel. Da får kunden de tre 10-kronene sine tilbake fra munnen. Du skal nå skrive noen deler av en klasse Automat for å representere en myntautomat. f) Begynn å lage klassen Automat. Det skal være tre objektvariabler: o magen av type Myntbeholdning: magen skal være final. o munnen av type Myntbeholdning: Mens det er et salg på gang, peker munnen til et Myntbeholdning-objekt, ellers er den lik null. o prisvalgtvare av type int: Mens det er et salg på gang, er prisvalgtvare prisen til den varen som er blitt valgt, ellers er den lik 0. Lag en konstruktør med fire parametre som gjør det mulig å legge noen mynter i magen (for slik å ha noen vekslepenger). Eksempel: Det skal være mulig å få laget en automat med ti mynter av hver valør i magen, munnen lik null og prisvalgtvare lik 0. En automat har mottatt nok penger hvis det er et salg på gang og munnens verdi er like stor eller større enn prisen til den varen som er blitt valgt. g) Lag en Automat-metode public boolean mottattnok() Metoden skal returnere true hvis automaten har mottatt nok penger, ellers false. h) Lag en Automat-metode public Myntbeholdning tømmunnen() Metoden skal sette munnen lik null og dessuten returnere munnen slik den var idet metoden ble kalt. i) Lag en Automat-metode public Myntbeholdning gjennomførsalget() Hvis automaten har mottatt nok penger, skal følgende skje: 1. Beregn hvor mye kunden har betalt for mye. Det beløpet vil vi prøve å utbetale. 2. Tøm munnen ved å kalle tømmunnen(), og legg de myntene som var i munnen i magen. 3. Beregn vekslepengene det faktisk er mulig å utbetale av magen (som i deloppgave 2e). 4. Trekk vekslepengene fra magen. 5. Sett prisvalgtvare lik 0. 6. Returner vekslepengene. Hvis automaten ikke har mottatt nok penger, skal metoden returnere null. 6