• No results found

Lösningsförslag tentamen FYTA11 Javaprogrammering

N/A
N/A
Protected

Academic year: 2022

Share "Lösningsförslag tentamen FYTA11 Javaprogrammering"

Copied!
9
0
0

Loading.... (view fulltext now)

Full text

(1)

Lunds universitet FYTA11 Institutionen f¨or Astronomi och Teoretisk fysik HT 12

L¨osningsf¨orslag tentamen FYTA11 — Javaprogrammering

Onsdag 5 december 2012, 10:15 – 14:15

Instruktioner

Hj¨alpmedel: Papper och penna. Behandla h¨ogst en uppgift per papper och s¨att ditt namn och uppgiftens nummer p˚ a varje papper. Skriv l¨asligt och kommentera utf¨orligt vad du g¨or – det kan ge dig po¨ang ¨aven om resultatet blir fel. Tentamen omfattar fyra uppgifter som vardera kan ge upp till tio po¨ang. F¨or G och VG kr¨avs 20 respektive 30 po¨ang, inr¨aknat de h¨ogst fem bonuspo¨angen fr˚ an simulerings¨ovningarna.

Uppgift 1: Sm˚ a fel

Korrigera felen i f¨oljande kodstycken.

a.

//if(arr.length = 3) System.out.println("Length is 3");

if(arr.length == 3) System.out.println("Length is 3");

b.

//JButton button;

JButton button = new JButton();

button.setText("Click me!");

c.

public static void main(String[] args) {

if(args.length != 1) {

System.out.println("This program requires one argument!");

System.exit(1);

}

//System.out.println("argument was: " + args[1]);

System.out.println("argument was: " + args[0]);

}

d.

//int year = 60 * 60 * 24 * 365;

long year = 60 * 60 * 24 * 365; // (eller m¨ojligen double) System.out.println("medellivsl¨angd: " + year * 80 + " sekunder");

e.

private String myName = "Steve";

// ...

public boolean isMyName(String name) {

// return myName == name;

return myName.equals(name);

}

(2)

f.

//System.out.println("pi is roughly = " + 22/7);

System.out.println("pi is roughly = " + 22./7);

g.

//System.out.println("pi is roughly = " + 3 + Math.sqrt(0.02));

System.out.println("pi is roughly = " + (3 + Math.sqrt(0.02)));

h.

double x, y;

do {

x = Math.random() * 2 - 1;

y = Math.random() * 2 - 1;

// double r2 = x * x + y * y;

//} while(r2 < 1);

} while(x * x + y * y < 1);

i.

Object[] v = new Object[2];

v[0] = "Something";

v[1] = 123;

// ...

//String thing = v[0];

String thing = (String)v[0];

j.

public class Vehicle {

private String model;

public Vehicle(String model) {

this.model = model;

} }

// I en annan fil:

public class Bicycle extends Vehicle {

public Bicycle(String model) {

// this.model = model;

super(model);

} }

(3)

Uppgift 2: Median av avrundade argument

Skriv ett program som tar en upps¨attning tal som argument d˚ a det startas, och skriver ut medianen av talen efter att ha avrundat vart och ett av dem till n¨armaste heltal.

Medianen av ett udda antal tal definieras som det tal som ligger i mitten n¨ar talen sorterats. Medianen av ett j¨amnt antal tal ¨ar medelv¨ardet av de tv˚ a mittersta talen (och beh¨over allts˚ a inte vara ett heltal).

Exempelvis skall

% java Median 11.2 -33.3 12.2 0 90 skriva ut talet 11 (eller 11.0), medan

% java Median 11.2 12.2 0 90 skriver ut 11.5.

Om n˚ agot av argumenten inte ¨ar ett tal skall en varning skrivas ut men programmet f˚ ar inte avbrytas utan skall f¨ors¨oka anv¨anda resterande argument. Om det inte finns n˚ agra giltiga tal alls s˚ a skall ett felmeddelande skrivas ut.

public class Median {

public static void main(String[] args) {

// G¨or plats till s˚a m˚anga tal som det finns argument // men h˚all reda p˚a hur m˚anga som stoppats in.

double[] arr = new double[args.length];

int num = 0; // antal tal

for(int i = 0; i < args.length; ++i) { try {

// Om konverteringen lyckas sparar vi talet (avrundat) och ¨okar num double v = Double.parseDouble(args[i]);

arr[num++] = Math.rint(v);

} catch(NumberFormatException e) {

System.err.println(args[i]+ " ¨ar inte ett tal");

} }

if(num == 0) {

System.err.println("inga tal givna");

return;

}

// Sortera talen och finn medianen java.util.Arrays.sort(arr, 0, num);

if(num % 2 == 1)

System.out.println(arr[num/2]);

else

System.out.println((arr[num/2] + arr[num/2-1]) / 2);

// alternativt kan man bli av med if-satsen genom att notera att // num/2 och (num-1)/2 ¨ar identiska om num ¨ar udda:

// System.out.println((arr[num/2] + arr[(num-1)/2]) / 2);

} }

(4)

Uppgift 3: Molly Malone

Molly Malone g˚ ar med sin k¨arra och s¨aljer fisk i Dublin. Hon antecknar fisksorten och antalet vid varje f¨ors¨aljning, och vill sedan sammanst¨alla informationen med hj¨alp av ett datorprogram. Du beh¨over hj¨alpa Molly att skriva en metod som sorterar fiskarna och summerar ihop antalet av respektive sort.

I klassen FishNotes finns en inre klass FishCount som representerar en rad i Mollys anteckningar, med namnet p˚ a en fisk och antalet av den sorten. Ditt jobb ¨ar att:

(a) skriva klart metoden summarize() som skall byta ut inneh˚ allet i fishCounts s˚ a som beskrivs i koden: Efter summarize() skall fiskarna vara sorterade alfabetiskt och ihopsummerade efter fisksort (8p).

(b) beskriva i ord (eller med kod) hur du skulle g¨ora f¨or att i st¨allet sortera fiskarna efter antal (fortfarande summerade efter sort), utifr˚ an din l¨osning till (a) (2p).

Det finns flera olika s¨att att l¨osa problemet. F¨oljande sidor ger dokumentation f¨or n˚ agra olika klasser och metoder som kan vara anv¨andbara.

Minns ocks˚ a hur man itererar ¨over en Collection (som t.ex. ArrayList):

for(Iterator<?> it = c.iterator(); it.hasNext(); ) {... it.next() ...}

alternativt for(Element type e : collection) {...}

Exempel: om fishCounts inneh˚ aller (Sill, 12), (Torsk, 2), (Lax, 5), (Sill, 7) f¨ore anropet till summarize s˚ a skall fishCounts efter anropet inneh˚ alla (Lax, 5), (Sill, 19), (Torsk, 2).

Vissa dagar s¨aljer Molly otroligt m˚ anga fiskar s˚ a det ¨ar l¨ampligt att metoden inte skalar kvadratiskt (eller v¨arre) med antalet element i fishCounts.

L¨ osningsf¨ orslag till (a) finns p˚ a f¨oljande sidor. Uppgift (b) l¨oses b¨ast genom att

man sorterar med en Comparator liknande den i andra l¨osningsf¨orslaget, men med

j¨amf¨orelse av count. Om man vill kan man i andra hand (dvs om talen ¨ar lika) ocks˚ a

j¨amf¨ora fish s˚ a att fiskar med samma antal blir sorterade alfabetiskt.

(5)

En l¨osning med Comparable, med ¨andringar i FishCount:

import java.util.*;

public class FishNotes {

/** Ett par av (namn, antal) f¨or n˚agon sorts fisk */

// public class FishCount ** ¨andrad till:

public class FishCount implements Comparable<FishCount>

{

public String fish;

public int count;

public FishCount() {}

public FishCount(String f, int c) {

fish = f;

count = c;

}

// Ny metod:

public int compareTo(FishCount o) {

return fish.compareTo(o.fish);

} }

/** Listan ¨over s˚alda fiskar */

private ArrayList<FishCount> fishCounts = new ArrayList<FishCount>();

/** L¨agger till en post till fisklistan */

public void addFish(String name, int count) {

fishCounts.add(new FishCount(name, count));

}

/** Sammanst¨aller listan ¨over fiskar s˚a att fiskarna kommer i alfabetisk ordning och varje fisksort finns med en g˚ang, tillsammans med totala antalet av den sorten. */

public void summarize() {

Collections.sort(fishCounts);

ArrayList<FishCount> newfc = new ArrayList<FishCount>();

String prevfish = null;

int cnt = 0;

for(FishCount fc : fishCounts) {

if(fc.fish.equals(prevfish)) cnt += fc.count;

else {

if(prevfish != null)

newfc.add(new FishCount(prevfish, cnt));

prevfish = fc.fish;

cnt = fc.count;

} }

if(prevfish != null)

newfc.add(new FishCount(prevfish, cnt));

fishCounts = newfc;

}

/** Skriver ut fisklistan */

public void print() {

for(FishCount fc : fishCounts)

System.out.println(fc.fish + "\t" + fc.count);

} }

(6)

En l¨osning med Comparator och en anonym klass som g¨or att man slipper ¨andra utanf¨or summarize:

public void summarize() {

// Vi vill slippa hantera tomma samlingar if(fishCounts.size() < 2)

return;

// Sortera p˚a fisknamn med en anonym Comparator-klass Collections.sort(fishCounts, new Comparator<FishCount>() {

public int compare(FishCount f1, FishCount f2) {

return f1.fish.compareTo(f2.fish);

} });

// Skapa en ny samling fiskar. G˚ar igenom fisklistan och adderar upp // antalen och sparar en fisk n¨ar vi ser en v¨axling till en annan sort.

ArrayList<FishCount> newfc = new ArrayList<FishCount>();

FishCount nfc = null;

for(FishCount fc : fishCounts) {

if(nfc == null) // F¨orsta fisken, ta den (vi sabbar gamla fishCounts) nfc = fc;

else if(fc.fish.equals(nfc.fish)) // Samma fisk; ¨oka antalet nfc.count += fc.count;

else { // Annan fisk; nu kan vi spara den f¨orra med r¨att antal newfc.add(nfc);

nfc = fc;

} }

newfc.add(nfc); // Sista fisken i listan fishCounts = newfc;

}

En kortare l¨osning med TreeMap:

public void summarize() {

// Vi l¨agger fiskarna i ett tr¨ad s˚a blir de sorterade efterhand.

TreeMap<String, Integer> tree = new TreeMap<String, Integer>();

for(FishCount fc : fishCounts) {

// Om fisken redan finns i tr¨adet s˚a ¨oka dess antal.

int cnt = fc.count;

if(tree.containsKey(fc.fish)) cnt += tree.get(fc.fish);

tree.put(fc.fish, cnt);

}

// Kopiera fr˚an tr¨adet till fishCounts

fishCounts = new ArrayList<FishCount>(); // clear() vore b¨attre for(Map.Entry<String,Integer> ent : tree.entrySet())

addFish(ent.getKey(), ent.getValue());

(7)

Uppgift 4: Partiklar i potential

Du skall simulera partiklar som r¨or sig i en potential och p˚ averkar varandra. F¨or enkelhets skull antas alla partiklar ha massan 1, s˚ a acceration och kraft ¨ar ekvivalen- ta. Simuleringsrogrammet finns redan, men du beh¨over skriva kod f¨or ditt specifika system. Allting g¨ors i tv˚ a dimensioner, och klassen Pair (se n¨asta sida) anv¨ands f¨or att representera b˚ ade en punkt (x, y) och en kraftvektor (F

x

, F

y

).

Potentialen som du har ges av

U (r) =

( −

kr

r ≥ 1 k r < 1

d¨ar k ¨ar n˚ agon konstant, vilket ger accelerationen (och kraften)

a(r) =

( −k

rr3

r ≥ 1 0 r < 1 f¨or en partikel i punkten r = (x, y). r ¨ar l¨angden av r.

(a) Implementera interfacet Potential (se n¨asta sida), i ¨overensst¨ammelse med ekvationerna ovan. Din klass heter l¨ampligen MyPotential, och skall ta konstanten k som argument till sin konstruktor.

(b) Potential har en metod randomPosition som beh¨ovs f¨or att kunna slumpa ut positioner p˚ a l¨ampliga positioner. Implementera den metoden s˚ a att den returnerar en slumpm¨assig position r j¨amnt f¨ordelad ¨over det omr˚ ade d¨ar 1 < r < 2.

Kraften som verkar p˚ a en partikel i till f¨oljd av v¨axelverkan med ¨ovriga partiklar ¨ar F

i

= X

j6=i

(r

i

− r

j

)

|r

i

− r

j

|

3

och den totala energin i v¨axelverkningarna ¨ar

E = X

i

X

j6=i

1

|r

i

− r

j

|

(c) L¨agg till interaktioner mellan partiklarna genom att implementera interfa-

cet InteractionPotential. De b˚ ada metoderna tar in positionerna hos samtli-

ga partiklar. getForces returnerar krafterna fr˚ an v¨axelverkan mellan partiklar-

na, med en kraftvektor per partikel. getEnergy returnerar den totala energin hos

v¨axelverkningarna.

(8)

/** Ett par av v¨arden (x,y), dvs en vektor i 2 dimensioner */

public class Pair {

public double x;

public double y;

public Pair() {}

public Pair(double xx, double yy) {

x = xx;

y = yy;

} }

public interface Potential {

/** Returnerar den potentiella energin hos en partikel p˚a den givna positionen. */

double getEnergy(Pair position);

/** Returnerar ett Pair (en vektor (Fx,Fy)) som representerar kraften som verkar p˚a en partikel p˚a den givna positionen (gradienten av -energin). */

Pair getForce(Pair position);

/** Genererar en slumpm¨assig punkt i ett l¨ampligt omr˚ade f¨or en partikel

** att starta fr˚an i simuleringen. */

Pair randomPosition();

}

L¨ osningsf¨ orslag (a-b):

public class MyPotential implements Potential {

private double k;

public MyPotential(double k) {

this.k = k;

}

// For convenience: distance to origin for a position private static double posR(Pair p)

{

return Math.sqrt(p.x * p.x + p.y * p.y);

}

public double getEnergy(Pair pos) {

double r = posR(pos);

if(r < 1) return k; // skulle ha varit -k return -k / r;

}

public Pair getForce(Pair pos) {

double r = posR(pos);

if(r < 1) return new Pair();

double a = -k / (r * r * r);

return new Pair(a * pos.x, a * pos.y);

}

public Pair randomPosition() {

double a = Math.random() * 2 * Math.PI;

double r = Math.random() + 1;

return new Pair(r * Math.cos(a), r * Math.sin(a));

(9)

public interface InteractionPotential {

/** Returnerar den totala interaktionsenergin hos en upps¨attning partiklar p˚a de givna positionerna. */

double getEnergy(Pair[] positions);

/** Returnerar ett f¨alt med lika m˚anga Pair som i argumentet. Argumentets Pair representerar partiklarnas koordinater och returv¨ardets Pair representerar de krafter som verkar p˚a var och en av partiklarna till f¨oljd av v¨axelverkan mellan dem. */

Pair[] getForces(Pair[] positions);

}

L¨ osningsf¨ orslag (c):

public class MyInteraction implements InteractionPotential {

// Avst˚andet mellan tv˚a punkter, s˚a vi slipper skriva uttrycket flera g˚anger private static double dist(Pair a, Pair b)

{

return Math.sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));

}

public double getEnergy(Pair[] pos) {

double E = 0;

for(int i = 0; i < pos.length; ++i) {

for(int j = 0; j < pos.length; ++j) {

if(i != j)

E += 1 / dist(pos[i], pos[j]);

} }

return E;

}

public Pair[] getForces(Pair[] pos) {

Pair[] f = new Pair[pos.length];

for(int i = 0; i < pos.length; ++i) {

f[i] = new Pair();

for(int j = 0; j < pos.length; ++j) {

if(i != j) {

double d3 = Math.pow(dist(pos[i], pos[j]), 3.);

f[i].x += (pos[i].x - pos[j].x) / d3;

f[i].y += (pos[i].y - pos[j].y) / d3;

} } }

return f;

} }

References

Related documents

Finns erforderliga rutiner och skyddsåtgärder för sådant arbete. Ja

A-traktor med en totalvikt av högst 3 500 kg, som tas i bruk den 1 januari 2004 eller senare (blev godkänd som A-traktor 1 januari 2004 eller senare) skall med avseende på

spänningarna över komponenterna.. Det leder till samma resultat, men blir lite mer att räkna.. Alltså kan sysemet H inte vara tidsinvariant. c) Det räcker inte med att observera

Best¨am den st¨orsta arean man kan f˚a av en rektangel som kan beskrivas s˚a att varje sida g˚ar genom var sitt h¨orn av en annan rektangel med sidl¨angderna a och

(I origo kan vi inte anv¨anda gradienterna f¨or att hitta en normalvektor eftersom gradienterna ¨ar noll. Detta ¨ar tv˚a par av linjer, men de ¨ar orienterade med en vinkel π/4

Ellipse -xradius :double -yradius :double +getWidth():double +getLength ():double +getArea():double +draw():void +erase():void. +move(dx:double,dy:double):void

För att rätta till felet kan vi således ändra namnet på den egna klassen eller specificera att det är klassen java.lang.Math vi avser. Specificera namnet

Därefter återgår exekveringen till raden efter super-anropet i klassen Uppgift7_1 där samma utskrift sker, men nu är det innehållet i Uppgift7_1’s fält klass som skrivs