Lunds universitet FYTA11 Institutionen för Teoretisk fysik HT 11 Tentamen FYTA11 Javaprogrammering Fredag 26:e augusti 2011, 10:15 16:15 Instruktioner Hjälpmedel: enkla ritverktyg och Javadoc-genererade referensblad som delas ut med tentan. Behandla högst en uppgift per papper och sätt ditt namn på varje papper. Skriv läsligt och kommentera utförligt vad du gör det kan ge dig poäng även om resultatet blir fel. Tentamen omfattar fyra uppgifter som vardera kan ge upp till tio poäng. Uppgift 1: Korrigera felen i följande kodsnuttar där felens natur anges av kommentarer i koden. I de fall det rör sig om kompileringsfel så genererades felet av raden ovanför kommentaren. a. public static void main(string[] a) { //Kompileringsfel: cannot find symbol/ symbol: class string System.out.println("Hay, everypony!"); b. c. d. e. int x = 42; int y = 39; System.out.println(x + + y); //Skriver ut 113 istället för 42 och 39 separerade med ett mellanslag. int[8] arr = new int[]; //Ger flera kompileringsfel int n = 5; char ch = 0 + n; //Kompileringsfel: possible loss of precision class Summer { final protected int sum(int a, int b) { return a + b; static public int sum(int a, int b, int c) { return sum(sum(a, b), c); //Kompileringsfel: non-static method sum(int,int) cannot be //referenced from a static context
f. class A { protected int n; A(int i) {n = i; class B extends A { B(int i) {A(i); //Kompileringsfel: cannot find symbol/ symbol: method A(int) g. h. i. int n = 1000000.; //Kompileringsfel: possible loss of precision class A { class B { static int silly() {return 99; //Kompileringsfel: inner classes cannot have static declarations static int getsilly() { return B.silly(); abstract class A {abstract String label(); class B extends A {String label() {return "meppity"; class C extends A {String label() {return "ooof"; public class Test { public static void test() { B x; x = new B(); System.out.println(x.label()); x = new C(); //Kompileringsfel: incompatible types System.out.println(x.label()); j. interface Messenger { public String getmessage(); public void setmessage(string msg); class Note { protected String message; public Note() { public Note(String msg) {message = msg; public String getmessage() {return message; public class Sticky extends Note implements Messenger { //Kompileringsfel: Sticky is not abstract and does not override //abstract method setmessage(java.lang.string) in Messenger public String setmessage(string msg) {message = msg; //Kompileringsfel: setmessage(java.lang.string) in Sticky //cannot implement setmessage(java.lang.string) in Messenger; //attempting to use incompatible return type
Uppgift 2: Permutationer och paritet Slumpmässiga permutationer är användbara i många datortillämpningar. Nedan finns ramarna till en enkel klass med enbart klassmetoder. Din uppgift är att fylla metoderna med meningsfull kod. Metoden swapelems skall byta plats på två element med givna index i ett fält. Metoden getpermutation skall returnera ett fält (av n heltal) som innehåller heltalen 0 till n 1 i slumpmässig ordning. Varje lösning som ger en jämn slumpfördelning över alla permutationer är tillåten, men här är ett förslag på en okomplicerad algoritm. Skapa ett fält med talen 0 till n 1 i ordning. Loopa över index k i stigande ordning och gör följande för varje index k: Välj ett slumpmässigt index m bland alla giltiga index med m k och anropa swapelems för ditt fält med k och m. Returnera fältet som nu har blandats slumpmässigt. Metoden oddpermutation skall returnera sant om och endast om permutationen som beskrivs av det givna fältet är udda. För att avgöra detta loopar man över alla indexpar (k,m) med k < m och räknar antalet fall då elementet med index k är större än det med index m. Permutationen är udda om och endast om antalet räknade fall är udda. public class Permutator { /** Swaps the elements with indices i and j in the Array a. */ public static void swapelems(int[] a, int i, int j) {... /** Returns a random permutation of the integers 0, 1,..., n-1. */ public static int[] getpermutation(int n) {... /** * Returns true if and only if the number of index pairs i, j * satisfying the following condition is an odd: * i < j and arr[j] > arr[i] */ public static boolean oddpermutation(int[] arr) {...
Uppgift 3: Kontrollera storlek och flytta brickor Metoderna från föregående uppgift är användbara för ett enkelt spel där man flyttar brickor i ett rektangulärt (ofta kvadratiskt) rutnät. Rutnätet har en tom ruta och spelet går ut på att flytta brickorna så att de hamnar i nummerordning. Nedan visas ett utdrag ur programkoden för ett sådant spel. Implementationen har dock brister som du skall rätta till. Rutnätets storlek sätts i konstruktorn men det sker ingen kontroll av parametrarnas rimlighet. Dessutom kan man inte flytta brickor med hjälp av tangentbordet utan måste använda musen. Definiera en subklass till Exception, med en konstruktor som tar två heltal w och h som argument och sätter Exception-klassens meddelande till Spelets rutnät kan inte ha storleken w x h.. Se till att konstruktorn för TilePuzzle kastar ett undantag av den egendefierade klassen om någon av rutnätets dimensioner är mindre än 2 eller om antalet rutor i spelet överstiger 900. Lägg till en lyssnare för tangenttryckningar i konstruktorn för TilePuzzle. Lyssnaren skall se till att instansmetoden movetile anropas med ett lämpligt riktningsargument när man trycker på en piltangent. Det är upp till movetilemetoden att kontrollera om draget verkligen kan genomföras och en sådan kontroll ingår inte i uppgiften.
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class TilePuzzle extends Canvas { private final int width, height; //dimensions of the puzzle grid private int[][] state; //stores a tile index for each position private final int emptytile; //tile index that refers to emptiness: //state[i][j] == emptytile if position is empty private int emptyx, emptyy; //current position of the empty square private int nmismatches; //counter that is 0 if the puzzle is solved public enum Direction {LEFT, RIGHT, UP, DOWN; private int x0, y0; //pixel coordinates of upper left corner of the grid private int side; //side of a tile static private final int prefside = 32; //default cell size in pixels static private final int minside = 16; //minimum cell size in pixels static private final int padding = 2; //minimum padding around grid in half cell units static private final int preffontsize = 16; //default font size in pixels public TilePuzzle(int w, int h) { width = w; height = h; emptytile = w*h - 1; setminimumsize(new Dimension(minSide*(w + padding), minside*(h + padding))); setpreferredsize(new Dimension(prefSide*(w + padding), prefside*(h + padding))); addmouselistener(new MouseAdapter() { //A mouse-click moves a tile if the clicked tile is next to the empty square. public void mouseclicked(mouseevent e) { if(e.getbutton()!= MouseEvent.BUTTON1) return; Point p = e.getpoint(); if(p.x >= x0 && p.y >= y0 && p.x < x0 + width*side && p.y < y0 + width*side) { int dx = emptyx - (p.x - x0)/side; int dy = emptyy - (p.y - y0)/side; if(dy == 0) { if(dx == -1) movetile(direction.left); else if(dx == 1) movetile(direction.right); else if(dx == 0) { if(dy == -1) movetile(direction.up); else if(dy == 1) movetile(direction.down); ); //allow focus selection by tabbing among graphical components setfocusable(true); reset(); //randomize the tiles public boolean issolved() {return nmismatches == 0; public void reset() {... public void movetile(direction d) {... public void paint(graphics g) {...
Uppgift 4: Huvudprogram med felrapportering En klass TileFrame som sköter fönster och spel är skriven men klassen har ingen main-metod. Vi vill att ett javaprogram skall skapa en spelplan av standardstorlek om det anropas utan argument i kommandoraden. Om programmet anropas med två heltal som argument skall spelplanens bredd och höjd sättas enligt dessa. Detta görs av klassen Puzzle men utan vettig felhantering. public class Puzzle { public static void main(string[] args) { try { if(args.length == 0) new TileFrame(); else if(args.length == 2) new TileFrame(Integer.parseInt(args[0]), Integer.parseInt(args[1])); catch(exception e) { System.exit(-1); Din uppgift är att ändra koden så att följande saker fungerar. Ett fel skall ge en dialogruta med ett felmeddelande och därefter skall programmet avslutas med returstatus 1. Om programmet startas med fel antal argument skall felmeddelandet bli följande: Fel i kommandoraden: Programmet tar noll argument(för standarstorlek) eller två heltal för rutnätets dimensioner. Om programmet får två argument men något av argumenten inte är ett heltal så skall felmeddelandet bli följande: Felaktigt numeriskt format i kommandoraden: Programmet tar två heltal som anger rutnätets dimensioner. Om ett undantag av den egendefinerade typen TilePuzzle.SizeException har kastats från TileFrame-konstruktorn skall felmeddelandet sättas till det meddelande som undantagsobjektet bär på.