Rekursiv würde ja bedeuten er müsste die Methode division() immer wieder aufrufen, aber du rufst sie nur nochmal auf wenn eine Exception auftritt. D.h. geb ich als Nenner die 0, fragt er erneut nach zähler und nenner. Ansonsten kommt er nie wieder in die methode rein.
D.h. nur beim ersten mal fängst du die Exception ab dann aber nicht mehr.
Ja stimmt dann muesste ich division() nochmal in sich selbst aufrufen lassen.
bin ein wenig ratlos wie so eine Funktionalitaet einfuegen soll, ich kann es ja auch nicht nach dem
werfen der Exception einsetzen, da soweit ich verstanden habe der code dort abbricht.
ah ich haette hier vlt besser bsp angeben sollen statt meiner konsolen eingaben, ich ging davon aus das ich zweimal den nenner 0 eingebe.
Er bricht nach der 2.Eingabe ab.*
Er bricht nicht ab, er beendet das Programm weil er ins finally rein kommt.
Du könntest eine while-Schleife verwenden bzw do-while und solange eine 0 als Nenner eingegeben wird (bzw solange ein Fehler auftritt), immer wieder erneut Zähler und Nenner abfragen
Aber die Wiederholung der Division, falls 0, wäre per se erstmal keine Rekursion sondern Induktion. Falls es eine Aufgabe ist und es heißt Implementiere die Division rekursiv, dann sollst du vermutlich auf / verzichten und stattdessen die Division durch rekursive Subtrahierung implementieren.
f(x, y) = 1 + f(x - y, y) ⇔ x >= y; y <> 0
f(x, y) = 0 ⇔ x < y; y <> 0
Aber die Wiederholung der Division, falls 0, wäre per se erstmal keine Rekursion sondern Induktion. Falls es eine Aufgabe ist und es heißt Implementiere die Divion rekursiv, dann würde ich meinen ist gewollt, dass auf / verzichtet wird und stattdessen die Division durch rekursive Subtrahierung implementiert werden soll.
Es ist keine Aufgabe, es soll mir nur selber zum Verstaendniss der Materie helfen, in diesem Fall: Rekursion und Exceptions.
Ich versuch einfach nochmal zu deutlich zu machen was genau ich überhaupt versuche zu machen:
Ich würde gern ein Code entwerfen welcher, nenner & zaehler mittels einer Methode abfragt und solange es eine nicht durchfuehrbare Operation ist(sprich 1/0) eine Exception wirft und den Methode erneut aufruft, solange bis Ausfuehrbar.
Meine Problem ist( ich meine mal das es mein Problem ist), dass ich nicht weis wo ich meine Methode erneut aufrufen soll.
Code:
import java.util.Scanner;
import Êxceptions.eigene_Exception;
public class Exception1 {
public int division(int zaehler, int nenner)
throws eigene_Exception {
Scanner eingabe = new Scanner(System.in);
while (nenner == 0) {
throw new eigene_Exception("division durch 0 nicht durchfuehrbar");
//so würde ich es machen, aber das geht ja nicht da nach throw abbricht
division(eingabe.nextInt(), eingabe.nextInt());
}
return (zaehler/nenner);
}
public static void main(String[] args) {
Exception1 x = new Exception1();
Scanner eingabe = new Scanner(System.in);
try {
System.out.println("gebe ein: zaehler / nenner");
x.division(eingabe.nextInt(), eingabe.nextInt());
} catch(eigene_Exception e) {
System.out.println("Fehlerbehandlung?");
}
}
}
Rein nach dem EVA-Prinzip (Eingabe Verarbeitung Ausgabe) ist die erneute Eingabe während der Verarbeitung keine schöne Sache. Ich halte persönlich sehr viel von dem Prinzip und ich kann dir nur empfehlen dich auch daran zu halten.
Was du aber machen könntest wäre den gesamten EVA-Vorgang in der Exception rekursiv zu gestalten, nur die Division selbst wäre dann nicht mehr rekursiv. Du hättest dann also 2 Funktionen.
okay hab jetzt erstmal die Rekursion probiert und gemerkt das mir da schon grundlegende Probleme habe
- werde noch mal Java Insel WebBuch schauen, da mein vorliegendes buch keine Rekursion behandelt
Code:
import java.util.Scanner;
public class rekursion_division {
public int division(int zaehler, int nenner) {
Scanner eingabe = new Scanner(System.in);
while (nenner == 0) {
System.out.println("eingabe: nenner+zaehler");
zaehler = eingabe.nextInt();
nenner = eingabe.nextInt();
division(zaehler, nenner);
}
return (zaehler/nenner);
}
public static void main(String[] args) {
rekursion_division x = new rekursion_division();
System.out.println(x.division(1, 0));
}
}
okay langsam kommen wir der sache näher :d
die Rekursion funktioniert soweit, allerdings werden die Parameter scheinbar nicht richtig überschrieben.
Wenn ich beim ersten Konsolenaufruf (1,1) eingebe, wird auch 1 ausgegeben, wenn ich vorher (1,0) und dann (1,1) bekomm ich 1/0 ausgegeben.
Code:
package Êxceptions;
import java.util.Scanner;
public class rekursion_division {
public int division(int zaehler, int nenner) {
Scanner eingabe = new Scanner(System.in);
if (nenner == 0){
System.out.println("eingabe: nenner+zaehler");
zaehler = eingabe.nextInt();
nenner = eingabe.nextInt();
division(zaehler, nenner);
}
return (zaehler/nenner);
}
public static void main(String[] args) {
rekursion_division x = new rekursion_division();
int ergebniss= x.division(1,0);
System.out.println(ergebniss);
}
}
Da hast du wieder die Eingabe während der Verarbeitung. Tus nicht!
Du kannst dir doch eine weitere Methode ala macheEineDivision() erstellen, welche die Parameter einliest, dann dividiere(z, n) verarbeitet und das Ergebnis oder den Excpetiontext ausgibt. Also EVA einmal durch. Und im Falle du bist in der Exception kannst du macheEineDivision() erneut aufrufen. Das ist möglich.
Da hast du wieder die Eingabe während der Verarbeitung. Tus nicht!
Du kannst dir doch eine weitere Methode ala macheEineDivision() erstellen, welche die Parameter einliest, dann dividiere(z, n) verarbeitet und das Ergebnis oder den Excpetiontext ausgibt. Also EVA einmal durch. Und im Falle du bist in der Exception kannst du macheEineDivision() erneut aufrufen. Das ist möglich.
Ich kann mir leider nicht erschliessen wie ich dann neue Eingaben tätigen kann wenn sich sich die Methode erneut aufruft.
In macheEineDivision() soll mein Scanner wie ich verstanden habe nämlich auch nicht rein.
2.Meinst du ich soll eingabe nie in meinen eigentlichen methoden nutzen sondern lediglich in meiner main?
Ihr habt natürlich recht mit der while-Schleife, das wäre dann eine Iteration
Normalerweise sieht eine Rekursion folgendermaßen aus
Code:
main(){
rekursiveMethode(a);
}
rekursiveMethode(a){
if (irgendeine bedingung mit a) {
return ...;
} else {
rekursiveMethode(mache was mit a und gib den neuen wert erneut an die methode);
}
Bei solchen kleinen Themen wie der Division mag dir das ganze vielleicht noch nicht so sinnig vorkommen und ist sicherlich auch nicht ganz so wichtig. Es bleibt übersichtlich.
Aber sagen wir du hast einen Adressbuch. In deiner ersten Version hast du alle Adressen in Dateien vorliegen, du sortierst die Adressen mit Bubble Sort und gibst diese auf der Konsole aus. Jetzt bist du weiter und willst die Textdateien loswerden. In deiner zweiten Version nimmst du eine Datenbank. Du musst wahrscheinlich lediglich die Eingabe ändern. Auch gefällt dir die Konsole nicht mehr, du willst es nun auf einer GUI (z.B. Swing) anzeigen, du musst nur die Ausgabe ändern. Dann fällt dir ein der Merge Sort ist eventuell doch besser geeignet als der Bubble Sort. Du änderst nur die Verarbeitung.
Oder denke an Multi-Device. Du willst für jedes Device keine eigene Logik bauen, sondern nur die Ausgabe auf diesem Device. Also ja ich würde die einzelnen Teile so gut wie möglich trennen.
Deine Division könnte theoretisch auch mal eine GUI bekommen. Natürlich ist die Division schnell wieder programmiert egal auf welche Plattform du sie anwendest. Aber es gibt weitaus komplexere Anwendungen, bei denen du froh bist, dass du sie nicht wieder anfassen musst.
Oder sie als Beispiel die Möglichkeit die Division als rekursiven Aufruf zu implementieren. In diesem Fall würdest du nur diese eine Methode ändern, nicht jedoch dein Main.