CMPS 144L Lab Activity
Numeral to Number Conversion, Recursively

Here we confine ourselves to considering decimal integer numerals, by which we mean non-empty character strings (i.e., values of type String) containing only digit characters (i.e., char values in the range ['0'..'9']).

Examples of numerals (expressed as String literals, as might appear in a Java program) are "7" and "80236".

The Integer.parseInt() method (recall that java.lang.Integer is the so-called wrapper class for the int primitive data type) has as its purpose to translate such numerals to their corresponding numbers (i.e., values of type int). Thus, for example, the call Integer.parseInt("5302") evaluates to the int value 5302.

As an academic exercise, in this activity you are to develop a method that performs the same translations. In addition, your solution must be recursive, meaning that it must involve a method that calls itself.

A recursive solution to this problem can be based upon the following ideas. Let #() be the (mathematical) function mapping (decimal integer) numerals into their corresponding integer values. For example, #("529") = 529. We can also imagine that # is overloaded so that it can be applied to digit characters, so that, for example, #('3') = 3.

Let x be the numeral x0x1...xn-2xn-1, (where each xi is a digit character).

If n=1 (i.e., the length of x is one), then #(x) = #(x0). That is, translating x into a number reduces to translating its lone digit into a number, which is easy. This is the base case.

If, on the other hand, n>1 (the recursive case):

#(x) = #(x0x1...xn-2xn-1) = 10 × #(x0x1...xn-2) + #(xn-1)

For example,

    #("5286")

=     < recursive case applied to "5286" >

    10×#("528") + #('6')

=     < recursive case applied to "528" >

    10×(10×#("52") + #('8')) + #('6')

=     < recursive case applied to "52" >

    10×(10×(10×#("5") + #('2')) + #('8')) + #('6')

=     < base case applied to "5" >

    10×(10×(10×#('5') + #('2')) + #('8')) + #('6')

=     < # applied to each of '5', '2', '8', and '6' >

    10×(10×(10×5 + 2) + 8) + 6

=     < arithmetic: 10×5 = 50 >

    10×(10×(50 + 2) + 8) + 6

=     < arithmetic: 50 + 2 = 52 >

    10×(10×52 + 8) + 6

=     < arithmetic: 10 × 52 = 520 >

    10×(520 + 8) + 6

=     < arithmetic: 520 + 8 = 528 >

    10×(528) + 6

=     < arithmetic: 10 × 528 = 5280 >

    5280 + 6 

=     < arithmetic: 5280 + 6 = 5286 >

     

Having understood all that, supply the body of either the parseIntRec() method, or the parseIntRecNarrated() method, in the ParseIntRecTester Java application that is provided. Use the application to test your method for correctness. (Make sure that the main() method calls the method that you have worked on, rather than the other one.) Entering an empty string at the prompt will cause the program to terminate.

The difference between parseIntRec() and parseIntRecNarrated() is that the former is intended to simply do its job, whereas the latter does that same job but also narrates its own execution while doing it. That narration may be helpful to you in figuring out where you have gone wrong, in case your initial efforts are not successful.

To illustrate, here is what an execution of the main() method could like like, if it calls parseIntRecNarrated():

Enter a decimal integer numeral (empty string to quit): 4567
Received "4567"
   Received "456"
      Received "45"
         Received "4"
         Returning 4 having received "4"
      Returning 45 having received "45"
   Returning 456 having received "456"
Returning 4567 having received "4567"

Numeral "4567" translates to integer 4567

Enter another decimal integer numeral (empty string to quit):
Goodbye.

If, instead, the parseIntRec() method were called, none of the "Received ..." or "Returning ..." messages would appear.