## A recursive example of `dashes`¶

### Review iterative `dashes`¶

You may recall a method we wrote called `dashes` which took a `String` parameter and returned a new `String` that was equivalent to the given parameter with dashes inserted between every character. For example, a call to `dashes("pupper")` would return the `String`

``````"p-u-p-p-e-r"
``````
Previously we implemented an iterative solution that looked something like this:

``````public static String dashes(String s) {
if (s.isEmpty()) {
return s;
} else {
String result = "" + s.charAt(0);
for (int i = 1; i < s.length(); i++) {
result += "-" + s.charAt(i);
}
return result;
}
}
``````
While that works just fine, let’s go ahead and explore writing a recursive solution to the same method.

### Reviewing the components of recursive methods¶

Before we dive into the details of solving `dashes` recursively, we should first remind ourselves the components of a recursive solution. We can recall that a recursive method deals with only one small part of a problem before passing on the rest of the problem to other method calls. We also can recall that recursive solutions are made up of a combination of base cases and recursive cases. It may help to review this brief outline of things needed to wrtie recursive methods:

Outline for writing recursive methods:

• Figure out the base case(s). These tend to be the simplest, most basic cases of the problem we can solve immediately. It may help to think of them as the “bottom” or “end” of the recursive call chain (hence the name “base case”)
• Figure out what is the smallest “part” or “section” of the problem we should break off in the recursive case
• Deal with the recursive case(s). This usually involves solving the small part of the problem that we broke off in the previous step and combining it with the result of a recursive call to the same method on the smaller sub-problem

### Implementing `dashes` recursively¶

Now that we’ve reviewed the components of recursive methods, let’s keep them in mind as we implement `dashes` recursively. To start, we will write the method stub

``````// Returns a String which is the result of adding dashes
// in between the characters of the given String
public static String dashes(String s) {
//TODO: implement this method
}
``````

We can begin by figuring out what our base case should be. What’s the simplest problem we can solve immediately? The case where we are passed the empty `String`, in which we want to return an empty `String` (we can’t insert dashes in-between an empty `String`). Let’s add our base case

``````// Returns a String which is the result of adding dashes
// in between the characters of the given String
public static String dashes(String s) {
if (s.isEmpty()) {
return "";
} else {
//TODO: implement the recursive case
}
}
``````

What do we want to do if our `String` is not empty? This is where we begin to write the recursive case. Remember, our recursive case should just do the smallest amount of work to solve part of the problem before passing off the rest of the work to other recursive calls (we don’t want to do too much in each method call!). We need to somehow add dashes to our `String`, so a small part of the problem we could do is break off one character, add one dash, and then combine that with a dashed version of the rest of the `String`. Wouldn’t getting a dashed version of the rest of the `String` be easy if we had a method to add dashes to a `String`? Thankfully, we are writing one so we can call it recursively to perform this last task! Below is a good example of a recursive case

``````// Returns a String which is the result of adding dashes
// in between the characters of the given String
public static String dashes(String s) {
if (s.isEmpty()) {
return "";
} else {
return s.charAt(0) + "-" + dashes(s.substring(1));
}
}
``````
`s.charAt(0)` breaks off the first character and then the `+ "-"` adds a dash. Then we need to figure out how to add dashes in between the characters of the rest of the given `String` (`s.substring(1)`). If we struggle to figure out exactly how to use our recursive method, it can sometimes help to look at the method comment in order to find the sub-problem to call it with. Our method comment states

``````Returns a String which is the result of adding dashes
in between the characters of the given String
``````
Note that this is exactly the functionality we want to perform on `s.substring(1)`!!! Rather than iteratively implementing all of that functionality in our recursive case, we can use the recursive call `dashes(s.substring(1))` to achieve the desired result.

### A reminder of the importance of testing code¶

Now that we have an attempt at a solution, we should test it on some sample inputs to make sure it is working as expected. In reality, we want to test on a wide variety of cases, such as

• The empty `String`
• A one character `String`
• An even-length `String`
• An odd-length `String`
• Any other cases specific/special to our problem’s functionality

For now, let’s just test our solution to `dashes` on the empty `String`, a `String` with one character `"P"`, and a slightly longer example `"pup"`.

For the empty `String` our solution would enter the base case and correctly return the empty `String`.

``````dashes("");
is empty, so return ""
``````
Nice!

For our one character `String`, we would want to return exactly that character (you can’t have dashes between one character). Let’s trace through what would happen

``````dashes("P")
is not empty, so execute recursive case
compute dashes("")
|    is empty, so return ""
return firstChar + "-" + rest ('P' + "-" + "" = "P-")
``````
By tracing through our code, we can see that for an input `String` with one character our output has an extra dash added at the end. We can see why, as a `String` with one character isn’t the empty `String`, so we enter our recursive case and add a dash followed by a call to `dashes("")`. How can we restructure our code to account for this case? It seems we need a new case for a one-character `String` such as the following

``````public static String dashes(String s) {
if (s.isEmpty()) {
return "";
} else if (s.length() == 1) {
return s;
} else {
return s.charAt(0) + "-" + dashes(s.substring(1));
}
}
``````
Now we can go back and trace through our previous inputs.

``````dashes("");
is empty, so return ""
``````
The empty `String` still works!

``````dashes("P")
is not empty but length is 1 so return same String ("P")
``````
And now our method works for a one-character `String`. Let’s go ahead and try our last test case.

``````dashes("pup")
not empty and length > 1 so execute last case
compute dashes("up")
|    not empty and length > 1 so execute last case
|    compute dashes("p")
|    |    not empty but length == 1 so return same String
|    return firstChar + "-" + rest ('u' + "-" + "p" = "u-p")
return firstChar + "-" + rest ('p' + "-" + "u-p" = "p-u-p")
``````
Looks like it’s working for this case too!

### Redundant cases¶

If we look at the first two cases, however, we can’t quite start celebrating our working solution. If we are given the empty `String`, we end up returning the empty `String`, and if we are given a one-character `String`, we return that same one-character `String`. In both cases, we end up returning the same `String` we were passed. When writing methods, it is poor code quality to write code with redundant/duplicate cases such as the method written above. Rather than having the cases be separate, let’s go ahead and combine the two cases in order to produce a stylistically-better version of our solution

``````public static String dashes(String s) {
if (s.length() <= 1) {
return s;
} else {
return s.charAt(0) + "-" + dashes(s.substring(1));
}
}
``````

### Recap¶

As a recap, some important takeaways for writing recursive solutions are:

• Figuring out the base case, which is often the simplest case of our problem that we can solve immediately.
• Find the small part of the problem we will break off and solve in the recursive case. Solve this small problem and then use a recursive call to solve the rest of the problem.
• Test recursive solutions just like we would test any other code!!! Testing is super important in programming, as we can often catch small errors that we overlook when writing methods. Often writing an incorrect solution is part of the problem solving process, and there is no harm in writing a wrong solution the first time around as long as we test and fix it!

# Practice

Try out this problem and this other problem for more practice with recursion.