Categories : Java

 

Recursion and Command line parameters are two of those things that you will run into eventually, and which will be a source of many headaches if you don’t pay attention to what you’re doing. Recursion is a concept that is similar across programming languages, but making a program accept command line parameters varies from language to language, and is probably going to trip you up more. So I’ll start there first…

Commandline Parameters in Java

Recall that, unlike C, Java mercifully has no pointers. Therefore, the biggest source of problems in learning command line parameters is eliminated. The other nice thing about Java is that, whether or not you use them, your program accepts command line paramters. You don’t have to explicitly declare them, as in C. Well, okay, your program does need to have an entry point (main method) to accept CLPs. You should know the decleration well by now, but I’ll state it again for effect:

public static void main(String[] args)

I’ve strengthened the important part for effect. Well, I guess you caught me in a lie again… you do need to declare them explicitly, but this decleration is part of every main method that you write in Java. So anyway, now that you know that you’re taking in these parameters, let me show you what they mean…

When you say String[] args in the decleration of the main method, it is a lot like saying String[] args in the body of a method. You are declaring args to be an array of type String. Thus, in Java, anything that you enter in the CL after the program name will be considered a string, and put in an array, starting with index 0.

Example: I have a strange desire to write a simple version of an echo program in Java. I want to be able to invoke the program on the command line with whatever it is I want to echo back to the user. So when I type “echo hi”, I should get “hi” as a response. To do this I’m going to need to refference args[0], which is where “hi” is stored.

***C USERS TAKE NOTE***

In C, when you refference something from argv[] (which is kind of like C’s version of args, for all you non-C people), argv[0] is the program’s name. So in the above example, I would have gotten “echo” returned to me instead of “hi”.

Of course, this can be a problem if you don’t want a string, but Java provides methods of turning strings into other things. You’ll see when we get to the example. Okay, that should be enough background of how to use CLPs in Java for you to understand the following example… why don’t we move on to recursion…

Using Recursion in Java

Recursion in java is a lot like recursion in any other programming language I’ve encountered. Recursion is actually a very simple idea: a method calls itself. Naturally you’re not going to want every method to call itself, but there are times when doing this simplifies your code emmensly. Consider the ever (in)famous recursive definition of factorial…

return n = n * factorial(n - 1)

Simple, effecient, one-liner. No need for messy while loops, or annoying if-else switches. You get the number you want without a problem. Cool, eh? Alrght, let’s get onto the program…

1   public class EvenOdd
2   {
3     public static int odd(int n)
4     {
5       /*
6        * First, make a method called odd().
7        */

8      if (n == 0) //our "base", or "test" case.
9      {
10      System.out.println("ODD");
11      return 0;
12     }

13     else
14     {
15       /*
16        * If our test case fails, call the even()
17        * method after decrimenting n
18        */

19       n--;
20       return even(n);
21     }
22    }

23    public static int even(int n)
24    {
25      /*
26       * Now I need an even() method.
27       */

28     if (n == 0) //test case.
29     {
30	System.out.println("EVEN");
31	return 0;
32     }

33     else 
34     {
35       /*
36        * If the test case fails, pass n to odd
37        * after decrimenting.
38        */
39       n--;
40	 return odd(n);
41     }
42    }

43    public static void main(String[] args)
44    {
45	int n = Integer.parseInt(args[0]);
46      /* 
47       * Here we declare n to be an int, and use
48       * parseInt to change the first CL argument
49       * from a string to an integer, giving
50       * n the number we enter in the command line.
51       */
52	EvenOdd eo = new EvenOdd();
53      /*
54       * eo is an object of the EvenOdd class.
55       * In Java, you can't just use the methods,
56       * you have to use them as members of a class.
57       */
58      eo.even(n);
59      /*
60       * Run our program, using n as the number to check,
61       * and calling even() first, because of the way I
62       * wrote the program, I need to do this.  If I
63       * called eo.odd(n), the results would be wrong.
64       */
65     }
66    }
Okay, there’s a lot going on here, as you can see, so why don’t I start with a top-down approach. Make sure you take a good look at the code before you read this part though, or it’s not going to make much sense. I’ve tried to put some good comments in this program, so I can discuss some of the more abstract things about it rather than do a line by line analysis.

public static int odd(int n)
This is a simple little method decleration, but it does beg the question of why I tell it to return an int. The short answer is that you need to return something. If the test case is true, than all the method has to do is print, but if it’s false, than I need to return an integer value (even(n)). If I don’t tell it to return an int, than I wouldn’t be able to do that, and our poor end user would never be able to tell if 9 is even or odd.

if (n == 0)
This is the “base” or “test” case for recursion. For a recursive method to work properly, it is absolutely essential that there is a situation in which the recursion calls come to an end. If you don’t include a test case, than the recursion would continue forever, and you would have an infinite loop on your hands, and I know how much you hate infinite loops. The test case for this program is where n becomes equal to zero; which is due to the algortihm that I’ve used. Essentially the program keeps asking itself if the number is equal to zero, and if not, to subtract one and ask again. Simple, eh?

return even(n);
The first instance of a return statement (line 11) also bears some investigating. As I’ve said before, we need to return a value, and in recursion, we have the program call itself. In this case, there are two methods that call each other interchangeably, so I tell the method to return another method (as a return value) while passing n to that method. This will bubble up the call chain with the return odd(n); call on line 40 until n reaches 0, the program prints its message, and exits.

int n = Integer.parseInt(args[0]);
This is saying a mouthful, so lets take a piece by piece look at what’s going on here. The obvious part of this decleration is the assignment of int n, if you don’t know what that means, you’re in the wrong tutorial. I’ll take the next part backwards. If you were paying attention above, you’ll note that main takes a parameter, an array of strings. args[0] means that whatever is the first thing entered after the name of the program, take that and do something to it. So far so good, but the “do something to it” part is where things start to get a little hairy.

The hairy part of this scheme is the “Integer.parseInt()”, which will convert the non-integer string into its integer value. If you’ve got a copy of Java in a Nutshell you can investigate this a little more indepth on your own. It’s one of the pre-defined methods part of the Java language, so you don’t have to install anything special, and while there are other ways of converting strings, this is probably the most brief as far as actual code is concerned. If you don’t do this, than you’ll be trying to perform math operations on a string, which obviously won’t work.

EvenOdd eo = new EvenOdd()
Okay, Java is object oriented, and it enforces its object oriented nature on the programmer, so any time you want to call a method outside of main, you have to instantiate a new instance of the class and then call that method as a member of that class.

eo.even(n);
This is where we call even as a member of eo, which is an instance of class EvenOdd. Giving it n as a parameter passes the number entered on the CL into the program, and we’ll get some results when we run it.

 Posted on : August 22, 2014

You might also likeclose