Ukeoppgaver 5: 21. - 27. sep (INF1000 - H?st 2011)
Filer; tekst; repetisjon av metoder (kapittel 3 og 6 i "Rett p? Java" 3. utg.)
M?l
F? ?velse i teorien du trenger for ? l?se Oblig 2 (l?kker,
arrayer, tekster, og metoder); og i tillegg litt om innlesing og utskrift til fil.
Oppgave merket med n?kkelsymbol er plukket ut som spesielt representativ for de viktigste temaene fra ukens forelesning, og alle b?r ha som minimumsm?l ? l?se denne selvstendig.
Oppgaver
- Enkle l?kker med tall:
(a) Nedtelling: Lag et program med en l?kke som teller ned fra 10 til 0. Bruk en teller-variabel med startverdi 10 og redusér den med 1 i hver gjennomgang av l?kka. Utskriften skal bli:...10 ...9 ...8 ...7 ...6 ...5 ...4 ...3 ...2 ...1 ...0
(b) Dobling: Lag en l?kke som starter med ? skrive ut tallet 2, og deretter dobler tallet, skriver det ut, og gjentar prosessen helt til 10 tall er skrevet ut. Bruk en teller-variabel "i" som teller de 10 gangene, og en annen variabel for tallet som ganges med 2 i hver omgang av l?kka og skrives ut. Utskriften skal bli:2 4 8 16 32 64 128 256 512 1024
(c) Tabell: Lag to nestede for-l?kker som gir f?lgende utskrift. Det skal bare skrives ut ett tall av gangen, som skal v?re verdien til telleren i den ytre l?kka (som g?r fra 1 til 3 og skal hete rad) ganget med telleren i den indre l?kka.1 2 3 4 2 4 6 8 3 6 9 12
- 2D-array (to-dimensjonal array) med tall:
(a) Utskrift: Lag to nestede for-l?kker som setter inn f?lgende verdier i en 2D-array og skriver de ut. Arrayen skal deklareres slik:int[][] tabell = new int[3][4];. Se oppgave nr. 1 (c) over for tips om disse verdiene. Husk at indeksene i arrayen starter fra 0, ikke 1. Verdien i tabell[2][3] skal v?re 12.1 2 3 4 2 4 6 8 3 6 9 12
(b) Sum av kolonne: Skriv programkode som beregner summen av verdiene i hver kolonne i ovennevnte array og skriver summene ut. Dette ligner p? en deloppgave i oblig 2!6 12 18 24
(c) S?k etter tall: Utvid programmet slik at det ber bruker taste inn et tall og deretter ser om tallet finnes i arrayen. Hvis tallet finnes skal alle array-indeksene der det ligger skrives ut, hvis ikke skal det gis beskjed om at tallet ikke finnes.Hvilket tall s?ker du: 8 Tallet finnes i tabell[1][3]
- Tekster: Antall tegn, store bokstaver, og like
tekster kap. 6, oppg. 1 (side 117)
Lag et program som:
(a) ber brukeren skrive inn en tekst og beregner antall tegn i teksten.
(b) ber brukeren om ? skrive inn en tekst og lager en ny tekst av den gamle med bare store bokstaver, og skriver ut den nye teksten. (Tips: Se sp?rsm?l "o" i oppgave 5 nedenfor.)
(c) ber brukeren skrive inn to ord og tester om disse er like. - String og charAt: Ord baklengs kap. 6, oppg. 3 (a)-(b), (side 117)
(a) Lag et program som skriver ut teksten ?Agnes i senga? baklengs. Hint: Bruk en for-l?kke som teller nedover.
(b) Modifiser programmet over slik at det f?rst gj?r om teksten til kun ? inneholde sm? bokstaver. - Tekster: Hva blir skrevet ut?
class Tekster { public static void main(String[] args) { Out skjerm = new Out(); String s1 = "hei"; String s2 = "Java"; String[] navn = { "Rune", "Martin", "", "Guro" }; /* a */ System.out.println(navn.length + s1.length()); /* b */ System.out.println(3.1415 + "" + 'x'); /* c */ System.out.println("" + false); /* d */ System.out.println("" + ! "abc".equals("abc")); /* e */ System.out.println("heia" == (s1 + "a")); /* f */ System.out.println("heia".equals(s1 + s2.charAt(1))); /* g */ System.out.println(s1.equals("h" + navn[0].charAt(3) + 'i')); /* h */ System.out.println(navn[1].substring(1)); /* i */ System.out.println(navn[1].substring(1, 4)); /* j */ System.out.println(s2.replace('a', 'i')); /* k */ System.out.println(navn[1].indexOf("tin")); /* l */ System.out.println(navn[2].indexOf("tin")); /* m */ System.out.println("A".compareTo("A")); /* n */ if (s1.compareTo("zz") < 0) System.out.println("s1 alfabetisk foran"); /* o */ System.out.println(navn[3].toUpperCase()); /* p */ if ("hei p? deg".startsWith(s1)) { System.out.println("ja"); } /* q */ int x = Integer.parseInt("123"); System.out.println(x + 1); } }
- Innlesing og utskrift til fil:
(eksempel side 52 i l?reboka)
(a) Ta utgangspunkt i f?lgende program, fra side 52 i l?reboka, som skriver fire typer verdier til skjerm (tegn, linje, heltall, og desimaltall), og endre programmet slik at utskriften g?r til en fil i stedet. Kall utfilen "minfil.txt".import easyIO.*; class Utskrift { public static void main(String[] args) { Out skjerm = new Out(); skjerm.outln('A'); skjerm.outln("Canis familiaris betyr hund"); skjerm.outln(15); skjerm.outln(3.1415, 2); // Bruk to desimaler } }
Hint:- EasyIO: Utskrift til fil programmeres nesten p? samme m?te som utskrift til skjerm, bare at man angir filnavn i klargj?ringen av "new Out", bruker et annet navn p? forbindelsen (f.eks. "utfil" i stedet for "skjerm"), og lukker filen til slutt. Mer detaljert: Klargj?r for utskrift til fil med f.eks. "Out utfil = new Out("minfil.txt");" Deretter bruker du utfil.out/outln for utskrift til fil p? samme m?te som du ville brukt skjerm.out/outln for utskrift til skjerm. Til slutt lukker du filen med utfil.close();. Hvis man glemmer close blir ingenting lagret i filen.
PrintWriter/printf: NB! Dette er bare ment for spesielt interesserte som vil pr?ve uten EasyIO.
Klargj?r for utskrift til fil med "import java.io.*;" og "PrintWriter utfil = new PrintWriter(new File("minfil.txt"));". Deretter bruker du utfil.print/println/printf for utskrift til fil p? samme m?te som du ville brukt System.out.print/println/printf for utskrift til skjerm. Til slutt utfil.close(); I tillegg b?r du ha "try{" i begynnelsen av metoden (f?r setningen med "new PrintWriter") og f?lgende p? slutten av metoden (du vil l?re mer om dette i INF1010, forel?pig er det nok at du bare skriver det helt likt): "} catch (Exception e) { e.printStackTrace(); }".
Hint: Innlesing fra fil programmeres som innlesing fra tastatur, bare at man angir filnanvet under klargj?ring, f.eks. "In innfil = new In("minfil.txt");", og bruker gjerne et annet navn p? forbindelsen (f.eks. "innfil" i stedet for "tast"). Hvis du vil pr?ve uten EasyIO klargj?r med "Scanner innfil = new Scanner(new File("minfil.txt"));" og legg try- og catch rundt metoden (se hintet i del (a)). - Lese to arrayer fra fil: kap. 5, oppg. 3 (side 99)
Lag et program som skal behandle data om vekten til elevene i en skoleklasse. Det er 27 elever i klassen. Dataene ligger p? fil slik:Jens 52 Marit 43 ...
(a) Les dataene inn i to arrayer: en navnearray (String) og en vektarray (int).Hint: Se "// Fil til array" p? side 62 i l?reboka.
(b) La programmet finne h?yeste og laveste vekt og skrive ut navn og vekt p? disse.
(c) La programmet beregne gjennomsnittsvekten i klassen. - Finn feil:
N?r vi pr?ver ? kompilere og kj?re dette programmet f?r vi feilmeldingene vist nedenfor. Hva er feil?1 class FinnFeil { 2 int[] fat = new int[5]; 3 System.out.println("Feilplassert"); 4 5 public static void main(String[] args) { 6 FinnFeil ff = new FinnFeil(); 7 ff.metode(); 8 } 9 10 void metode() { 11 for (int i = 0; i < 5; i++) { 12 fat[i] = 10 * i; 13 } 14 15 System.out.println(fat[5]); 16 System.out.println(fat2); 17 System.out.println(fat[1], 2); 18 } 19 }
Hva betyr disse feilmeldingene, og hvordan retter vi feilene?(a) FinnFeil.java:3: <identifier> expected System.out.println("Feilplassert"); ^ FinnFeil.java:3: illegal start of type System.out.println("Feilplassert");^ (b) Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5 at FinnFeil.metode(FinnFeil.java:15) at FinnFeil.main(FinnFeil.java:7) (c) FinnFeil.java:16: cannot find symbol symbol : variable fat2 location: class FinnFeil System.out.println(fat2); ^ (d) FinnFeil.java:17: cannot find symbol symbol : method println(int,int) location: class java.io.PrintStream System.out.println(fat[1], 2); ^
- Metode med inn og ut-parametre: kap. 7, oppg. 2 (side 133)
Lag en metode som regner ut hypotenusen c i en rettvinklet trekant n?r vi g?r ut fra Pytagoras formel:c? = a? + b? der a og b er lengden p? katetene ? de to andre sidene i trekanten. Vi bruker a og b som parametre til metoden. Du trenger da ? kalle kvadratrotmetoden i Math.sqrt(double_verdi) i den metoden du lager. Returner verdien c som verdien p? metoden. Test metoden ved ? kalle den i en dobbel for-l?kke for alle kombinasjoner av a og b med heltallsverdiene fra 1.0 til og med 6.0, og skriv ut svarene.double finnHypotenus(double a, double b) { // ... return c; }
Hint: Kallet p? metoden kan se slik ut:double c = finnHypotenus(a, b); ...eller: System.out.println(finnHypotenus(a, b)); - Mer om metoder
Fullf?r f?lgende program, som viser bruk av metoder. Angi ogs? hva programmet skriver ut.import java.util.Scanner; // Tilsvarer: import easyIO.*; class Metoder { public static void main(String[] args) { TestMetoder tm = new TestMetoder(); tm.start(); } } class TestMetoder { Scanner tast = new Scanner(System.in); // Tilsvarer: In tast = new In(); void start() { // Kaller en enkel metode: metode1(); // Kaller en metode med én inn-parameter: skrivTredoblet(123); // Leser to tall fra tastatur, og overf?rer de til en metode // som finner og skriver ut det h?yeste av de to tall: skjerm.out("Skriv to tall (f.eks. 7 4): "); int tall1 = tast.nextInt(); // Tilsvarer: ... = tast.inInt(); int tall2 = tast.nextInt(); // Tilsvarer: ... = tast.inInt(); finnH?yesteAv2(tall1, tall2); // Kaller en metode som multipliserer de samme to tall lest // inn ovenfor, og returnerer resultatet hit. int resultat = multipliser( /* Fyll inn resten. . . */ ); skjerm.outln("Resultat multiplisert: " + resultat); // Metode med array som inn-parameter: double[] verdier = { 0, -3, 5, 10, -20, -7.7, 1.2, -0.01 }; //int antNeg = finnAntallNegativeTall(verdier); //skjerm.outln("Arrayen verdier[] har " + antNeg + " negative tall."); // <- Ta bort "//" i de to linjene over. } void metode1() { skjerm.outln("Dette er metode1"); } void skrivTredoblet(int x) { int tredoblet = x * 3; skjerm.outln("Tredoblet resultat = " + tredoblet); } void finnH?yesteAv2(int a, int b) { // Hva mangler her? // . . . skjerm.outln("H?yest av de to tall er:" /* . . . */ ); } int multipliser( /* Fyll inn resten. . . */) { // . . . return 0 ; // . . . Erstatt 0 med resultatet av x ganger y. } // Skriv metoden "finnAntallNegativeTall" her, som har en array med // double-verdier som inn-parameter, finner ut hvor mange av verdiene // i arrayen er negative tall, og returnerer det antallet (som en int). // . . . }
- Fibonacci-tallene
(a) L?kker: Lag et program som skriver ut de 15 f?rste tall i Fibonaccif?lgen. F?lgen er definert ved at de to f?rste tall er 0 og 1, og hvert neste tall er summen av de to foreg?ende. Utskriften skal bli:0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Mer info: Fibonacci-tallene forekommer mye i naturen, bl.a. i tregrener, blomster, kongler og kaniner.
(b) Metoder: Endre strukturen i Fibonacci-programmet du lagde ovenfor slik at det f?lger malen fra Oblig 2 (vist ogs? i oppgave nr. 8 fra forrige uke), med en kontrollklasse ?verst, etterfulgt av en hjelpeklasse for metodene. Bruk tre metoder i hjelpeklassen: en ordrel?kke som skriver ut f?lgende meny, og en metode for hvert av de 2 menyvalgene:
1. Skriv ut de 15 f?rste tall i Fibonaccif?lgen 2. Test om et tall h?rer til f?lgen
Metoden for ordre 2 ber bruker taste inn et tall, og g?r s? i en l?kke som genererer Fibonacci-tallene frem til det bruker-inntastede tallet. Deretter gis det melding til bruker om tallet h?rte til f?lgen eller ikke. -
Ukens n?tt 1: N?rmeste Fibonacci-tall (middels vanskelig)
Utvid ordre 2 i foreg?ende oppgave slik at den ogs? sier hvilket Fibonacci-tall er n?rmest det bruker-inntastede tallet. Hvis to er like n?rme, f.eks. hvis bruker tastet inn "4", skriv ut begge (i dette tilfellet "3" og "5"). -
Ukens n?tt 2: Sudoku
hjelpeprogram (middels vanskelig)
(a) Lag et program som leser inn en Suduko-oppgave fra fil og lagrer de forh?ndsutfylte tallene i en 2-dimensjonal array. Deretter g?r programmet i en l?kke som sp?r brukeren om et rad- og et kolonnenummer (i omr?det 1-9, eller 0 for ? avslutte). Programmet skal s? svare brukeren med hvilke tall (1-9) som er mulige kandidater for plassering i den angitte rad/kolonne-plassen, ved ? finne ut hvilke av sifrene 1-9 ikke er allerede brukt i samme rad, kolonne, eller 3×3-omsluttende boks.
Input-filen er p? 9 linjer, med 9 tall per linje adskilt med mellomrom, og hvor 0 angir plassene som ikke har forh?ndsutfylt siffer i Sudoku-oppgaven. Her er et eksempel p? en slik fil (med middels vanskelig oppgave). Finn gjerne andre oppgaver fra aviser eller nettet.6 0 7 0 0 0 0 8 0 0 0 0 1 0 4 0 7 0 0 0 5 0 0 8 0 3 0 8 0 0 3 0 0 7 0 0 4 0 0 5 0 6 0 0 8 0 0 1 0 0 2 0 0 6 0 8 0 4 0 0 5 0 0 0 9 0 2 0 3 0 0 0 0 7 0 0 0 0 1 0 3
(b) Utvid deretter programmet slik at det g?r gjennom alle ikke-utfylte ruter (i stedet for ? be brukeren taste en), og for de rutene som bare har ett kandidatsiffer setter du sifferet inn i arrayen. Gjenta prosessen med de gjenv?rende ikke-utfylte ruter helt til to p?f?lgende gjennomkj?ringer ikke finner nye tall ? sette inn. Skriv ut resultatbrettet til slutt. - Tips til Emacs: Linjenummer p? hver
linje
Du kan f? linjenummer p? hver linje i Emacs ved ? lime inn litt kode i din "~/.emacs"-fil, som forklart i veiledningen i Emacs-oppgavene fra Forkurs i informatikk.
L?sningsforslag
Her kan du finne l?sningsforslag til disse oppgavene. Det anbefales ? l?se oppgavene p? egen h?nd f?r du studerer l?sningsforslagene.Tibakemelding om dette oppgavesettet kan du skrive i bloggen eller sende p? mail til josek [a] ifi.uio.no