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.

[N?kkeloppg.]: 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

  1. 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
    


  2. 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]


  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.


  4. 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.


  5. 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);
    
        }
    }
    


  6. 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(); }".

    (b) Utvid programmet slik at det ogs? leser innholdet i filen som ble opprettet i del (a), lagrer det i fire passende variabler (den f?rste skal v?re av typen char, osv.), og skriver til slutt verdiene i variablene ut p? skjerm. 
    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)).



  7. [N?kkeloppg.]: 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.


  8. 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);
                        ^
    


  9. 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));


  10. 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).
    
        // . . .
    }
    


  11. 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. 


  12. [N?tteoppg.]: 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").



  13. [N?tteoppg.]: 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.



  14. 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