First off I would like to say that this is my first post and that although I have never posted on StackOverflow.com, the people here have helped me an enormous amount and I wish I could go back and +1 all of the posts that have helped me.
That being said I was given an assignment in an algorithms class where I have to recursively convert the numbers 1 through 1,000,000 to their word counter parts.
For Example going from 1 to 1,000,000
one
two
three
...and so on...
one hundred and ninetyseven
one hundred and ninetyeight
one hundred and ninetynine
two hundred
...and so on...
nine hundred and ninetynine thousand nine hundred and ninetyeight
nine hundred and ninetynine thousand nine hundred and ninetynine
one million
I’ve got my code working to 8,980 just running to 10,000 for testing but then I run into a Stack Overflow. I’m not sure if the JVM puts aside only enough memory to run to 8,980 or if it’s something in my code. I’ve written a break down of my conditionals below and pasted the code in full underneath.
public class Numbers {
private final String HUNDRED = " hundred ";
private final String THOUSAND = " thousand ";
private String[] zeroToNineteen = { "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
private String[] twentyToOneHundred = { "", "", "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety" };
The following recursive method is my only method in my numbers class.
public void toOneMillion(int n) {
String number = Integer.toString(n);
String newNumber = "";
I first set a String number to the parameter n by means of Integer.toString(n).
Then with each conditional statement I figure out the first number in the sequence and from there use that number to set a String newNumber to the index value in the correct array.
newNumber = zeroToNineteen[Integer.parseInt(number.substring(0, 1))] + THOUSAND;
Afterward I print newNumber to the console and then drop the first number from number and let it drop down to the next conditional.
System.out.print(newNumber);
number = number.substring(1, 4);
I then repeat this step until the number falls between 0 and 100. Where I then println the number to the console and make the recursive call toOneMillion(n+1); until n is equal to 10,000 (for testing purposes).
I guess my question is, is it possible to achieve 1 to 1,000,000 without encountering a stackoverflow? Also if you see something in my code that shouldn’t be there or code that could be written in a more efficient way (I know the whole thing could be written in a more efficient way, I’m just wondering about smaller things) could you point it out and perhaps explain? Thank you so much for reading this far, and thank you for any help to come.
Code In Full
I have a main class that creates an instance of the numbers class and calls the recursive meathod via – numbers.toOneMillion(1)… and that’s the only other class in my project folder, so it’s this is the class with the problem.
public class Numbers {
private final String HUNDRED = " hundred ";
private final String THOUSAND = " thousand ";
private String[] zeroToNineteen = { "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve",
"thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
private String[] twentyToOneHundred = { "", "", "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety" };
public void toOneMillion(int n) {
String number = Integer.toString(n);
String newNumber = "";
if (n == 10000) {
System.out.println("10000");
} else if (n > 0) {
if (n >= 100) {
if (n >= 1000) {
if (n % 1000 == 0) {
newNumber = zeroToNineteen[Integer.parseInt(number.substring(0, 1))] + THOUSAND;
System.out.print(newNumber);
number = number.substring(1, 4);
} else {
newNumber = zeroToNineteen[Integer.parseInt(number.substring(0, 1))] + THOUSAND;
System.out.print(newNumber);
number = number.substring(1, 4);
// System.out.println("HELLO!" + number + " " + n);
}
}
if (Integer.parseInt(number) != 0) {
if (n % 100 == 0) {
if(zeroToNineteen[Integer.parseInt(number.substring(0, 1))].equals("")) {
newNumber = zeroToNineteen[Integer.parseInt(number.substring(0, 1))];
System.out.print(newNumber);
number = number.substring(1, 3);
} else {
newNumber = zeroToNineteen[Integer.parseInt(number.substring(0, 1))] + HUNDRED;
System.out.print(newNumber);
number = number.substring(1, 3);
}
} else {
if(zeroToNineteen[Integer.parseInt(number.substring(0, 1))].equals("")) {
newNumber = zeroToNineteen[Integer.parseInt(number.substring(0, 1))] + "and ";
System.out.print(newNumber);
number = number.substring(1, 3);
} else {
newNumber = zeroToNineteen[Integer.parseInt(number.substring(0, 1))] + HUNDRED + "and ";
System.out.print(newNumber);
number = number.substring(1, 3);
}
// System.out.println("HELLO!" + number + " " + n);
}
}
}
if (Integer.parseInt(number) < 20) {
System.out.println(zeroToNineteen[Integer.parseInt(number)]);
toOneMillion(n + 1);
} else {
if (n % 10 == 0) {
number = number.substring(0, 1);
newNumber = twentyToOneHundred[Integer.parseInt(number)];
System.out.println(newNumber);
toOneMillion(n + 1);
} else {
newNumber = twentyToOneHundred[Integer.parseInt(number
.substring(0, 1))];
newNumber += zeroToNineteen[Integer.parseInt(number
.substring(1))];
System.out.println(newNumber);
toOneMillion(n + 1);
}
}
}
}
}
I realize my code is jumbled and I should break down all of my conditionals into one method that handles the same thing for each conditional, I would just like to get the code working first and then perfect it. Also I’m almost posotive there is a much more efficient way to do what I’m trying to do, however my brain and thought processing came up with this so don’t hate to hard.
I have a feeling you are misunderstanding where they are expecting the recursion.
Thinking more along the lines of :
Where
printNumberRecursivelyruns through the number recursively one digit at a time.If I’m wrong then the assignment is ludicrous.