This week's book giveaway is in the Kotlin forum.
We're giving away four copies of Kotlin in Action and have Dmitry Jemerov & Svetlana Isakova on-line!
See this thread for details.
Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Can Someone Explain to Me This Code?  RSS feed

 
Arnel Colar
Greenhorn
Posts: 7
Eclipse IDE Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I was doing an exercise here in javaranch to say a number. I finished it and yet it felt a bit cluttered and there are too many redundant codes so I asked for help. Many helped but there was one that caught my attention. This code:


Every number I input works flawlessly. Then I got confused.. so here are my questions:
How did the say() method work?
Why is it that even if it is not on a loop the say() method works?
What is the role of boolean here?

 
fred rosenberger
lowercase baba
Bartender
Posts: 12542
48
Chrome Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The say method is a recursive function. It calls itself, each time reducing the problem to an easier case.

Printing the words for a number like 123,456,789 can be broken into simpler parts - it's the same as printing the words for 123,000,000 and then printing the words for 456,789.

So if we input this value, we'd call say(123456789). That method then calls say(123456789, true).

So now we drop into line 15. My number is < 1000000000, so we return "say(number/1000000, false)+" million "+say(number%1000000, false)"

if you look at that carefully, you will see we are calling the method say two more times...one with 123 and false, and once with 456,789 and false. So before we can return from THIS call of say, we have to go INTO another nested version of itself.

When we call say(123,false), we will get to line 25 and call the method say two MORE times...and again, the first one of these calls has to return before the second starts.



Recursion is a very messy, nasty, but powerful tool. I've been writing code for 10+ years, and recursive calls still give me headaches.


and to answer your last question, we need to know if we should say the word "zero" or not. if the input is "0", then we DO want to say "zero", However, if the input is "123,000,456", when we break down the number, we don't want it to print "zero thousand". The boolean flag is used to control that part.
 
Matthew Brown
Bartender
Posts: 4568
9
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Arnel. Welcome to The Ranch!

There's no loop, but this is an example of a recursive function. You'll notice that that some of the branches in the say() method call the say() method again (with a modified argument). That sort of mechanism can effectively give you a "loop" without needing an explicit loop structure.

Let's trace through an example. Call say(1234, true).

This matches the condition on line 27. Which re-calls the method twice. So:
(remember this is integer arithmetic)

Tracing these secondary calls (and keep going)
And putting it all back together again


If you've got something like this that doesn't make sense to you, just try taking it step by step, using a pen and paper to keep track.
 
Jesper de Jong
Java Cowboy
Sheriff
Posts: 16028
87
Android IntelliJ IDE Java Scala Spring
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch!

To understand how a program works, just follow in your mind line by line what happens, remembering the value of variables as you go through the program.

Suppose we enter the number 120 in line 36.
In line 37, the variable speak will then be assigned the number 120.
In line 38, the say() method is called with the value 120.

Then we go into the say() method in line 10.
In line 11, it calls the other version of the say() method (line 15), with number = 120 and sayZero = true.

Then the if-statements are being evaluated.
The first one (line 17) is false, because number is 120, which is not less than 0.
The second one (line 19) is also false, as are the third and fourth ones (lines 21 and 23).
The fifth one, in line 25, is true, because 120 < 1000 is true.
So, what happens then?

The method returns the value of the expression after the return-statement.

Here comes something that makes understanding this a bit confusing: the say() method calls itself (two times) - it is a recursive method.

First, it calls say(number/100, false) and then say(number%100) (which is actually the first version of the say() method in line 10 - but that calls the one from line 15 again immediately).

So, it calls say(1, false) first. Now remember where that call was (in line 25); that's the point where we will get back when the call returns.
The call starts again at line 15, but now with number = 1 and sayZero = false.
The if in line 17 and 19 are again false.
But now the if in line 21 is true. It returns simple[number], which is "one".

Now the method returns back to the previous call that we had to remember: line 25.
Note that the statement is now partially evaluated: we now have return "one"+" hundred"+say(number%100).
There's one more say() call to evaluate. It goes to line 10, then in line 11, the second say() method is called again, this time with number = 20 and sayZero = true.

Following this along some more, you'll see that this goes to line 23, where it returns tens[number/10] = tens[2] = "twenty" plus the result of another recursive call, which will return "" because sayZero will be false in line 19.

Note the notation in line 19:

It is using the ? : operators, which might be new to you. This is just a shorthand form of an if-statement.

result = expr ? a : b just means:


Getting back to line 25 of the first call, we now have: return "one"+" hundred "+"twenty" , or return "one hundred twenty".

That's what is returned to the main() method in line 38, so that's what you'll see.
 
Arnel Colar
Greenhorn
Posts: 7
Eclipse IDE Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you all for the welcome and thank you for explaining the code. I thought I would look like a complete idiot asking that question (I get that a lot on OTHER Java forums). It looks like this will be favorite Java forum starting today.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!