Lunds universitet FYTA11 Institutionen för Teoretisk fysik HT 10 Tentamen FYTA11 Javaprogrammering Måndag 10:e januari 2011, 09:00 13:00 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. b. String s = "Hello!"; System.out.println(s + ": " + s.length); //Kompileringsfel: cannot find symbol/ symbol: variable length class A { protected Integer val; A(int v) {val = new Integer(v); static class B extends A { B() {val = new Integer(0); //Kompileringsfel: cannot find symbol/ symbol: constructor A() c. try { int b = 1000/a; catch(arithmeticexception) { //Kompileringsfel: <identifier> expected System.err.println("Heltalsdivision med 0"); System.exit(-1);
d. e. f. g. h. i. j. import java.awt.geom.*; Point p = new Point(8, 20); Point2D q = p.clone(); //Kompileringsfel: incompatible types/ found: java.lang.object/ // required: java.awt.geom.point2d public class FixedPrec2D extends java.awt.geom.point2d { //Kompileringsfel: FixedPrec2D is not abstract and does not override // abstract method gety() in java.awt.geom.point2d private long x, y; private final long denom = 1000000; public double getx() {return (double)x/denom; public void setlocation(double x, double y) { this.x = Math.round(x*denom); this.y = Math.round(y*denom); class SillyVec { public java.util.vector<int> content; //Kompileringsfel: unexpected type/ found: int/ required: reference final int N = 8; System.out.println((int)Math.random()*N); //Skriver alltid ut en nolla istället för ett slumptal från 0 till 7 int i; for(i = 0; i < 4; ++i); System.out.print(" " + i); System.out.println(); //Skriver ut " 4" istället för " 0 1 2 3" class Hello { public void main(string[] a) { System.out.println("Hello!"); //Exekveringfel för java Hello: Exception in thread "main" java.lang.nosuchmethoderror: main import java.awt.geom.*; Point2D p = new Point(4, 8); System.out.println(p); p = new Point2D(5.43, 2.9); //Kompileringsfel: java.awt.geom.point2d is abstract; cannot be instantiated
Uppgift 2: Kontrollera sudoku En sudoku består av ett rutnät med 9 9 rutor som skall fyllas med en siffra i vardera ruta. Vissa rutor har siffror som är givna på förhand och utmaningen består i att fylla de tomma rutorna så att följande regler uppfylls: I var och en av de 9 raderna i rutnätet skall siffrorna 1 till 9 vara ifyllda med exakt en förekomst av varje siffra. Samma villkor som ovan fast tillämpat på de 9 kolumnerna i rutnätet. Rutorna i rutnätet delas också in i 9 grupper om vardera 3 3 angränsande rutor. Varje sådan grupp skall också vara fylld med siffrorna 1 till 9 så att varje siffra förekommer exakt en gång inom gruppen. Din uppgift här är att skriva en publik instansmetod issolved till en given klass Sudoku. Klassen Sudoku har en privat instansvaribel state av typen char[][] sådan att state[r][c] anger tecknet som finns i ruta c i rad r. Metoden issolved tar inga argument och returnerar en boolean som är sann om och endast om innehållet i state uppfyller ovanstående regler. Du kan utgå ifrån att storleken på fälten i state matchar en 9 9-matris men tecknen som lagrats i state är inte nödvändigtvis inom intervallet 1 till 9.
Uppgift 3: Lyssna på JButtons Ett ofullständigt huvudprogram till Sudoku-klassen i föregående uppgift är givet. import java.awt.event.*; import javax.swing.*; public class SudokuFrame extends JFrame implements ActionListener { private Sudoku sudoku; private static final String newstr = "Ny sudoku"; private static final String resetstr = "Börja om"; private static final String checkstr = "Rätta"; //Sudoku collection for testing purposes private static final String[] sudokulist = { ; public SudokuFrame() { super("sudoku"); sudoku = new Sudoku(); //Load test-collection of sudokus for(string s: sudokulist) sudoku.add(s); //Setup graphical interface Container c = getcontentpane(); c.setlayout(new BorderLayout()); c.add(sudoku, BorderLayout.CENTER); Container g = new JPanel(new GridLayout(1, 3)); c.add(g, BorderLayout.SOUTH); JButton newb = new JButton(newStr); g.add(newb); newb.addactionlistener(this); JButton resetb = new JButton(resetStr); g.add(resetb); resetb.addactionlistener(this); JButton checkb = new JButton(checkStr); g.add(checkb); checkb.addactionlistener(this); pack(); //Pick a random sudoku from the test-collection sudoku.picksudoku(); Din uppgift består i att komplettera klassen SudokuFrame med en main-metod för att starta programmet och en lyssnar-metod för att fånga tryckningarna på de JButtons som lagts till i konstruktorn. Knapparna Ny sudoku och Börja om skall leda till anrop av metoderna sudoku.picksudoku() respektive sudoku.reset(). Knappen Rätta skall ge ett anrop till metoden issolved som beskrivs i föregående uppgift och en dialogruta med lämpligt meddelande beroende på returvärdet skall visas. Observera att du inte får göra ändringar i den givna konstruktorn. Tips: I ovanstående kod blir kommandosträngen för den händelse som genereras av en knapptryckning densamma som den sträng som visas på knappen.
Uppgift 4: Hantera tangenttryckningar Sudoku-klassen från uppgift 2 behöver hantera utritning, musklick och tangenttryckningar. Din uppgift består i att fylla definitionen av en anonym KeyAdapter-klass med meningsfull kod. import java.util.*; import java.awt.event.*; import javax.swing.*; public class Sudoku extends Canvas { private char[][] state; //current content of the sudoku grid private boolean[][] locked; //true for cells with pre-set numbers private int x0, y0; //pixel coordinates of the upper left corner of the sudoku grid private int side; //side of a cell in the sudoku grid private int row, col; //active cell location in the sudoku grid public Sudoku() { //initialize instance variables //setup input listeners addmouselistener(new MouseAdapter() { 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 + 9*side && p.y < y0 + 9*side) { row = (p.y - y0)/side; col = (p.x - x0)/side; repaint(); ); addkeylistener(new KeyAdapter() { ); //Implement override to handle keyboard events. //allow focus selection by tabbing among graphical components setfocusable(true); En tryckning på en siffertangent 1 till 9 skall sätta state[row][col] till tecknet för den nedtryckta siffran om locked[row][col] är falsk. (Instansvariabeln locked är sann för de rutor vars siffror är givna från början.) En tryckning på mellanslag, backspace eller delete skall sätta state[row][col] till mellanslag om locked[row][col] är falsk. En tryckning på en piltangent skall uppdatera row och col på lämpligt sätt. Kolumnerna går från vänster till höger och raderna går uppifrån och ner. Variablerna row och col måste alltid ha värden i intervallet 0 till och med 8. Slutligen skall metoden repaint() anropas om och endast om state, row eller col har ändrats.