Прежде всего, я хотел бы сказать, что это мой первый пост, и, хотя я никогда не публиковал на StackOverflow.com, люди здесь помогли мне огромное количество, и я хотел бы вернуться и +1 все посты, которые мне помогли.
При этом мне дали задание в классе алгоритмов, где я должен рекурсивно преобразовывать числа от 1 до 1 000 000 в их счетчики слов.
Например, переход от 1 до 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
У меня код работает до 8,980, а до тестирования до 10000, но затем я сталкиваюсь с переполнением стека. Я не уверен, что JVM откладывает только достаточно памяти для работы до 8 980 или это что-то в моем коде. Я написал разбивку своих условий ниже и вставил код полностью внизу.
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 = "";
Сначала я установил строку number
для параметра n
с помощью Integer.toString(n)
.
Затем с каждым условным оператором я вычисляю первое число в последовательности и оттуда использую это число, чтобы задать для String newNumber
значение индекса в правильном массиве.
newNumber = zeroToNineteen[Integer.parseInt(number.substring(0, 1))] + THOUSAND;
После этого я печатаю newNumber
на консоль, а затем сбрасываю первое число с number
и позволяю ему опуститься до следующего условия.
System.out.print(newNumber);
number = number.substring(1, 4);
Затем я повторяю этот шаг до тех пор, пока число не упадет между 0 и 100. Где я затем печатаю номер на консоль и выполняю рекурсивный вызов toOneMillion(n+1);
до тех пор, пока n
не станет равным 10000 (для целей тестирования).
Полагаю, мой вопрос в том, можно ли достичь от 1 до 1 000 000, не сталкиваясь с переполнением стека? Также, если вы видите в моем коде что-то, чего не должно быть, или код, который может быть написан более эффективным способом (я знаю, что все это может быть написано более эффективным способом, мне просто интересно узнать о более мелких вещах) Вы указываете это и, возможно, объясняете? Большое вам спасибо за чтение этого, и спасибо за любую помощь прийти.
Полный код
У меня есть основной класс, который создает экземпляр класса чисел и вызывает рекурсивный метод через - numbers.toOneMillion(1)
... и это единственный другой класс в папке моего проекта, так что именно этот класс имеет проблему.
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);
}
}
}
}
}
Я понимаю, что мой код перемешан, и я должен разбить все мои условные выражения на один метод, который обрабатывает одну и ту же вещь для каждого условного выражения. Я просто хотел бы сначала заставить код работать, а затем усовершенствовать его. Кроме того, я почти уверен, что есть гораздо более эффективный способ сделать то, что я пытаюсь сделать, однако мой мозг и обработка мыслей придумали это, так что не ненавидь усердно.