3.4 Lösungen
3.4 Lösungen3.4.1 Schleifenterminierung
int i = 1, j = 1; do { i = i + j; j++; } while (i < 200);
int i = 1, j = 20; while (i + j < i) { i = i + 2; j--; }
int i = 1, j = 20; while (i + j > i) { i = i + 2; j--; }
int i = 100, j = 27; while (i != j) { i = i / 2; j = j / 3; }
3.4.2 Ziffern einer Zahl
public class Main { public static void main(String[] args) { int firstArg = 0; int stellen = 0; int a; if (args.length > 0) { try { firstArg = Integer.parseInt(args[0]); } catch (NumberFormatException e) { System.err.println("Argument muss Ganzzahl sein"); System.exit(1); } System.out.println("Die Zahl firstArg = " + firstArg + " wurde eingelesen"); a = firstArg; while (a !=0) { stellen++; a/=10; } } System.out.println(" Die Zahl " + firstArg + " hat " + stellen + " Stellen!"); } }
3.4.3 Quersumme
package s1.block3; public class Quersumme { public static void main(String[] args) { int firstArg = 0; int querSumme = 0; int a; if (args.length > 0) { try { firstArg = Integer.parseInt(args[0]); } catch (NumberFormatException e) { System.err.println("Argument muss Ganzzahl sein"); System.exit(1); } System.out.println("Die Zahl " + firstArg + " wurde eingelesen"); a = firstArg; while (a !=0) { querSumme+= a%10; a/=10; } System.out.println("Die Zahl " + firstArg + " hat die Quersumme " + querSumme + "!"); } } }
3.4.4 Zahlenstatistik
package s1.block3; public class Zahlenstatistik { public static void main(String[] args) { int feld[]; int min = Integer.MAX_VALUE; int max = Integer.MIN_VALUE; float average = 0; if (args.length > 0) { feld = new int[args.length]; try { for (int i=0;i<args.length;i++) { feld[i] = Integer.parseInt(args[i]); if (feld[i] < min) {min=feld[i];} if (feld[i] > max) {max=feld[i];} average += feld[i]; } } catch (NumberFormatException e) { System.err.println("Argument muss Ganzzahl sein"); System.exit(1); } average= average/(float)args.length; System.out.println("Anzahl eingelesene Werte: " + args.length); System.out.println("Kleinster Wert: " + min); System.out.println("Größter Wert: " + max); System.out.println("Durchschnitt: " + average); } } }
3.4.5 Primzahlzerlegung
package s1.block3; public class Primzahlzerlegung { public static void main(String[] args) { int firstArg = 0; int p=1; long time; time= System.nanoTime(); if (args.length > 0) { try { p = Integer.parseInt(args[0]); } catch (NumberFormatException e) { System.err.println("Argument muss Ganzzahl sein"); System.exit(1); } System.out.println("Eingelesene Zahl: " + p); while (p>1) { for (int i=2; i<= p; i++) { while (p%i == 0) { System.out.println("Primfaktor: " + i); p /= i; } } } } time= System.nanoTime() - time; System.out.println("Zeit in m: "+ time); } }
Optimiert:
// Gute Kandidaten // 2^30-1 = 1073741823 // 2^31-1 = 2147483647 public class Main { public static void Primzahlzerlegung(String[] args) { int firstArg = 0; long p = 1; long time; time = System.nanoTime(); if (args.length > 0) { try { p = Integer.parseInt(args[0]); } catch (NumberFormatException e) { System.err.println("Argument muss Ganzzahl sein"); System.exit(1); } long i = 2; System.out.println("Eingelesene Zahl: " + p); while ((p > 1) && (i <= p)) { if (p % i == 0) { System.out.println("Primfaktor: " + i); p /= i; i = 2; } else { if (i > Math.sqrt(p)) { // Beende Suche wenn Wurzel von P erreicht i = p; } else { i++; } } } } time = System.nanoTime() - time; System.out.println("Zeit in m: " + time); } }
3.4.6 Codevereinfachung
a.)
// Annahme: j >= 0 i = j;
a = (a<b) ? b : a; b = (a<b) ? a : b; c = (a<b) ? a : c;
3.4.7 Wochentagberechnung
Hier wurde nur der julianische Kalender implementiert nicht der (aktuelle) gregorianische Kalender.
Hier wurden Felder verwendet, die noch nicht vorgestellt wurden.
package s1.block3; public class WochentagBerechnung { public static void main(String[] args) { int monatOffSet[] = new int[13]; int tag = 0; int monat = 0; int jahr=0; int wochentag0101startJahr= 6; int jahresOffSet; // Bedeutung siehe Feld tagText String[] tagText = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"}; int wochentag; int startJahr = 2010; int anzSchaltJahre; if (args.length > 1 ) { try { tag = Integer.parseInt(args[0]); monat = Integer.parseInt(args[1]); jahr = Integer.parseInt(args[2]); wochentag0101startJahr = Integer.parseInt(args[3]); } catch (NumberFormatException e) { System.err.println("Argument muss Ganzzahl sein"); System.exit(1); } monatOffSet[1] = 0; monatOffSet[2] = (monatOffSet[1]+31)%7; monatOffSet[3] = (monatOffSet[2]+28)%7; monatOffSet[4] = (monatOffSet[3]+31)%7; monatOffSet[5] = (monatOffSet[4]+30)%7; monatOffSet[6] = (monatOffSet[5]+31)%7; monatOffSet[7] = (monatOffSet[6]+30)%7; monatOffSet[8] = (monatOffSet[7]+31)%7; monatOffSet[9] = (monatOffSet[8]+31)%7; monatOffSet[10] = (monatOffSet[9]+30)%7; monatOffSet[11] = (monatOffSet[10]+31)%7; monatOffSet[12] = (monatOffSet[11]+30)%7; jahresOffSet = (monatOffSet[12]+31)%7; if (monat>2) anzSchaltJahre=jahr/4-startJahr/4; else anzSchaltJahre=(jahr-1)/4-startJahr/4; wochentag = (monatOffSet[monat] + tag - 1 + wochentag0101startJahr + (jahr-startJahr)*jahresOffSet + anzSchaltJahre )%7; System.out.println ("Der 1.1."+ startJahr+" war ein " + tagText[wochentag0101startJahr]); System.out.println ("Der "+ tag + "."+monat+"."+jahr+ " ist ein " + tagText[wochentag]); // Optional: Datumsbestimmung mit Hilfe der Java Infrastruktur Calendar myCal = new GregorianCalendar(jahr,monat+1,tag); System.out.println ("Gregorianischer Java Kalender:"); System.out.println ("Der " + tag + "." + monat + "." + jahr+ " ist ein " + tagText[myCal.get(Calendar.DAY_OF_WEEK)]); } } }
3.4.8 Überlauf
Bei der Addition von Ganzzahlen gibt es keine Überlaufsprüfung.
package s1.block3; public class Ueberlauf { public static void main(String[] args) { int a = 0; int b = 0; int result; if (args.length > 1 ) { try { a = Integer.parseInt(args[0]); b = Integer.parseInt(args[1]); } catch (NumberFormatException e) { System.err.println("Argument muss Ganzzahl sein"); System.exit(1); } } System.out.println("Eingelesene Werte: " + a + ", " + b); result = a + b; if ((result < a) || (result < b)) System.out.println("Überlauf!"); else System.out.println(a + " + " + b + " = " + result); } }
3.4.9 Schnitt zweier Linien
Eingabereihenfolge der Parameter ist: a1, a2, b ,c , d1, d2
package s1.block3; public class GeradenSchnitt { public static void main(String[] args) { double a1 = 0.0; double a2 = 0.0; double b = 0.0; double c = 0.0; double d1 = 0.0; double d2 = 0.0; double tmp; if (args.length > 5) { try { a1 = Double.parseDouble(args[0]); a2 = Double.parseDouble(args[1]); b = Double.parseDouble(args[2]); c = Double.parseDouble(args[3]); d1 = Double.parseDouble(args[4]); d2 = Double.parseDouble(args[5]); } catch (NumberFormatException e) { System.err.println("Argument muss Fließkommazahl sein"); System.exit(1); } } System.out.println("Linie 1: (" + a1 + "," + b + ") bis (" + a2 + "," + b + ")"); System.out.println("Linie 2: (" + c + "," + d1 + ") bis (" + c + "," + d2 + ")"); // Schnittpunkt ist (c,b) // Sortieren von a1, a2 . if (a1 > a2) { tmp = a1; a1 = a2; a2 = tmp;} // Sortieren von d1, d2 . if (d1 > d2) { tmp = d1; d1 = d2; d2 = tmp; } System.out.println("Nach sortieren..."); System.out.println("Linie 1: (" + a1 + "," + b + ") bis (" + a2 + "," + b + ")"); System.out.println("Linie 2: (" + c + "," + d1 + ") bis (" + c + "," + d2 + ")"); if ((a1 <= c) && (c <= a2) && (d1 <= b) && (b <= a2)) System.out.println("Die beiden Strecken schneiden sich"); else System.out.println("Die beiden Strecken schneiden sich nicht"); } }
Beispielläufe
java s1.block3.GeradenSchnitt 3.1 8.2 4.0 5.2 11.1 4.9 Linie 1: (3.1,4.0) bis (8.2,4.0) Linie 2: (5.2,11.1) bis (5.2,4.9) Nach sortieren... Linie 1: (3.1,4.0) bis (8.2,4.0) Linie 2: (5.2,4.9) bis (5.2,11.1) Die beiden Strecken schneiden sich nicht java block3.GeradenSchnitt 3.1 8.2 6.0 5.2 11.1 4.9 Linie 1: (3.1,6.0) bis (8.2,6.0) Linie 2: (5.2,11.1) bis (5.2,4.9) Nach sortieren... Linie 1: (3.1,6.0) bis (8.2,6.0) Linie 2: (5.2,4.9) bis (5.2,11.1) Die beiden Strecken schneiden sich
3.4.10 Codevereinfachung
a)
a = a * b + 2 * c;
b)
x<0 | x>=0 | |
---|---|---|
y<0 | a=x*y | a=x*(-y) |
y>=0 | a = x*(-y) | a=(-x)*(-y) |
y = ((x<0) && (y<0)) ? y : -y; x = ((y>=0) && (x>=0))? -x : x; a = x * y;;
3.4.11 Dreiecksbestimmung
package s1.block3; public class Dreiecksvergleich { public static void main(String[] args) { float x[] = new float[3]; int j; if (args.length > 2 ) { try { float a; for (int i=0; i <3; i++) { x[i] = Float.parseFloat(args[i]); j=i; // Sortiere Eingabe in steigender Reihenfolge while (j>0) if (x[j] < x[j-1]) { a = x[j-1]; x[j-1] = x[j]; x[j]= a; j--; } else j=0; } } catch (NumberFormatException e) { System.err.println("Argument muss Fließkommazahl sein"); System.exit(1); } System.out.println("Eingebene Werte: " + x[0] + "; " + x[1] + "; " + x[2]); // Die folgenden Vergleiche verlassen sich darauf, dass das Feld // aufsteigend sortiert ist. if (x[0]+x[1]<=x[2]) System.out.println("Dreieck ist ungültig"); else if (x[0] == x[2]) System.out.println("Dreieck ist gleichseitig (und gleichschenkelig)"); else { if ((x[0] == x[1]) || (x[1] == x[2])) System.out.println("Dreieck ist gleichschenkelig (nicht gleichseitig)"); if (x[0]*x[0]+x[1]*x[1]==x[2]*x[2]) System.out.println("Dreieck ist rechtwinklig"); } } } }
3.4.12 Sortieren
package s1.block3; public class Sortieren { public static void main(String[] args) { int a = 0; int b = 0; int c = 0; if (args.length > 2 ) { try { a = Integer.parseInt(args[0]); b = Integer.parseInt(args[1]); c = Integer.parseInt(args[2]); } catch (NumberFormatException e) { System.err.println("Argument muss Ganzzahl sein"); System.exit(1); } } System.out.println("Eingelesene Werte: " + a + ", " + b + ", " + c); // alle Moeglichkeiten testen if ((a <= b) && (b<=c)) System.out.println("Sortierte Werte: " + a + ", " + b + ", " + c); else if ( (a <= c) && (c <= b) ) System.out.println("Sortierte Werte: " + a + ", " + c + ", " + b); else if ( (b <= a) && (a <= c) ) System.out.println("Sortierte Werte: " + b + ", " + a + ", " + c); else if ( (b <= c) && (c <= a) ) System.out.println("Sortierte Werte: " + b + ", " + c + ", " + a); else if ( (c <= a) && (a <= b) ) System.out.println("Sortierte Werte: " + c + ", " + a + ", " + b); else if ( (c <= b) && (b <= a) ) System.out.println("Sortierte Werte: " + c + ", " + b + ", " + a); } }
3.4.13 Plausibilitätsprüfung
package s1.block3; public class Plausibilitaetspruefung { public static void main(String[] args) { int monatTage[] = {0, 31, 28, 31, 30, 31, 30,
int tag = 0; int monat = 0; int jahr = 0; if (args.length > 2 ) { try { tag = Integer.parseInt(args[0]); monat = Integer.parseInt(args[1]); jahr = Integer.parseInt(args[2]); } catch (NumberFormatException e) { System.err.println("Argument muss Ganzzahl sein"); System.exit(1); } System.out.println("Eingabe ist: " + tag + "." + monat + "." + jahr); if ((monat>0) && (monat < 13) && (tag>0)) if (monatTage[monat] >= tag) System.out.println("Datum ist gültig"); else if ((monat == 2) && (tag == 29) && (jahr%4 == 0) && ((jahr%100 !=0) || (jahr%400==0)) ) System.out.println("Datum ist gültig (Schalttag)"); else System.out.println("Datum ist ungültig"); } } }
3.4.14 Textverschlüsselung
Die vorgestellte Lösung ist eine naive, aber in diesem Fall korrekte Lösung da hier der implementierte Wert eines Zeichen im Vordergrund steht und nicht die Bedeutung des Zeichens.
Sie basiert auf der naiven Annahme, dass die den Zeichen (Buchstaben) zugeordnete Zahlenwerte der Sortierreihenfolge der Buchstaben entspricht. Diese Annahme ist für lateinische Zeichensätze meißten, mehr oder weniger richtig. Im Allgemeinen sollte man bei Programmentwicklung an die Internationalisierung denken. Hier gilt:
- Die lexikografische Ordnung (Sortierreihenfolge) ist länderabhängig und hängt von der Landeseinstellung (locale, Codepage) der eingestellten Umgebung ab.
- Beispiel: Die Buchstaben ß, ö, Ö, ü etc haben in Unicode oder ISO 8852 Werte die nicht der deutschen lexikographischen Ordnung entsprechen.
- Die von Java verwendete Unicodecodierung erlaubt die Codierung der meisten Zeichen der Welt gleichzeitig. Die Sortierreihenfolge ist hier nicht garantiert.
- Beispiel: Es gibt Zeichen die in der japanischen sowie in der chinesichen Sprache verwendet werden. Diese Zeichen sind identisch, haben jedoch eine unterschiedliche Bedeutung. Sie werden daher in China und Japan unterschieldlich sortiert.
package s1.block3; public class Textverschluesselung { public static void main(String[] args) { String myText = ""; int offSet = 0; char c; if (args.length > 1 ) { offSet = Integer.parseInt(args[0]); myText = args[1]; } System.out.println("Eingabe: <<" + myText + ">>, Verschiebung: " + offSet); System.out.print("Ausgabe: <<"); offSet = offSet%26; // Bei 26 Buchstaben kann der Versatz nur module 26 sein for (int i=0;i < myText.length(); i++) { // Lese jeden Wert der Zeichenkette aus und erhöhe den Zähler im Feld c = myText.charAt(i); if ((c>='A') && (c<='Z')) { c = (char)(c + offSet); if (c > 'Z') c-=(char)26; //Ziehe vom Ergebnis 26 ab da es jenseits von "Z" liegt. System.out.print(c); } } System.out.println(">>"); } }
3.4.15 Verzweigung
package s1.block3; public class Verzweigung { public static void main(String[] args) { int x[] = new int[3]; if (args.length > 2 ) { try { for (int i=0; i<3; i++) x[i]= Integer.parseInt(args[i]); } catch (NumberFormatException e) { System.err.println("Argument muss Ganzzahl sein"); System.exit(1); } } System.out.println("Eingabe: " + x[0] +", " + x[1] + ", "+ x[2]); if ((x[0]==x[1]) && (x[1]==x[2])) System.out.println("Alle Werte sind gleich."); if ((x[0]==x[1]) || (x[1]==x[2]) || (x[0]==x[2])) System.out.println("Mindestens zwei Werte sind gleich."); if ((x[0]!=x[1]) && (x[1]!=x[2]) && (x[0]!=x[2])) System.out.println("Alle Werte sind verschieden."); } }
3.4.16 Häufigkeit von Zeichen
package s1.block3; public class Haeufigkeitzeichen { public static void main(String[] args) { String myText=""; char c; int histogram[] = new int[Character.MAX_VALUE]; if (args.length > 0 ) { myText=args[0]; } System.out.println("Eingabe: <<" + myText + ">>"); for (int i=0;i < myText.length(); i++) { // Lese jeden Wert der Zeichenkette aus und erhöhe den Zähler im Feld c = myText.charAt(i); histogram[c]++; } for (int i=0; i < Character.MAX_VALUE; i++) if (histogram[i]!= 0) { // Wichtig: unterdrücke alle leeren Einträge. // Das Feld hat ~65000 Zellen! System.out.print((char)i + ": "); for (int j=0; j< histogram[i]; j++) System.out.print('*'); System.out.println(); } } }
3.4.17 Weckzeiten implementieren
package s1.block3; public class WeckzeitLoesung { int wzh = 0; // Weckzeit in Stunden int wzm = 0; // Weckzeit in Minuten int wzs = 0; // Weckzeit in Sekunden public void setzeWeckzeit(int hh, int mm, int ss) { if (korrekteWeckzeit(hh,mm,ss)) { wzh = hh; wzm = mm; wzs = ss; } } public boolean korrekteWeckzeit(int h, int m, int s) { boolean result; // benutzen die Variablen h,m,s um eine gültige Zeit zu bestimmen result = ((h>=0) && (h<=12 && (m>=0) && (m<=59)&& (s>=0) && (s<=59))); return result; } public boolean klingeln(int aktH, int aktM, int aktS) { boolean result; // benutzen die Variablen der aktuellen Zeit aktH (Stunde), // aktM (Minute), aktS (Sekunde) und die Weckzeit wzmh, wzm, wzs // um zu bestimmern ob der Wecker klingeln soll // Bestimme aktuelle Zeit in Sekunden int aktZeit = aktH*3600 + aktM*60+aktS; // Bestimme Weckzeit in Sekunden int weckZeit = wzh *3600 + wzm *60+wzs; // Ist die aktuelle Zeit größer aber nicht größer als 10 Sekunden? result = (aktZeit-weckZeit>=0) && (aktZeit-weckZeit<10); return result; }
}
- 8597 views