Datalogi I, grundkurs med Java 10p, 2D4112, 2003-2004 Tentamen 29 november 2003, svar och lösningar 1a) Snabbaste lösningen är att addera i det binära systemet och konvertera svaret till decimalt tal: 10001 2 + 110 2 = 10111 2 =23. Ett annat sätt är att göra om de binära talen var för sig och addera: 10001 2 =17, 110 2 =6, 17 + 6 =23. 23 =10111 2. 1b) Ett hexadecimalt tal är ett tal uttryckt i ett positionssystem med basen 16. Om ett tal skrivs S n S n s...s 2 S 1 S 0,såangersiffranS k hur många 16 k som ingår i talet. När man uttrycker tal i basen B så behövs det också B st siffror. I vårt vanliga 10-system har vi 10 siffersymboler: 0,1,2,3,4,5,6,7,8,9. Med basen 16 behövs 16 symboler och då används 0..9 samt A, B, C, D, E och F. 2a) Fortran - imperativt, Lisp - funktionellt, C++ - objkektorienterat. 2b) Objektorienterade: Java, Simula, Smalltalk... Imperativa: C, Pascal, Basic,... Funktionella: Haskell, Scheme, Erlang,... 3a) En noggrann beskrivning av hur man kommer fram till lösningen på ett problem uttryckt i grundoperationer som är väldefinierade för den som ska följa beskrivningen. Lösningen skall nås efter ett ändligt antal steg. 3b) Pseudokod är en blandning av programkod och naturligt språk. Används när man vill beskriva algoritmer på ett sätt som ligger nära program (programspråk), som kan förstås av den som kan programmera Man använder pseudokod när man inte vill inte låsa beskrivningen till ett visst språk och/eller inte heller beskriva alla programkodens triviala detaljer utan fokusera på den intressantare algoritmbeskrivningen. 3c) Frågan är vilket tal som är minst : n 2 eller n logn (C 1 och C 2 är ju lika stora och påverkar inte svaret). Svaret är att n logn är mindre än n 2, skillnaden blir tydligare ju större n är. Det anges inte vilken logaritm som används men svaret är detsamma. Om n är ungefär 1000 så är ju n 2 = 1000000 men n logn = 1000 10 = 10000 om 2-logaritmen används. 4) Syntaxen är reglerna för hur man får skriva i programspråket för att det ska gå att kompilera programmet. Semantiken i språket beskriver vad olika språkkonstruktioner betyder, vad som verkligen sker när man skriver på ett visst sätt. Syntaxfel upptäcks senast vid kompilering, ibland upptäcks de medan man skriver och om man skriver Javaprogram med en editor som Emacs som känner till Java-syntax så kan felen upptäckas av Emacs. Semantiska fel kan vara svårare att upptäcka men man bör hitta dem genom en ordentlig testning av programmet följt av felsökning. 5) En aktiveringspost är en minnesreservatiom som görs i sambande med metodanrop. Det reserveras plats för metodens parametrar och lokala variabler. Detta minnesutrymme förblir reserverat tills metoden exekeverat färdigt. Om en metod anropar en metod (en annan eller samma) så finns den första aktiveringsposten kvar under det andra metodanropet. En kedja med aktiveringsposter kan förekomma. 1
6) A 7) A 8) D 9) D 10) C 11) B 12) B 13) D 14) C 15) B 16) B 17) C 18) C 19) B 20) int antallika (int[] a, int[] b) { int nlika = 0; int n = a.length; if (b.length < n) n = b.length; for (int i=0; i< n; i++) if (a[i] == b[i]) nlika++; return nlika; 21) I det här alternativet ändras den vektor som ges som parameter. void permutera (int [] a) { int tmp = a[0]; for (int i=0; i < a.length -1; i++) a[i] = a[i+1]; a[a.length-1] = tmp; I följande alternativ ändras inte på parametern. Metoden returnerar en ny vektor. int [] permuterad (int [] a) { int[] c = new int[a.length]; for (int i=0; i < a.length -1; i++) c[i] = a[i+1]; c[a.length-1] = a[0]; return c; 2
22) Här är den fullständiga lösningen. Det som saknas är att koppla lyssnaren till textfälten samt hela metoden actionperformed. I den metoden testas m.h.a. parametern till metoden i vilket textfält det skett en händelse. Om det var fahrenheitfältet så läses det fältet av, celsius- grader beräknas och skriv ut i Celsius-fältet. OM händelsen var i celsisus- fältet så läses det av och utskrift sker i fahrenheitfältet. import java.awt.*; import java.applet.*; import java.awt.event.*; public class CF extends Applet implements ActionListener{ private TextField celsius, fahrenheit; public void init () { add(new Label("Grader Celsius")); celsius = new TextField(5); add(celsius); celsius.addactionlistener(this); add(new Label("Grader Fahrenheit")); fahrenheit = new TextField(5); add(fahrenheit); fahrenheit.addactionlistener(this); public void actionperformed (ActionEvent e) { if (e.getsource() == celsius) { double c = Double.parseDouble(celsius.getText()); fahrenheit.settext("" + (9*c/5 + 32)); else { double f = Double.parseDouble(fahrenheit.getText()); celsius.settext("" + (5*(f-32)/9)); 3
23a) import java.util.*; // inget avdrag om man utelämnat detta! class Glosa { private String sve; private ArrayList eng; Glosa (String s, String e) { sve = s; eng = new ArrayList(); eng.add(e); void läggtillsynonym(string s) { eng.add(s); boolean gissaeng(string giss) { String s; for (int i=0; i< eng.size(); i++) { s = (String) eng.get(i); if (s.equals(giss)) return true; return false; String visasve() { return sve; String visaeng () { String s = "";; for (int i=0; i< eng.size(); i++) { s = s + (String) eng.get(i) + " "; return s; Metodern visasve och visaeng kan istället skrivas som void-metoder som skriver ut (med System.out.print...) instansvariabeln sve respektive alla ord i listan eng. 4
23b) class TestaGlosa { public static void main (String [] x) { Glosa g = new Glosa("svår", "difficult"); g.läggtillsynonym("hard"); g.läggtillsynonym("serious"); g.läggtillsynonym("severe"); // den var inte med i uppgiften! System.out.println(g.visaSve() + " kan översättas till något av"); System.out.println(g.visaEng()); if (g.gissaeng("severe")) // utskriften bör bli "Rätt" System.out.println("Rätt"); else System.out.println("Fel"); if (g.gissaeng("hart")) // utskriften bör bli "Fel" System.out.println("Rätt"); else System.out.println("Fel"); 5