Föreläsning 5-7 Innehåll Algoritm för summering Aritmetiska uttryck Logiska uttryck Algoritm för att beräkna max och min Repetition inför delmålskontroll 1 Teckenuttryck Slumptal Undervisningsmoment: föreläsning 5-7 övning 3 laboration 5-6 Avsnitt i läroboken: 3.9, 6 (ej 6.5), 7 (utom 7.8-9 som behandlas senare) EDAA20 (F5-7 programmering) HT 2016 1 / 48 Summering Mönster Algoritmexempel public class ComputeSomething { public static void main(string[] args) { int n = scan.nextint(); int sum = 0; for (int k = 0; k < = n; k++) { int term = (int) Math.pow(2, k); sum = sum + term; System.out.println(sum); Vad beräknas när man matar in värdet 3? EDAA20 (F5-7 programmering) HT 2016 2 / 48 Summering Exempel: alternerande harmoniska serien Uppgift: Beräkna summan av ett antal termer. Lösning: Deklarera och nollställ en variabel som håller reda på det aktuella värdet av summan. Gå sedan igenom termerna en efter en och addera varje term till summan. Algoritmen i pseudokod: sum = 0; för alla termer { term = "nästa term" sum = sum + term; Beräkna följande summa: 1P 1 k = 1 1 2 + 1 1 3 4 + 1 5... k=1 Tag bara med de termer som är större än epsilon. Värdet på epsilon läses in. EDAA20 (F5-7 programmering) HT 2016 3 / 48 EDAA20 (F5-7 programmering) HT 2016 4 / 48
Summering Exempel: alternerande harmoniska serien lösning public class AlternatingHarmonicSeries { public static void main(string[] args) { System.out.println("Den alternerande harmoniska summan."); System.out.println("Tag bara med termer större än: "); double eps = scan.nextdouble(); EDAA20 (F5-7 programmering) HT 2016 5 / 48 Heltalsdivision och rest Uttryck Uttryck talar om hur värden ska beräknas. Exempel: aritmetiska uttryck 2 * (x + y) - 10 logiska uttryck a > 0 && a < 10 true teckenuttryck a Objektuttryck new Square(20, 10, 40) null this EDAA20 (F5-7 programmering) HT 2016 6 / 48 Heltalsdivision och rest Exempel på användning a / b ger ett heltal som resultat om både a och b är heltal. Exempel: 17 / 3 är lika med 5 (heltalsdivision) 17 % 3 är lika med 2 (rest vid heltalsdivision) 3personerskarättvistdelapå17kakor.Allafår5kakorvaroch2 kakor blir över. Avgör om x är udda eller jämnt: if (x % 2 == 0) { System.out.println("jämnt" ); else { System.out.println("udda"); Avgör om x är jämnt delbart med 10: if (x % 10 == 0) { System.out.println("x är jämnt delbar med 10"); EDAA20 (F5-7 programmering) HT 2016 7 / 48 EDAA20 (F5-7 programmering) HT 2016 8 / 48
Heltalsdivision och rest Övning Skriv ut antal timmar och minuter mellan start- och sluttid. System.out.println("Skriv starttid och sluttid " + "(timmar och minuter):"); int starthour = scan.nextint(); int startmin = scan.nextint(); int stophour = scan.nextint(); int stopmin = scan.nextint(); int nbrhours = stophour - starthour; if (nbrhours < 0) { // om tidsintervallet passerar midnatt nbrhours = nbrhours + 24; int minutes = 60 * (stophour - starthour) + (stopmin - startmin); Logiska uttryck Logiska uttryck kan ha två möjliga värden, true eller false. Variabler av typen boolean kan tilldelas logiska uttryck boolean ok = true; ok = false; ok = x < 5; Logiska uttryck används bland annat som villkor i if- och while-satser: if (x < 5) {... while (true) {... EDAA20 (F5-7 programmering) HT 2016 9 / 48 EDAA20 (F5-7 programmering) HT 2016 10 / 48 Relationer Logiska operatorer Ett logiskt uttryck kan vara en relation där man jämför värdet av två uttryck: x < 5 Relationsoperatorer: < <= == lika med >= >!= skilt från Logiska uttryck kan kopplas samman med operatorerna:! icke && och eller Exempel: xtillhörintervallet[5,10] x >= 5 && x <= 10 xtillhörinte intervallet [5, 10] x < 5 x > 10 Ett och-uttryck är true om alla deluttryck har värdet true. Ett eller-uttryck är true om minst ett av deluttrycken har värdet true. EDAA20 (F5-7 programmering) HT 2016 11 / 48 EDAA20 (F5-7 programmering) HT 2016 12 / 48
Algoritmexempel Konstanter för minsta och största tal public class ComputeSomething { public static void main(string[] args) { System.out.println("Skriv 7 tal:"); int result = Integer.MAX_VALUE; for (int i = 0; i < 7; i++) { int nbr = scan.nextint(); if (nbr < result) { result = nbr; System.out.println(result); Konstanter för minsta respektive största värde: int i1 = Integer.MIN_VALUE; // -2147483648 int i2 = Integer.MAX_VALUE; // 2147483647 double d1 = Double.MIN_VALUE; // 4.9E-324 (OBS! minsta möjliga positiva heltal) double d2 = Double.MAX_VALUE; // 1.8E308 double d3 = -Double.MAX_VALUE // -1.8E308 Med E menas gånger 10 upphöjt till Indata: 23 19 18 19 21 17 20 Vilket värde skrivs ut? EDAA20 (F5-7 programmering) HT 2016 13 / 48 EDAA20 (F5-7 programmering) HT 2016 14 / 48 Beräkna minimum Mönster Beräkna maximum Mönster Uppgift: Beräkna det minsta talet i en följd av tal. Lösning: Deklarera en variabel min som ska hålla reda på det hittills minsta värdet. Låt min få ett stort startvärde. Gå sedan igenom talen och jämför med min. Uppdatera min ifall det aktuella talet är mindre. Algoritmen i pseudokod: min = "stort värde"; för alla värden { value = "nästa värde"; if (value < min) { min = value; Uppgift: Beräkna det största talet i en följd av tal. Lösning: Deklarera en variabel max som ska hålla reda på det hittills största värdet. Låt max få ett litet startvärde. Gå sedan igenom talen och jämför med max. Uppdatera max ifall det aktuella talet är större. Algoritmen i pseudokod: max = "litet värde"; för alla värden { value = "nästa värde"; if (value > max) { max = value; EDAA20 (F5-7 programmering) HT 2016 15 / 48 EDAA20 (F5-7 programmering) HT 2016 16 / 48
Beräkna maximum Övning Delmål 1 Exempel på vad du ska kunna Beräkna och skriv ut det största talet av ett antal heltal som läses in från tangentbordet. Fyll i den kod som saknas. int max = Integer.MIN_VALUE; while (scan.hasnextint()) { int nbr = scan.nextint(); Förklara följande begrepp: algoritm, program, kompilering, exekvering, variabel, tilldelningssats. Formulera algoritmer med if-, for- och while-satser (beräkna minimum, maximum, summor...) Skriva enkla program som skapar och använder objekt. Förklara följande begrepp: objekt, klass, specifikation, implementering, attribut, metod, parameter, konstruktor, private, public. Implementera enkla klasser. Rita figur över minnessituationen med variabler och objekt med attribut (dvs. visa att du förstår vilka objekt som finns i ett program och hur de hänger ihop). EDAA20 (F5-7 programmering) HT 2016 17 / 48 EDAA20 (F5-7 programmering) HT 2016 18 / 48 Delmål 1 Repetition Tecken Exempel: På föreläsning 6 blir det repetition inför delmålskontroll 1. Det vi ska repetera är framförallt: viktiga begrepp som klass, attribut, konstruktor... hur man skapar och använder objekt implementering av klasser Material till denna repetitionsföreläsning delas ut separat. char c1 = A ; char c2 = 7 char space = ; Observera att det ska vara apostrofer omkring en teckenkonstant. Tecknen är internt numrerade 0, 1, 2,... enligt Unicode-tabellen: Siffrorna 0 till 9 kommer i följd (nr 48-57). Bokstäverna A till Z kommer i följd (nr 65-90). Bokstäverna a till z kommer i följd (nr 97-122) Å, Ä, Ö och å, ä, ö är besvärliga att hantera. De kommer inte direkt efter de andra bokstäverna och dessutom i fel ordning. EDAA20 (F5-7 programmering) HT 2016 19 / 48 EDAA20 (F5-7 programmering) HT 2016 20 / 48
Några speciella tecken Några tecken måste skrivas på speciellt sätt: \n radframmatningstecken \t tabulatortecken \" citattecken Exempel: System.out.println("Ett\nord\npå\nvarje\nrad"); System.out.println("En\tsnygg\ttabell"); System.out.println("10\t20\t30"); Förskjutningschiffer I förskjutningschiffer (ceasarchiffer) byter man ut varje bokstav mot bokstaven ett bestämt antal steg framåt i alfabetet. Exempel: om antal steg (chiffernyckeln) är 3 byts A ut mot D osv: ABCDEFGHIJKLMNOPQRSTUVWXYZ DEFGHIJKLMNOPQRSTUVWXYZABC Exempel: JAVA -> MDYD När man dekrypterar texten gör man samma sak i motsatt riktning. Exempel: MDYD -> JAVA EDAA20 (F5-7 programmering) HT 2016 21 / 48 EDAA20 (F5-7 programmering) HT 2016 22 / 48 Rot13 Kryptera ett tecken I chiffret Rot13 används chiffernyckeln 13. Rot13 är sin egen invers, dvs. man kan kan använda samma algoritm för att kryptera och dekryptera. ABCDEFGHIJKLMNOPQRSTUVWXYZ NOPQRSTUVWXYZABCDEFGHIJKLM Exempel: JAVA -> WNIN -> JAVA Vi ska skriva ett program som läser en text och krypterar alla tecken i intervallet [A-Za-z] med chiffret Rot13. Börja med det enklare delproblemet att kryptera ett tecken i intervallet [A-Za-z]: ABCDEFGHIJKLMNOPQRSTUVWXYZ NOPQRSTUVWXYZABCDEFGHIJKLM Detta kan man lösa genom följande algoritm: om tecknet är i intervallet [A-Ma-m] ersätt tecknet med bokstaven 13 steg framåt i alfabetet annars om tecknet är i intervallet [N-Zn-z] ersätt tecknet med bokstaven 13 steg bakåt i alfabetet EDAA20 (F5-7 programmering) HT 2016 23 / 48 EDAA20 (F5-7 programmering) HT 2016 24 / 48
Konvertering mellan tecken och heltal Metod för att kryptera ett tecken Ett tecken i ett heltalsuttryck konverteras automatiskt till motsvarande heltal. char c = D ; int nr = c + 13; // 68 + 13 I andra riktningen måste man konvertera explicit. c = (char) nr; c nr c nr 'D' 81 'Q' 81 public class Encrypter { /** Krypterar ett tecken i intervallet [A-Za-z] genom att använda krypteringsalgoritmen Rot13. */ public static char encryptrot13(char c) { if (c >= a && c <= m c >= A && c <= M ) { c = (char)(c + 13); else if (c >= n && c <= z c >= N && c <= Z ) { c = (char)(c - 13); return c; EDAA20 (F5-7 programmering) HT 2016 25 / 48 EDAA20 (F5-7 programmering) HT 2016 26 / 48 Läsa och kryptera ett tecken Klassen String En teckensträng består av 0 till flera tecken. Exempel: Skriv ett program som läser ett tecken och chiffrerar det. public class Rot13 public static void main(string[] args) { String s = scan.next(); char c = s.charat(0); scan.close(); c = Encrypter.encryptRot13(c); System.out.print(c); "Detta är en teckensträng" "A" "" I Java används klassen String för att beskriva teckensträngar. /** Skapar en tom sträng. */ String(); /** Returnerar antal tecken i strängen. */ int length(); /** Returnerar tecknet på plats pos. */ char charat(int pos);... EDAA20 (F5-7 programmering) HT 2016 27 / 48 EDAA20 (F5-7 programmering) HT 2016 28 / 48
Inläsning av tecken Läsa och kryptera en teckensträng I klassen Scanner finns en metod next för att läsa in en teckensträng: String name = scan.next(); Det finns ingen speciell metod för att läsa in ett värde av typen char. Istället kan man t.ex. läsa en teckensträng metoden next och sedan plocka ut första tecknet. String name = scan.next(); char initial = name.charat(0); Skriv ett program som läser en teckensträng och chiffrerar den. Algoritm: läs en teckensträng för varje tecken i teckensträngen kryptera tecknet skriv ut EDAA20 (F5-7 programmering) HT 2016 29 / 48 EDAA20 (F5-7 programmering) HT 2016 30 / 48 Läsa och kryptera en teckensträng, forts Läsa och kryptera en text Skriv ett program som läser en teckensträng och chiffrerar den. public class Rot13 public static void main(string[] args) { String s = scan.next(); scan.close(); for (int i = 0; i < s.length(); i++) { char c = s.charat(i); c = Encrypter.encryptRot13(c); System.out.print(c); Skriv ett program som läser en text och chiffrerar den. Algoritm: Så länge det finns en rad att läsa läs en rad för varje tecken på raden kryptera tecknet skriv ut EDAA20 (F5-7 programmering) HT 2016 31 / 48 EDAA20 (F5-7 programmering) HT 2016 32 / 48
Programexempel: Rot13 Läsa och kryptera en text, forts Skriv ett program som läser en text och chiffrerar den. public class Rot13 public static void main(string[] args) { System.out.println("Skriv texten som ska krypteras:"); while (scan.hasnextline()) { String s = scan.nextline(); for (int i = 0; i < s.length(); i++) { char c = s.charat(i); c = Encrypter.encryptRot13(c); System.out.print(c); System.out.println(); scan.close(); EDAA20 (F5-7 programmering) HT 2016 33 / 48 Slumptalsgenerator Klassen Random Slumptal får man med hjälp av standardklassen java.util.random. /** En slumptalsgenerator med slumptalsfröet seed. */ Random(long seed); /** En slumptalsgenerator med ett slumpmässigt slumptalsfrö. */ Random(); /** Slumpmässigt heltal i intervallet [0,n). */ int nextint(int n); /** Slumpmässigt reellt tal i intervallet [0,1.0). */ double nextdouble(); EDAA20 (F5-7 programmering) HT 2016 34 / 48 Övning Dra slumptal inom ett heltalsintervall Slumptal Exempel: krona eller klave Lägg till programkoder för att dra ett slumptal i intervallet [0,5] och ett slumptal i intervallet [1,6]. Random rand = new Random(); Random rand = new Random(); if (rand.nextdouble() < 0.5) { System.out.println("krona"); else { System.out.println("klave"); Alternativ: if (Math.random() < 0.5) { System.out.println("krona"); else { System.out.println("klave"); EDAA20 (F5-7 programmering) HT 2016 35 / 48 EDAA20 (F5-7 programmering) HT 2016 36 / 48
Övning Tippa 1, x eller 2 Programexempel: tärningsspel Skriv ett program som låter en användare spela detta tärningsspel: Sannolikhet för 1 ska vara 55% - - x - - 15% - - 2 - - 30% Random rand = new Random(); double nbr= rand.nextdouble(); char res; if (nbr < 0.55) { res = 1 ; Spelaren gör första tärningsslaget och får samma poäng som tärningen visar. Sedan fortsätter spelet enligt följande regler: Om tärningen visar något annat än en etta adderas antal prickar tärningen visar till spelaren poäng. Om spelaren slår en etta sätts poängsumman till 0 och spelet avbryts. Spelaren kan inför varje tärningsslag välja att avbryta spelet och nöja sig med den poäng som uppnåtts. EDAA20 (F5-7 programmering) HT 2016 37 / 48 EDAA20 (F5-7 programmering) HT 2016 38 / 48 Klassen Die Specifikation Vi behöver en klass som beskriver en tärning. Den ska ha metoder för att kasta tärningen och för att läsa av antal prickar: /** Skapar en tärning. */ public Die(); /** Kastar tärningen. */ public void roll(); /** Tar reda på resultatet av det senaste kastet. */ public int getresult(); EDAA20 (F5-7 programmering) HT 2016 39 / 48 Tärning Klassen Die public class Die { private static Random rand = new Random(); private int pips; // antal prickar som visas /** Skapar en tärning. */ public Die() { roll(); // så att pips får ett värde 1..6 /** Kastar tärningen. */ public void roll() { pips = 1 + rand.nextint(6); /** Tar reda på resultatet av det senaste kastet. */ public int getresult() { return pips; EDAA20 (F5-7 programmering) HT 2016 40 / 48
Klassen Die kommentarer Anropa metod på objektet självt Slumptalsgeneratorn rand är ett statiskt attribut. Det betyder att rand hör till själva klassen Die och inte till något enskilt tärningsobjekt. Alla tärningsobjekt man skapar delar på samma slumptalsgenerator. Man får då en bättre fördelning av slumptalen jämfört med om varje tärning har sin egen slumptalsföljd. Ett anrop av nextint(6) ger ett heltal mellan 0 och 5. För att få ett slumptal mellan 1 och 6 får vi göra så här: pips = rand.nextint(6) + 1; För att tärningen ska få ett vettigt startvärde anropas metoden roll inuti konstruktorn. För att tärningen ska få ett vettigt startvärde anropas metoden roll inuti konstruktorn: /** Skapar en tärning. */ public Die() { roll(); Normalt anger man med punktnotation vilket objekt en metod ska utföras på. Det behövs inte i det här fallet. Metoden roll är deklarerad i den här klassen och utförs på det aktuella objektet. Man kan också anropa metoden så här: this.roll(); EDAA20 (F5-7 programmering) HT 2016 41 / 48 EDAA20 (F5-7 programmering) HT 2016 42 / 48 Programexempel: tärningsspel Kasta tärning tills etta Programexempel: tärningsspel Kasta tills tärningen visar en etta Vi börjar med att lösa det enklare delproblemet att kasta en tärning tills den visar en etta. Därefter utökar vi programmet stegvis. Algoritm: kasta tärningen int sum = antal prickar så länge summan ej är lika med 0 kasta tärningen om tärningen visar en etta sum = 0 annars sum = sum + antal prickar Die d = new Die(); d.roll(); int sum = d.getresult(); System.out.println("Poäng: " + sum); while (sum!= 0) { d.roll(); if (d.getresult() == 1) { sum = 0; else { sum = sum + d.getresult(); System.out.println("Poäng: " + sum); EDAA20 (F5-7 programmering) HT 2016 43 / 48 EDAA20 (F5-7 programmering) HT 2016 44 / 48
Programexempel: tärningsspel Låt spelaren välja när det är dags att avbryta Lägg till programkod som låter användaren av programmet avgöra när det är dags att sluta slå tärningen. Algoritm: kasta tärningen int sum = antal prickar fråga om användaren vill fortsätta så länge sum är skild från 0 och användaren vill fortsätta kasta tärningen om tärningen visar en etta sum = 0 annars sum = sum + antal prickar fråga om användaren vill fortsätta EDAA20 (F5-7 programmering) HT 2016 45 / 48 Programexempel: tärningsspel Låt spelaren välja när det är dags att avbryta Die d = new Die(); d.roll(); int sum = d.getresult(); System.out.println("Poäng: " + sum); System.out.println("Vill du fortsätta (ja/nej)"); String answer = scan.next(); while (sum!= 0 && answer.equals("ja")) { d.roll(); if (d.getresult() == 1) { sum = 0; else { sum = sum + d.getresult(); System.out.println("Poäng: " + sum); System.out.println("Vill du fortsätta (ja/nej)?"); answer = scan.next(); System.out.println("Du fick " + sum + " poäng."); EDAA20 (F5-7 programmering) HT 2016 46 / 48 Programexempel: tärningspel Utöka programmet - antal tärningsslag, max antal poäng Checklista Hur mycket poäng kan det vara rimligt att förvänta sig (maximalt och igenomsnitt)?låtprogrammetsimuleraettstortantalspelomgångar och skriv ut den största poängumman som uppnåddes samt den genomsnittliga poängsumman. Utgå från programmet som kastar tärningen tills det blir en etta. Ändra stegvis koden på följande sätt: Låt programmet skriva ut antal poäng som uppnåtts innan kastet med den avslutande ettan. Tag bort alla övriga utskrifter. Låt programmet upprepa antal spelomgångar ett stort antal gånger. Istället för att skriva ut en poängsumma per spelomgång ska nu programmet ändras så att det skriver ut den största poängsumman som uppnåddes. Lägg till kod för att beräkna och skriva ut den genomsnittliga poängsumman. Exempel på vad du ska kunna formulera aritmetiska uttryck med operatorerna +, -, *, / och % formulera logiska uttryck i Java använda if- for- och while-satser formulera algoritmer och programkod för att beräkna summor formulera algoritmer och programkod för att beräkna minsta och största värde använda klassen Random för att generera slumptal Skriva lite större program än tidigare. EDAA20 (F5-7 programmering) HT 2016 47 / 48 EDAA20 (F5-7 programmering) HT 2016 48 / 48