-4

I will make an array of Book class, I don't believe the contents of Book class matter but I have implemented Comparable although that doesn't really need to be utilized in this exact example. I need to return something that is a String. In past examples we have always done it so that it is void but uses System.out.println. I have a low grasp on recursion as a whole so if someone could help I would greatly appreciate it. Thank you

  • this seems to be quite complex for learning basic recursion. Firstly get familiar with simply outputting some numbers sequences (eg. `1 2 3 ... 10`) using recursion. Then think about this task – Fureeish Nov 08 '17 at 00:51
  • @Fureeish I know how to do that but every example I see doesnt output it in String type but always uses void so I am not sure how write the output – Tommy Harvey Nov 08 '17 at 00:55
  • In this case, I would advise you to think about a recursive method that will **sum up** the first `n` numbers. Hint: if the method signature is `int sum(int n)`, then the part of the code inside that method would be `return n + sum(n - 1);`. Be careful - read again about the ending condition. Learning basic recursion often leads to infinite 'loops' or method calls – Fureeish Nov 08 '17 at 01:00

2 Answers2

0

Recursion is not the right strategy for this problem. It sounds like you're asking for homework help, so I'd recommend involving your TA or other resources at your school that better understand the context of your question. Since you mentioned it: implementing Comparable is not necessary for printing the array. You need Comparable if you intend to sort the array.

That said, here are the components it sounds like you need:

  1. Your Book class needs a string representation. In Java, canonically you encode this in a toString method:

    class Book
    {
       private String title;
    
       // ...other Book methods defined here...
    
       public String toString()
       {
           return this.title; // Or whatever the correct string representation of your Book is.
       }
    }
    
  2. I assume you have an array of Books initialized, say in your main function. Usually, you would print the list iteratively. It's far simpler. See this answer: How to print out individual Strings from Iterable<String>.

    However, your question is specific to recursion. A recursive function always requires two elements:

    1. A base case
    2. A recursive step

    Iterating a list recursively is common in functional programming, for which a common base case is the empty list. Java arrays are not suited to this pattern, though some List implementations like LinkedList are. That said, we can use an array by making the recursive step increment a counter instead. This has literally zero advantage over iterating the list in a for loop, and has the major disadvantage of being prone to stack overflows. But, you asked for recursion...

    public String stringifyBooks(Book[] books, int currentIndex)
    {
         // From https://stackoverflow.com/questions/47169798/how-to-print-an-array-of-objects-using-recursion
         if (currentIndex >= books.length || currentIndex < 0)
         {
             // Base case
             return "";
         }
         else
         {
             // Recursive step
             return books[currentIndex].toString() + ", " +
                 stringifyBooks(books, currentIndex + 1);
         }
    }
    

    Now you can call stringifyBooks with an array of Books and an initial index and you will get all the strings of books starting at that index. What happens if you pass an initial index greater than the length of the array of books, or if books is an empty array?

    When you try it for yourself, you may notice that this solution produces a trailing ", ". To avoid this, you can try (a) adjusting the base case (or adding a second "base case"), or you can (b) adjust the recursive step to identify when the base case was hit with the recursive function call (hint: check for the value returned by the base case and account for it in the recursive step).

    Use of recursion will suffer from Java's stack size limitations. Try it on a very long array of books (say 10,000 of them) and you'll probably run into the limitations. Moreover, the cost of all the string concatenations will be quite large. Incidentally, you would pay that cost if you accumulated your strings inside an iterative algorithm (i.e. one using a for loop) as well. Java provides a built-in StringBuilder for this reason. See if you can modify the above code to take in a StringBuilder and append each book to it inside the recursive step instead of using the + operator to concatenate strings at each recursive step. (Note that this modification will mean stringifyBooks would return void instead of String -- your StringBuilder parameter ends up essentially being your return value.)

    Finally, if you intended to use a List<Book> instead of Book[], you could construct a recursive function where: (1) the base case checks the List's isEmpty function and returns ""; (2) the recursive case creates a string of the first element in the list, removes the first element, calls the recursive function on the list, then returns the string of the first element + the result of the recursive function call. (Or does the same sort of thing but with a StringBuilder.) If you do this, you would remove the currentIndex variable. Bear in mind that this destroys your list of books, so you will need to clone it before calling the recursive function if you need it after using the function.

Matt
  • 161
  • 9
-1

To return a string from a method you just say so in the method header:

public String getName(){
    return this.name;
}

If you want to return a String representation of the Object the convention is to use the .toString() method. String.format() is very helpful for this.

public String toString(){
    return String.format("Name: %s Number of pages: %d", this.name, this.numPages);
}

edit:

To print an array of these objects using recursion:

public static String arrayAsString(Book[] books, int startIndex){
    if(startIndex > books.length - 1) return null;

    String toAppend = arrayAsString(books, startIndex + 1);

    if(toAppend == null) return books[startIndex].toString();
    else return books[startIndex].toString() + " " + toAppend;
}