wir sollen einen String rekursiv (das heißt ohne Schleifen etc) umdrehen, also sprich dass z.B. aus “Hallo” “ollaH” wird.
Ich habe auch schon einen Quellcode, der allerdings aus mir unerfindlichen Gründen nicht funktionieren möchte:
System.out.println("Geben Sie ein Wort ein: ");
String wort = scan.next();
System.out.println(wort);
scan.close();
}
public static String dreheWortUm(String wort){
if (wort.length() > 0){
System.out.println(wort.charAt(wort.length()-1));
dreheWortUm(wort.substring(0, wort.length()-1));
}
return wort;
}
}```
Mein Ansatz ist der, dass ich quasi erstmal überprüfen lasse ob die Länge des Strings über null liegt (in der Aufgabe vorgegeben) und dann die letzte Stelle des Strings ausgegeben wird. Danach ruf ich dreheWortUm erneut auf und er schneidet quasi so lange die Buchstaben ab, bis das Wort umgedreht ist.
Sieht einer was eventuell fehlen könnte oder wo der Fehler ist?
Danke und schöne Weihnachtszeit :)
Hm, ich werde aus dem Code nicht so ganz schlau.
Sollt ihr das Wort lediglich rekursiv ausgeben auf der Konsole, oder soll die Methode den String tatsächlich umdrehen? Momentan ist der Rückgabewert der Methode sinnlos.
Jemand noch eine Idee, wie ich die chars die ja untereinander nun auftauchen in einen String umwandeln kann?
Bei String.valueOf(wort); tut sich leider gar nichts :x
Am einfachsten wäre es die einzelnen Buchstaben in einer Klassenvariablen (static) zu “sammeln” oder der Methode eine Variable durchzureichen und so Schritt für Schritt den Rückwärts String aufzubauen.
Besser wäre es den String Buchstabe für Buchstabe zu durchlaufen und diese passend zurück zu geben und rückwärts zu verketten.
Ausgaben ala System.out.println() sind in der Methode dreheWortUm eher Kontraproduktiv.
Zuerst ein Rekursionsende definieren. Wenn der String keine Buchstaben enthält, dann gib den leeren String zurück.
Ein Rekursionsschritt besteht nun darin, den letzten Buchstaben zu nehmen und ihn zu Verknüpfen mit, dem String der aus allen Buchstaben, bis auf den letzten besteht und umgedreht wurde.
Danke an alle Helfer, habe nun meinen Code komplett umgeschrieben weil es mir einfach zu kompliziert war.
Habe nun einen ähnlichen (aber wesentlich kürzeren) Code, der im Prinzip dasselbe macht (er trennt quasi die Buchstaben vorne ab, um sie hinten wieder zu einem String zusammenzufügen)
Wer an der Lösung interessiert ist, hier ist der fertige Code. Falls euch noch was auffallen sollte, raus damit:
Sym du bist doch nicht etwa in meinem OOP-Kurs? ;D
Nein Spaß - die darauf folgende Aufgabe war tatsächlich, einen jUnit-Test dafür zu schreiben
Und der funktioniert sogar :>
if (s.isEmpty())
return "";
return rev(s.substring(1)) + s.charAt(0);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
System.out.println(rev("Hallo"));
}```
Zeile 2: Abbruchbedingung, das Umgekehrte von nix ist nix
Zeile 4: Reduzierung des Parameters, rekursiver Aufruf, Erweiterung der Rückgabe
Mit einem StringBuilder, dessen Referenz du als Argument mit schleppst (u. a.), wäre alles viel effektiver-
Hm ja mit einer leeren Menge kann man es natürlich auch machen, das stimmt.
Das mit dem StringBuffer musste ich erstmal nachlesen haben wir noch nicht verwendet sorry
Mein jUnit-Test sieht so aus:
import org.junit.Test;
public class Aufgabe5Test {
String wort = "Haus";
String umgedreht;
@Test
public void testDreheWortUm() {
umgedreht = "suaH";
assertEquals(umgedreht,Aufgabe5.dreheWortUm(wort));
}
}```
[ul]
[li] Die beiden Variablen gehören in Deinem Fall in die Methode, da sie nirgends sonst verwendet werden.[/li][li] Was passiert mit dem Leerstring “”? Warum ist das nicht getestet?[/li][li] Was passiert mit null? Warum ist das nicht getestet?[/li][/ul]
Danke nochmal für eure weiter Hilfe, ich habe den Test nun umgeschrieben und er prüft nun auch, ob der String leer ist. Also habe es so realisiert dass ich im Test dem leeren String den Wert “” zugewiesen habe und das dann geprüft wird.
Hier könnt ihr euch den TEst nochmal anschauen :
import org.junit.Test;
public class Aufgabe5Test {
String wort = "Haus";
@Test
public void testDreheWortUm() {
String umgedreht = "suaH";
assertEquals(umgedreht,Aufgabe5.dreheWortUm(wort));
}
{
String leer = "";
assertEquals(leer,Aufgabe5.dreheWortUm(""));
}
}
[QUOTE=Max1992]Danke nochmal für eure weiter Hilfe, ich habe den Test nun umgeschrieben und er prüft nun auch, ob der String leer ist. Also habe es so realisiert dass ich im Test dem leeren String den Wert “” zugewiesen habe und das dann geprüft wird.
Hier könnt ihr euch den TEst nochmal anschauen :
import org.junit.Test;
public class Aufgabe5Test {
String wort = "Haus";
@Test
public void testDreheWortUm() {
String umgedreht = "suaH";
assertEquals(umgedreht,Aufgabe5.dreheWortUm(wort));
}
{
String leer = "";
assertEquals(leer,Aufgabe5.dreheWortUm(""));
}
}
```[/QUOTE]
Da fehlt sowas wie
``` @Test
public void emptyInput()```
Recursion is the goto of functional programming - Erik Meijer
Rekursion ist ein mächtiges Werkzeug, dessen gebrauch weise erfolgen sollte.
Wenn die Rekursionstiefe zu Groß wird, dann gibt es einen Stackoverflow. 3000 sollte oftmals ausreichen.
Im Gegensatz zu Scala macht Java von Haus aus keine Tail Call Optimization um beliebige Stacktiefen erreichen zu können.
Tail Call Optimization funktioniert allerdings nur, wenn die Rückgabe einer Funktion nur aus dem Aufruf selbiger besteht. Folgende rekursive Implementierung könnte Scala optimieren
return dreheWortUm(new StringBuffer(), wort);
}
private static String dreheWortUm(StringBuffer acc, String wort){
//Rekursionsende, gibt den Akkumulator zurück
if (wort.length() <= 0){
return acc.toString();
} else {
acc.append(wort.charAt(wort.length()-1));
String rest = wort.substring(0, wort.length()-1);
return dreheWortUm(acc, rest);
}
}```
Hier würde Scala daraus automatisch eine iterative Implementierung generieren, die vorerst keine Stackprobleme bekommt.
Dies würde dann in etwa so aussehen
```private static String dreheWortUm(StringBuffer acc, String wort){
StringBuffer acc_1 = acc;
String wort_1 = wort;
while(true) {
if (wort_1.length() <= 0){
return acc_1.toString();
} else {
acc_1.append(wort_1.charAt(wort_1.length()-1));
String rest = wort_1.substring(0, wort_1.length()-1);
acc_1 = acc_1;
wort_1 = rest;
}
}
}```