Write a Java program that recursively reads ten names from a file, and then outputs the total number of characters in the names, the list of names, and the list of names in reverse order. All looping must be performed recursively.

Jay Walker
Erol Flintstone
C. Erol Madre
Billy Pilgrim
Mickey Angels
José Francisco de San Martín
Squarebob Sponge Pants
Mischa Ternoff
Chester Peak
Al Italia
Ben Dover
Pat Pending

I am 100% lost. I would like advice on where would be the first place to start. Thinking about the program, I wanted to build a main that would call a scanner that would read the file first. When reading the file, it would count the characters in the text (quick question, would a scanner count the spaces between the characters?).

Next I was thinking of just a simple print function that would display the entire names.txt file.

Finally, the part that I'm 110% lost...how the heck would I go about listing the names in reverse order? What would I use? How does recursion fit in all this? O.o I'm totally blown at that part.

Since you want to read from a file , your inital step would be to read about java IO. Check out various classes Reader, Writer, BufferedReader etc. That will give you a pretty clear idea about how to start. For ex. BufferedReader has a method readLine() that reads an entire line i.e. lines separated by newline character at a time. Accordingly you can decide what to use. Simple read a file first and display its contents on the console. Once you are done with this , you can move ahead

If you have no idea about reading from file, try DJSAN10 suggestion and use normal iteration (while loop) just to understand how it works. Then you change from the normal iteration to recursive (because your requirement asks you to deal with recursion only).

If you already understand how to use Scanner, it is even easier and you can ignore all Reader/Writer because Scanner nextLine() is enough to do a recursion. What you need to do is to pass in a Scanner object. If you do not want the method to return anything but modify data, pass in another object which will store the reading in data from file to a recurive method (such as ArrayList of String). If you want the method to return data as a long string, then just have return statement with the data read inside the method. Don't forget to concatenate the line read from the file before you return.

While in the method, after read the line (nextLine()), if there is still data (hasNext()), call the method again inside the method -- recursive call. If nothing else, finish it up (either return or do nothing because you have already modify the passed in data variable).

Once you get the data, check for statistic value (you could combine this check inside the read-in recursive call). Then the display method will be another recursive method which print it backward. It should be easier now once you get and idea and correctly implement the first part (read in).

Let me know how you implement the first part because it is important for you to understand recursive.

Edited 4 Years Ago by Taywin

Comments
nicely put..!!

UPDATE!! My code works! But...

My professor said this, "Most of what you have in main() should be in a run() method, and much of the initialization should be in a constructor."

Is what he said just a matter of cutting and moving code or do I have to start over again? Don't really understand what he said. O.o

The reason I ask that is cause I don't understand how constructors vs. methods work. I was taught constructor material in like a day, so I don't have a healthy grasp of it.

Thanks!

import java.util.*;
import java.io.*;

public class hw3
    {
    public static final int MAXLINES = 10;

    public static void main(String[] args) throws FileNotFoundException 
        {
        Scanner scan = new Scanner(new File("names.txt"));
        String[] names = new String[MAXLINES];

        readNames(names, scan, 0);
        forward(names,0);
        System.out.println();
        reverse(names,0);
        System.out.println(totalChars(names, 0,0));
        }

    static String[] readNames(String[] names, Scanner scan, int curLine) 
        {
        if(curLine >= MAXLINES)
            return names;
        names[curLine] = scan.nextLine();
            return readNames(names, scan, curLine+1);
        }

    static void forward(String[] names, int cur) 
        {
        if(cur >= names.length)
            return;
        System.out.println(names[cur]);
        forward(names, cur+1);
        }

    static void reverse(String[] names, int cur) 
        {
        if(cur >= names.length)
            return;
        reverse(names, cur+1);
        System.out.println(names[cur]);     
        }

    static int totalChars(String[] names, int cur, int sum) 
        {
        if(cur >= names.length)
            return sum;
            return totalChars(names, cur+1, sum+names[cur].length());
        }
    }

The only reason for putting everything in run() method, to me, is to use Thread class (the run() method belongs to a Thread). I don't see the requirement from your posted problem, so I am not sure why he said most of it should be in the run() method? If your instructor wants a run() method inside the class without inheriting from the Thread class, to me it is not supposed to because it doesn't sound convensional. I would name it something similar to runProgram() or something...

The constructor is for creating the class instance. An example of construtor is below.

class hw3 {
  // declare the class variables
  public static final int MAXLINES = 10;
  Scanner scan;
  String[] names;

  // This is the (default/explicit) constructor.
  // It does not require an arugment, so every variables are
  // intialised with default value.
  public hw3() {
    scan = new Scanner(new File("names.txt"));
    ...  // other initilisations
  }
  // This is another type of constructor that requires an argument,
  // so some variables may be intialised depending on the incoming arguments.
  public hw3(String filename) {
    scan = new Scanner(new File(filename));
    ...  // other initilisations
  }

  ...  // all of your current class's method implementation go here

  public runProgram() {
    readNames();  // See the difference?
                  // You don't need to pass arguments because they are
                  // all in your class instance already.
    ... // now move all of your method calls in here
  }

  public static void main(String[] args) {
    hw3 myInstance = new hw3();  // initilise the class instance
    // now you could simply call this...
    myInstance.runProgram();
    // done in main
  }
}

Edited 4 Years Ago by Taywin

This article has been dead for over six months. Start a new discussion instead.