Ukeoppgaver 4:  14. - 20. sep (INF1000 - H?st 2011)

Metoder, flerdimensjonale arrayer  (kapittel 7.1-7.7, 5.7 i "Rett p? Java" 3. utg.)

M?l
?ve p? bruk av forgreninger, l?kker, arrayer, og metoder.

[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. Enkel kalkulator med if-else og switch:
    [ NB! Vi bruker en litt spesiell m?te ? gi input i denne oppgaven, der bruker m? taste mellomrom mellom de tre delene av regnestykket (f.eks. "4 + 5"), men du vil l?re hvordan programmet kan godta andre skrivem?ter neste uke. ]
    (a) Lag en kalkulator som st?tter enkle regnestykker p? formen: tall operator tall, hvor de tre elementene er adskilt med mellomrom.  Tall er heltall, og operator er en av de fire regneartene: + - * /.  Eksempel p? kj?ring av programmet:
    Regnestykke: 4 + 5
    Resultat: 9
    
    Bruk tast.inInt() og tast.inChar(" ") for ? lese tall og regneart fra tastaturet (hvis du bruker EasyIO, hvis ikke se "Hint" nedenfor).  Mellomrommet i parentesene til inChar angir at den skal betrakte mellomrom som et skilletegn f?r og etter regnearten.  Dette er n?dvendig ? si fra til inChar, fordi den leser inn ett tegn av gangen.  Lagre tallene og operator i passende variabler, og bruk if-else-setninger til ? velge hvilken regneart skal utf?res. 
    Hint for ? l?se det uten EasyIO: Bruk scan.nextInt() i stedet for tast.inInt(), og scan.next().charAt(0) i stedet for tast.inChar(" ");.

    (b) Hvordan kan programmet endres for ? bruke en switch-setning i stedet for if-else?  (Hint: Se eksemplet p? side 80 i l?reboka, og husk ? ta med break;-setningene.)

    (c) Hva slags divisjon f?r vi utf?rt?, og hvordan kan vi endre programmet for ? f? utf?rt den andre typen divisjon uten ? endre deklarasjonen av de to innleste heltall?


  2. L?kker: Hva blir skrevet ut?
    Avgj?r uten ? bruke datamaskin hva som blir skrevet ut n?r f?lgende programsetninger utf?res.
    //(a)
           int a = 10;
           while (a < 20) {
               a += 4;
           }
           System.out.println("a = " + a);
    
    //(b)
           int sum = 0;
           for (int b = 1; b < 6; b += 2) {
               sum += b;
           }
           System.out.println("sum = " + sum);
    
    //(c)
           int produkt = 1;
           for (int c = 1; c < 4; c++) {
               produkt = produkt * c;
    	   System.out.println(produkt);
           }
    
    //(d)
           for (int d = 3; d >= 1; d--) {
               for (int e = 1; e <= 3; e++) {
                   System.out.println(d + e);
               }
           }
    
    //(e)
           int teller = 0;
           for (int ytre = 0; ytre < 3; ytre++) {
               teller++;
               for (int indre = 0; indre < 3; indre++) {
                   teller++;
               }
           }
           System.out.println(teller);
    


  3. Utskrift og sum av oddetalls-array: kap. 5, oppg. 1-2 (side 99)
    (a) Skriv et program som inneholder en heltalls-array med f?lgende elementer: 1, 3, 5, 7, 9, 11, 13, 15, 17, 19.  Programmet skal inneholde en l?kke som skriver ut indeksen og verdien for alle elementene i arrayen.

    (b) Sum av elementene i en array: Vi bruker her samme array som i forrige oppgave: Beregn summen av elementene og skriv ut resultatet.


  4. S?ke etter tall i array:
    (a) Utvid programmet fra forrige oppgave slik at det ber bruker taste inn et tall, og deretter skriver ut en beskjed om det inntastede tallet finnes eller ikke finnes i arrayen.

    (b) Legg ogs? til en l?kke som skriver ut alle verdiene i arrayen som er mindre enn det inntastede tallet.


  5. Flerdimensjonal array:
    To-dimensjonale arrayer brukes p? samme m?te som en-dimensjonale, men har to sett med klammer, og gjennomg?s best ved hjelp av to nestede for-l?kker, som vist i f?lgende program:
    import easyIO.*;
    class Array2D {
       public static void main(String[] args) {
    
            int[][] b = new int[3][4];
    
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 4; j++) {
    
                    b[i][j] = i * j;
    
                    System.out.println(<Hva mangler her?>);
                }
            }
       }
    }
    Arrayen kan illustreres slik:
      0 1 2 3
    0_
    1_
    2_
    KJ?REEKSEMPEL:
    > java Array2D     
    b[0][0] = 0
    b[0][1] = 0
    b[0][2] = 0
    b[0][3] = 0
    b[1][0] = 0
    b[1][1] = 1
    b[1][2] = 2
    b[1][3] = 3
    b[2][0] = 0
    b[2][1] = 2
    b[2][2] = 4
    b[2][3] = 6
    (a) Hvor mange elementer er det plass til i arrayen b vist over?
    (b) Hva er array-indeksene til array-elementene i tredje kolonne, og hvilke verdier f?r disse elementene i programmet over?
    (c) Fullf?r println-setningen i programmet ovenfor slik at det gir utskriften vist under "Kj?reeksempel".


  6. Blokker og skop:
    Hvilke av disse programmene er lovlige?
    class Prog1 {
        public static void main(String[] args) {
            int k = 0;
            if (k >= 0) {
                int n = k + 1;
            }
            System.out.println(n);
        }
    }
    
    class Prog2 {
        public static void main(String[] args) {
            int k = 0;
            if (k >= 0) {
                int n = k + 1;
            }
            if (k < 0) {
                System.out.println(n);
            }
        }
    }
    
    class Prog3 {
        public static void main(String[] args) {
            int k = 0;
            if (k >= 0) {
                k++;
                System.out.println(k);
            }
        }
    }
    


  7. inLine(), inChar(), og ordrel?kke:
    Lag et program som sp?r bruker etter et navn.  Programmet leser navnet inn ved hjelp av inLine() (hvis du bruker EasyIO) eller med nextLine (hvis du bruker Scanner); og "fyller" s? skjermen med navnet ved ? skrive det ut 100 ganger.  Videre skal programmet sp?rre bruker om hun vil gi et nytt navn (j/n).  Svaret leses n? med .inChar("\n\r") hvis du bruker EasyIO (for tips uten EasyIO se "Hint" nedenfor), og hvis det er 'j' gjentas hele prosessen; hvis svaret ikke er 'j' avsluttes programmet.  Kj?reeksempel:
    Skriv et navn: Ola Nordmann
    Ola Nordmann Ola Nordmann Ola Nordmann Ola Nordmann Ola Nordmann O
    la Nordmann Ola Nordmann Ola Nordmann Ola Nordmann Ola Nordmann Ol
    a Nordmann Ola Nordmann Ola Nordmann Ola Nordmann Ola  ...osv...
    Gi nytt navn? (j/n): j
    Skriv et navn:
    
    Hint: Legg merke til det som st?r i parentesene til .inChar("\n\r") ovenfor (i varianten med EasyIO). Det som man skriver i disse parentesene kalles for "skilletegn" og angir hvilke tegn som ikke skal regnes som svaret (men i stedet regnes bare som skilletegn som adskiller evt. forskjellige svar). I dette tilfellet skal programmet hoppe over evt. linjeskift (\n) eller vognretur (\r) som bruker har tastet inn, og i stedet lese inn en vanlig bokstav fra tastatur, f.eks. 'j'. Det samme kan man ogs? f? til uten EasyIO ved hjelp av scan.nextLine().charAt(0); tips om dette finner du i kommentar #4 i bloggposten EasyIO.


  8. [N?kkeloppg.]: Metoder:
    (a) Endre strukturen til programmet ditt fra oppgave nr. 7 over slik at det f?lger den typen programstruktur som vi skal bruke i Oblig 2 (vist i skissen nedenfor), dvs. med en liten kontrollklasse ?verst, etterfulgt av en egen klasse for metodene.  Hele programmet med begge klassene lagres i én fil, kalt Navn100.java (dvs. navnet til klassen med metoden main()).  Lag bare én metode i hjelpeklassen, kalt ordrel?kke(), som gj?r alt som st?r i nr. 7 ovenfor.
    import easyIO.*;
    
    class Navn100 {
        public static void main(String[] args) {
            Hjelpeklasse hj = new Hjelpeklasse();
            hj.ordrel?kke(); // Kj?rer metoden ordrel?kke() i hjelpeklassen
        }
    }
    
    class Hjelpeklasse {
        // Klargj?ring for innlesing/utskrift, gjelder for hele klassen:
        In tast = new In();
        Out skjerm = new Out();
    
        String navn;
    
        void ordrel?kke() {
            char giNyttNavn = 'j'; // Startverdi
    
            while (giNyttNavn != 'n') {
                // - Be bruker taste et navn og les det inn med .inLine();
                // - Utskrift av navn 100 ganger.
                // - Sp?r om bruker vil "Gi nytt navn? (j/n):", og .inChar("\n\r"):
    
    
            }
        }
    }
    
    Mer info: Grunnen til at vi skriver programmet p? denne m?ten med to klasser vil bli klarere n?r vi kommer til kapittel 8, men har sammenheng med at vi ?nsker ? lage gode "objektorienterte" program der vi jobber med "objekter".  I denne skissen er det fem pekere til objekter: args[], hj, tast, skjerm, og navn.

    (b) Flere metoder: Endre programmet slik at koden som skriver ut navnet 100 ganger flyttes til en egen metode kalt utskrift().  Husk ? legge inn et kall p? metoden p? det stedet i programmet du flyttet koden fra.

    (c) Inn-parameter: Endre programmet slik at det ogs? sp?r bruker hvor mange ganger navnet skal skrives ut.  Verdien som bruker taster skal overf?res som parameter til metoden utskrift() som du lagde i del (b).  Endre ogs? metoden utskrift(..) slik at den tar imot argumentet ved hjelp av parameteren int antall, slik:  void utskrift(int antall) {


  9. [N?tteoppg.]: Ukens n?tt 1: (vanskelig!)
    Lag et program som ber om 5 tall fra bruker, og deretter finner og skriver ut hvilke tall som er gjentatt blant disse.  F.eks. hvis bruker tastet inn 6 6 3 6 3, s? skal programmet gi meldingen: Tall som er gjentatt: 6 3 Send l?sningen din til josek [at] ifi.uio.no, s? legger jeg den ut i l?sningsforslagene!



  10. [N?tteoppg.]: Ukens n?tt 2: (vanskelig!)
    Lag en metode som skriver ut alle anagrammer av et ord p? 4 bokstaver som ligger i en char-array.  Anagrammene skal ha de samme 4 bokstavene, i alle mulige rekkef?lger og uten ? gjenta noen bokstav.  For eksempel, hvis ordet er deklarert som f?lger, er 4 av anagrammene som vist under, og totalt 24. Send l?sningen din til josek [at] ifi.uio.no, s? legger jeg den ut i l?sningsforslagene!
    char[] ord = { 'A', 'R', 'N', 'E' };
    
     Kj?reeksempel:
     ARNE
     AREN
     ANRE
     ANER
     ...20 ord til...
    
    Tips: En m?te ? l?se dette p? er med nestede l?kker som i utgangspunktet kan g? innom alle mulige kombinasjoner, inkludert AAAA, AAAE, osv. men slik at det bare blir utskrift av de med 4 forskjellige bokstaver.  Bruk den tomme strengen "" og + i utskriftssetningen for ? konvertere char-ene til tekst: System.out.println("" + ord[3] + ord[2] ···


  11. Tips til Emacs: (for spesielt interesserte)
    • Emacs-forkortelser: Legg til f?lgende fem linjer i din ~/.emacs-fil:
      (define-abbrev-table 'java-mode-abbrev-table '(
          ("psv" "public static void main(String[] args) {" nil 0)
          ("sop" "System.out.println" nil 0)
      ))
      (abbrev-mode 1)
      Deretter starter du Emacs p? nytt. N?r du skriver psv i et Java-program (etterfulgt av mellomrom eller linjeskift) s? vil det n? bli utvidet til: public static void main(String[] args) {, og tilsvarende for sop etterfulgt av (.  Legg gjerne til flere forkortelser.  Mer info om filen ~/.emacs kan du finne i Ukeoppgaver 2.
    • Undo: For ? angre siste redigering trykk C-_ (dvs. Ctrl-understrek), eller klikk p? ikonet med bilde av en ?b?yd pil? ?verst i Emacs-vinduet.
    • Copy/paste: For ? kopiere tekst fra et hvilket som helst sted p? skjermen til Emacs, start med ? markere teksten ved hjelp av musa. Deretter flytter du mus-pekeren til det stedet i Emacs-vinduet der du vil lime inn teksten, og trykker musens midt-knapp (dvs. hjul-tasten) rett ned. Ferdig! Du trenger alts? ikke trykke Ctrl-c eller h?yreklikk > Copy for ? velge teksten i Emacs, det er nok ? markere det.
    • Cut/paste: Hvis du vil klippe bort tekst og flytte det til et annet sted i Emacs-vinduet: markér teksten; trykk Delete-tasten eller C-w for ? klippe det bort; flytt tekst-mark?ren til ?nsket sted; og trykk Insert-tasten eller C-y for ? lime inn.
    • Splittet vindu: For ? kunne se to filer samtidig kan du dele Emacs-vinduet i to ved ? trykke C-x 2 ("C-" st?r for Ctrl-tasten). For ? g? tilbake til ? vise én fil klikk med musa p? ?nsket del av splitt-vinduet og trykk C-x 1.
    • Flere vinduer: For ? ?pne et ekstra-Emacs-vindu slik at du kan se to filer samtidig enda lettere trykk C-x 52. Husk C-x C-f for ? ?pne en fil i det nye vinduet.
    • Innrykk: Du kan la Emacs sette riktig innrykk i hele programmet ved ? trykke C-x h og deretter velge i menyene ?verst: Java > Indent Line or Region.
    • Flere tips til Emacs kan du finne 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