L?sningsforslag ukeoppg. 3:  13. - 17. sep (INF1000 - H?st 2010)

Forgreninger (kap. 4.1 - 4.2), l?kker (kap. 4.3 - 4.4), arrayer (kap. 5.1 - 5.5 og 5.7), og litt om tekster og filer.
NB! Legg merke til at disse er l?sningsforslag.  L?sningene dine trenger ikke ? v?re like med disse forslag for ? v?re riktige.  Det er vanlig i programmering at samme oppgave kan l?ses p? mange vidt forskjellige m?ter, og alle fremgangsm?ter er ok i INF1000 s? lenge de leder fram til riktig resultat og oppfyller kravene som st?r oppgaveteksten.

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

Oppgaver til teoritimen

  1. Enkel kalkulator med if-else og switch:
    (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.  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.  P.S. Det vil bli lagt ut l?sningsforslag b?de med og uten bruk av easyIO.

    (b) Hvordan kan programmet endres for ? bruke en switch-setning i stedet for if-else?  (Hint: Se eksemplet p? side 78 i l?reboka, og husk ? ta med break;-setningene.)
    L?sningsforslag uten EasyIO:
    // (a)
    import java.util.Scanner;
    class Kalkulator {
        public static void main(String[] args) {
            Scanner tast = new Scanner(System.in);
    
    	System.out.print("Regnestykke: ");
    	int a = tast.nextInt();
    	char op = tast.next().charAt(0);
    	int b = tast.nextInt();
    
    	int svar = 0;
    	if (op == '+') {
    	    svar = a + b;
    
    	} else if (op == '-') {
    	    svar = a - b;
    
    	} else if (op == '*') {
    	    svar = a * b;
    
    	} else if (op == '/') {
    	    svar = a / b;
    	}
    
    	System.out.println("Resultat: " + svar);
        }
    }
    
    // (b)
    import java.util.Scanner;
    class Kalkulator {
        public static void main(String[] args) {
            Scanner tast = new Scanner(System.in);
    
    	System.out.print("Regnestykke: ");
    	int a = tast.nextInt();
    	char op = tast.next().charAt(0);
    	int b = tast.nextInt();
    
    	int svar = 0;
    	switch (op) {
    	  case '+':
     	           svar = a + b;
    	           break;
    	  case '-':
    	           svar = a - b;
    		   break;
    	  case '*':
    	           svar = a * b;
    		   break;
    	  case '/':
    	           svar = a / b;
    		   break;
    	}
    	System.out.println("Resultat: " + svar);
        }
    }
    
    L?sningsforslag med EasyIO:
    // (a)
    import easyIO.*;
    
    class Kalkulator {
        public static void main(String[] args) {
            Out skjerm = new Out();
            In tast = new In();
    
    	skjerm.out("Regnestykke: ");
    	int a = tast.inInt();
    	char op = tast.inChar(" ");
    	int b = tast.inInt();
    
    	int svar = 0;
    	if (op == '+') {
    	    svar = a + b;
    
    	} else if (op == '-') {
    	    svar = a - b;
    
    	} else if (op == '*') {
    	    svar = a * b;
    
    	} else if (op == '/') {
    	    svar = a / b;
    	}
    
    	skjerm.outln("Resultat: " + svar);
        }
    }
    
    // (b)
    import easyIO.*;
    
    class Kalkulator {
        public static void main(String[] args) {
            Out skjerm = new Out();
            In tast = new In();
    
    	skjerm.out("Regnestykke: ");
    	int a = tast.inInt();
    	char op = tast.inChar(" ");
    	int b = tast.inInt();
    
    	int svar = 0;
    	switch (op) {
    	  case '+':
     	           svar = a + b;
    	           break;
    	  case '-':
    	           svar = a - b;
    		   break;
    	  case '*':
    	           svar = a * b;
    		   break;
    	  case '/':
    	           svar = a / b;
    		   break;
    	}
    	skjerm.outln("Resultat: " + svar);
        }
    }
    


    (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?
    Programmet over gir heltallsdivisjon. For ? f? vanlig flyttallsdivisjon kan vi deklarere svar som double, og endre siste regnestykke til f.eks. ett av disse:
    	svar = (double) a / b;
    	svar = 1.0 * a / b;
    


  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);
    
    a = 22
    
    //(b)
           int sum = 0;
           for (int b = 1; b < 6; b += 2) {
               sum += b;
           }
           System.out.println("sum = " + sum);
    
    sum = 9
    //(c)
           int produkt = 1;
           for (int c = 1; c < 4; c++) {
               produkt = produkt * c;
    	   System.out.println(produkt);
           }
    
    
    1
    2
    6
     
    //(d)
           for (int d = 3; d >= 1; d--) {
               for (int e = 1; e <= 3; e++) {
                   System.out.println(d + e);
               }
           }
    
    4
    5
    6
    3
    4
    5
    2
    3
    4
    //(e)
           int teller = 0;
           for (int ytre = 0; ytre < 3; ytre++) {
               teller++;
               for (int indre = 0; indre < 3; indre++) {   
                   teller++;
               }
           }
           System.out.println(teller);
    
    12


  3. Array med tall:
    (a) Lag et program som ber bruker taste inn tre heltall og lagrer disse i en array kalt tall:
    int[] tall = new int[3];
    
    (b) Sum av array: Utvid programmet slik at det regner ut summen av tallene ved hjelp av en l?kke, og skriver ut resultatet.
    (c) Minste verdi: Utvid programmet slik at det finner og skriver ut det minste tallet i arrayen.
    (d) Lave verdier: Legg til programkode som skriver ut alle verdiene i arrayen som er mindre enn 10.
    (e) S?k: Legg til programkode som skriver ut en beskjed om verdien 5 finnes eller ikke finnes i arrayen.
    import easyIO.*;
    class Ukeoppg3_3 {
        public static void main(String[] args) {
            In tast = new In();
            Out skjerm = new Out();
    
            int[] tall = new int[3];
    
            // (a) Lese 3 tall fra tastatur:
            for (int i = 0; i < 3; i++) {
                // Ledetekst:
                skjerm.out("Angi tall[" + i + "]: ");
    
                // Les et tall fra tastatur og lagre det i arrayen tall[]:
                tall[i] = tast.inInt();
            }
    
            // (b) Sum av array:
            int sum = 0;
            for (int i = 0; i < 3; i++) {
                sum += tall[i];
            }
            skjerm.outln("(b) Sum av tallene = " + sum);
    
            // (c) Minste verdi:
            int minste = tall[0];
            for (int i = 0; i < 3; i++) {
                if (tall[i] < minste) {
                    minste = tall[i];
                }
            }
            skjerm.outln("(c) Minste verdi = " + minste);
    
            // (d) Lave verdier:
            skjerm.out("(d) Lave verdier (< 10): ");
            for (int i = 0; i < 3; i++) {
                if (tall[i] < 10) {
                    skjerm.out(tall[i] + " ");
                }
            }
            skjerm.outln();
    
            // (e) S?k:
            boolean funnet = false;
            for (int i = 0; i < 3; i++) {
                if (tall[i] == 5) {
                    funnet = true;
                }
            }
            skjerm.out("(e) Verdien 5 finnes ");
            if (! funnet) {
                skjerm.out("ikke ");
            }
            skjerm.outln("i arrayen");
        }
    }
    
    KJ?REEKSEMPEL:
    > java Ukeoppg3_3
    Angi tall[0]: 2
    Angi tall[1]: 7
    Angi tall[2]: 11
    (b) Sum av tallene = 20
    (c) Minste verdi = 2
    (d) Lave verdier (< 10): 2 7 
    (e) Verdien 5 finnes ikke i arrayen


  4. Array med String-er:
    Hva blir skrevet ut i f?lgende program?, og hvorfor?
    class NavneArray {
       public static void main(String[] args) {
    
           String[] navn = { "Anne", "Kari", "Ole", null };
    
    //(a)
           System.out.println(navn[1] + navn[navn.length/2]);
    
    KariOle
    //(b)
           for (int i = 0; i < navn.length; i++) {
               // Testen "!= null" sikrer at neste ledd ikke blir null.equals(..)
               if (navn[i] != null
                   && (navn[i].equals("Ole") || navn[i].equals("Anne")) ) {
                   System.out.println(i);
               }
           }
    
    
    0
    2
     
    //(c)
           int indeks = 0;
           boolean funnet = false;
           while (indeks < 4 && !funnet) {
               if (navn[indeks].equals("Kari")) {
                   funnet = true;
               }
               indeks++;
           }
           System.out.println(indeks);
    
    2
    //(d)
           String[] andreNavn = { "Per", "Anne", "Ole" };
           for (int i = 0; i < 4; i++) {
               for (int j = 0; j < 3; j++) {
                   // Testen "!= null" for ? stoppe og unng? null.equals(..)
                   if (navn[i] != null && navn[i].equals(andreNavn[j])) {
                       System.out.println(i + " " + j);
                   }
               }
           }
       }
    }
    
     
    0 1
    2 2


  5. Innlesing og utskrift til fil:  (eksempel side 50 i l?reboka)
    (a) Ta utgangspunkt i f?lgende program, fra side 50 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: Utskrift til fil vha. easyIO programmeres p? samme m?te som utskrift til skjerm, bare at man i tillegg angir filnavnet ? f.eks. new Out("minfil.txt"), ? og lukker filen til slutt (utfil.close()).  Navnet p? forbindelsen skjerm b?r ogs? endres for ? gj?re det tydelig at man skriver til en utfil.
    import easyIO.*;
    
    class Utskrift {
        public static void main(String[] args) {
    	Out utfil = new Out("minfil.txt");
    	utfil.outln('A');
    	utfil.outln("Canis familiaris betyr hund");
    	utfil.outln(15);
    	utfil.outln(3.1415, 2); // Bruk to desimaler
    	utfil.close();
        }
    }
    
    KJ?REEKSEMPEL:
    > more minfil.txt
    A
    Canis familiaris betyr hund
    15
    3.14
    

    (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, men man m? i tillegg angi filnanvet ? f.eks. new In("minfil.txt").
    import easyIO.*;
    
    class Utskrift {
        public static void main(String[] args) {
    	Out skjerm = new Out();
    
    	Out utfil = new Out("minfil.txt");
    	utfil.outln('A');
    	utfil.outln("Canis familiaris betyr hund");
    	utfil.outln(15);
    	utfil.outln(3.1415, 2); // Bruk to desimaler
    	utfil.close();
    	skjerm.outln(" Fil 'minfil.txt' opprettet med 4 verdier.");
    
    	In innfil = new In("minfil.txt");
    	char tegn = innfil.inChar();
    	String linje = innfil.inLine();
    	int heltall = innfil.inInt();
    	double flyttall = innfil.inDouble();
    	innfil.close();
    
    	skjerm.outln(" Leste f?lgende verdier fra filen 'minfil.txt':");
    	skjerm.outln(tegn);
    	skjerm.outln(linje);
    	skjerm.outln(heltall);
    	skjerm.outln(flyttall);
        }
    }
    
    KJ?REEKSEMPEL:
    > java Utskrift
     Fil 'minfil.txt' opprettet med 4 verdier.
     Leste f?lgende verdier fra filen 'minfil.txt':
    A
    Canis familiaris betyr hund
    15
    3.14
    


  6. Flerdimensjonal array:
    To-dimensjonale arrayer brukes p? samme m?te som en-dimensjonale, men har to sett med klammer, og gjennomg?s best vha. to nestede for-l?kker:
    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
    1X
    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) Fullf?r println-setningen slik at programmet gir utskriften vist under Kj?reeksempel.
    (b) Hvor mange elementer er det plass til i arrayen b vist over?
    (c) Hva er indeksene til elementet markert med "x" i figuren, og hvilken verdi f?r elementet utdelt i programmet?
    (a) System.out.println("b[" + i + "][" + j + "] = "  + b[i][j]);
    (b) 12 elementer (dvs. 3 x 4)
    (c) b[1][2] == 2
    

Oppgaver til terminaltimen

  1. Enkel kalkulator med if-else og switch:
    (a) - (c) (Samme oppgaver som i nr. 1 for teoritimen.)

    (d) Test programmet p? datamaskin og se hvilke feilmeldinger du f?r n?r du pr?ver ? dele et tall p? 0, b?de med og uten l?sningen din p? deloppgave (c) ovenfor.


  2. Utskrift av oddetalls-array: kap. 5, oppg. 1 (side 97)
    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.
    class Oddetall {
        public static void main(String[] args) {
    	int[] oddetall = { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 };
    
    	for (int i = 0; i < oddetall.length; i++) {
    	    System.out.println("oddetall[" + i + "] = " + oddetall[i]);
    	}
        }
    }
    


  3. Sum av elementene i en array: kap. 5, oppg. 2 (side 97)
    Vi bruker her samme array som i forrige oppgave: Beregn summen av elementene og skriv ut resultatet.
    	int sum = 0;
    	for (int i = 0; i < oddetall.length; i++) {
    	    sum = sum + oddetall[i];
    	}
    	System.out.println("sum = " + sum);
    


  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.
    import easyIO.*;
    
    class Uke3_Terminaloppg3 {
        public static void main(String[] args) {
            In tast = new In();
            int[] oddetall = { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 };
    
            // (a) Finnes tallet?
            System.out.print("Tast inn et tall: ");
            int tall = tast.inInt();
    
            boolean funnet = false;
            for (int i = 0; i < oddetall.length; i++) {
                if (oddetall[i] == tall) {
                    funnet = true;
                }
            }
            System.out.print("Tallet " + tall);
            if (funnet) {
                System.out.println(" finnes i arrayen");
            } else {
                System.out.println(" finnes ikke i arrayen");
            }
    
            // (b) Skriv ut verdiene < tall:
            System.out.print("Verdier i arrayen som er < " + tall + ": ");
            for (int i = 0; i < oddetall.length; i++) {
                if (oddetall[i] < tall) {
                    System.out.print(oddetall[i] + " ");
                }
            }
            System.out.println();
        }
    }
    
    KJ?REEKSEMPEL:
    Tast inn et tall: 5
    Tallet 5 finnes i arrayen
    Verdier i arrayen som er < 5: 1 3 
    


  5. Array med String-er:
    (Samme oppgave som nr. 4 for teoritimen.)


  6. Innlesing og utskrift til fil:  (eksempel side 50 i l?reboka)
    (Samme oppgave som nr. 5 for teoritimen.)


  7. Begynn med Oblig 2.


  8. Ukens n?tt: (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 her!


  9. 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 vha. 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

Tibakemelding om dette oppgavesettet kan du skrive i bloggen eller sende p? mail til josek [a] ifi.uio.no