Программа, которая набирает числа

В этом проекте мы создадим программу, которая переводит числа в слова. Практически это будет полезно в банках, где при выписке чеков необходимо записывать сумму денег орфографически. Конечно, в Интернете доступно множество движков «Число в слова», но я думаю, было бы забавно попытаться воссоздать их самостоятельно на Java!

Здесь мы с Брайаном сделаем две разные версии: индонезийский и английский конвертеры. У каждого из двух языков будут разные условные обозначения и исключения, поэтому наши коды будут немного отличаться.

Конвертер Gisella (индонезийский)

Основной метод

Наименьшие строительные блоки в Java называются методами / функциями. Каждая программа будет иметь main () метод, который будет первым методом, который будет выполнять IDE. Мой основной метод будет делать три вещи по порядку: попросить пользователя ввести число, проанализировать количество цифр и добавить расширение -ribu или -juta там, где это необходимо, и распечатать результат на экране пользователя.

1) Пользовательский ввод

В наших первых нескольких строках кода мы должны сначала отобразить Вставить сумму: на экране пользователя и попросить его ввести числа. Эту процедуру можно выполнить с помощью функции print(“Insert amount: “) и ссылки scanner, которые мы ранее использовали в 001_MortgageCalculator. Если код написан правильно, терминал должен выглядеть так:

Я буду использовать цикл while(true), чтобы пользователь мог постоянно вводить и преобразовывать сумму без повторного запуска кода. Мне также нужно будет добавить оператор if, который будет отображать false, чтобы завершить / прервать этот цикл. В этом случае цикл прервется, если пользователь введет «0» (строки 8–9).

Этот конвертер будет предполагать, что сумма денег не содержит десятичных знаков для простоты - IDR также не включает центов иирл. Следовательно, примитивная переменная int используется для определения amount, вводимого пользователем, как показано в строке 7. Его можно заменить на float при работе с центами в долларах / других валютах, но мы не будем иметь дело с этим в этом проекте.

2) Параметры

Следующим шагом будет установка параметров / условий для подсчета количества цифр в amount. Тогда это позволит программе знать, где при необходимости добавить слова «juta» или «ribu».

Это можно сделать с помощью функции number.length() из класса String. Однако компьютеры не могут анализировать числа в формате int, если функция является частью класса String; amount следует сначала преобразовать в String (строка 10). Поэтому мы скрываем amount в number с помощью функции Integer.toString(amount). Затем я определяю int i как длину (количество цифр) number.

Затем я разобрал i на группы по 3 цифры, сгруппировав их в массивы. Если i ›3, вводить следует либо ribu, либо juta. При повторном использовании цикла while() анализ будет продолжаться до тех пор, пока i не станет больше 3. Для достижения этого для каждого последующего цикла количество цифр вычитается на 3 (i-3). Например:

number (ввод пользователя) = 1760980

Цикл 1

i = 7 (в то время как i ›3 = истина)

arrayNumber: {“980”, “”, “”}

positionArray: 1

i-3 = 4

Цикл 2

i=4 (в то время как i ›3 = истина)

arrayNumber: {“980”, “760”, “”}

i-3 = 1

positionArray: 2

Цикл 3

i = 1 (в то время как i ›3 = ложь)

Теперь, когда мы вышли из цикла while, программа перейдет к строке 19. С этого момента мы будем создавать новые операторы for и if, которые будут указывать числа в arrayNumber и добавлять расширения «Juta» и «Ribu» там, где это необходимо.

Ссылаясь на приведенный выше пример, в настоящее время arrayNumber - это {«980», «760», «»}. Чтобы добавить «1» из «1760980» в последний слот, мы используем функцию number.substring(0,i) в строке 19. Эта функция попросит программу принять цифру в 0-й позиции (компьютер начинает отсчет с 0) до i. Поскольку i равно 1 из цикла 3 выше, будет взята только «1», а для нашего arrayNumber останется {«980», «760», «1»}.

Двигаясь дальше, мы начнем писать числа в arrayNumber, используя цикл for. Для этого вводится новая переменная int j для хранения значения positionArray из цикла while в строке 14. Буква j используется, чтобы отличить ее от i, которая использовалась ранее. Мы начинаем с самого большого positionArray в порядке убывания (j- -), чтобы работать в обратном порядке. Таким образом, первая группа из трех цифр будет написана первой. Продемонстрируем эту логику (строки 21–29), продолжив приведенный выше пример:

Предположим, что одно из сохраненных значений arrayNumber равно 000 (если вход содержит «000»), тогда расширение не будет добавлено, и программа запустит только строку 22 и перейдет к строке 32 . Поскольку ни одно из наших значений arrayNumber не равно «000», мы перейдем к строке 22.

Строка 22 преобразует значение в слова с помощью функции converter и сохранит результат в строке arrayResult. В результате у нас будет «1», записанное как «Satu». Вам может быть интересно, как это выполняет функция конвертера или почему конвертер не является частью main() method. Мы вернемся к этому в разделе Под-метод позже.

В цикле 2 наибольшее значение positionArray равно 2. Следовательно, j: 2.

Строка 24 j==2 (true), поэтому расширение «Juta» будет напечатано после «Satu».

Затем цикл for повторится для других значений j. После этого программа возвращается к строке 22.

Из цикла 1 positionArray равно 1. Следовательно, j: 1 и «Tujuh Ratus Enam Puluh» будут напечатаны после «Juta».

Строка 27 j==1 (true), поэтому расширение «Ribu» будет добавлено после «Tujuh Ratus Enam Puluh».

Теперь для j: 0 будет выполнена только строка 23, поскольку значение не удовлетворяет логическим условиям, указанным в строках 24–28. Таким образом, «Sembilan Ratus Delapan Puluh» печатается без какого-либо расширения, и программа выйдет из цикла if и перейдет к строке 32.

3) Результат

Последним шагом в основном методе будет вывод на экран суммы, хранящейся в String arrayResult, с помощью функции System.out.

Под-метод

Вот функции, которые используются в методе main(), но не определены там, чтобы код выглядел более лаконичным. Определяя их отдельно, мы также можем вызывать / использовать эти функции в другом классе. Для этого подметод должен быть «общедоступным», а не «частным». Поскольку я не планирую использовать эти функции где-либо еще, я создал методы converter и numberText в частном порядке.

1) конвертер

Эта функция возвращает значение arrayNumber. Поскольку мы разобрали его максимум на три цифры, converter может распознавать только единицы, десятки (puluh) и сотни (ratus). Для выполнения такой функции следует аналогичная процедура: взять длину строки и при необходимости добавить префиксы. Эти префиксы должны иметь отдельный код, поскольку они отклоняются от обычных соглашений.

Обратите внимание на несколько префиксов и исключений:

  • В IDR префикс Se используется для обозначения «100». Число пишется «Seratus», а не «Satu Ratus».
  • «10» и «11» пишутся «Sepuluh» и «Sebelas», а не «Satu Puluh» или «Satu Puluh». Сату
  • Если значение String в i равно 0, мы возвращаем только пустое пространство «» без расширений «Ratus» или «Puluh».

Я использую for циклы и if-else условия для создания таких исключений:

Возвращенный result теперь будет работать как аргумент каждый раз, когда функция converter вызывается в методе main или в других классах.

2) numberText

Эта функция дополняет указанную выше функцию converter. Его задача - распознавать номер и печатать его слова. Каждый раз, когда используется numberText(amountString.charAt(i)), функция numberText будет возвращать слово, представляющее символ в i. Функция switch-case используется для отображения различных возможных чисел, которые могут появиться. Напомним, что всегда следует за каждым регистром ставить break, чтобы цикл прервался после того, как программа завершит поиск назначенного слова.

Версия Брайана (английский)

В этой версии Брайан добавил комментарии в свое окно кода, чтобы отслеживать шаги, которые он выполнял, а также облегчить читателям их выполнение. Эти комментарии печатаются серым цветом // в этом формате.

По сути, его программа работает следующим образом: разбирает ввод на единицы, десятки, сотни и так далее. Отсюда функцииconvertHundreds, convertThousands и convertTens используются для соответствующего преобразования числа.

  • Для однозначных чисел: программа просто возвращает String из заранее определенного массива всех чисел от нуля до девяти.
  • Для двузначных чисел (от 10 до 19): они тоже аналогичным образом возвращают только String из заранее определенного массива специальных десятков.
  • Для двузначных чисел (20 и выше): программа просматривает первую цифру и берет String из массива, содержащего такие значения, как {Двадцать, Тридцать, Сорок и т. Д.}. Итак, если первая цифра - 6, String начнется с шестидесяти.
  • Для трехзначных чисел: программа берет две последние цифры числа и пропускает их через метод convertTens. После этого он берет первую цифру числа и преобразует ее тем же способом, что и однозначные числа.
  • После этого он посмотрит на вторую цифру и повторит процедуру для однозначных чисел.
  • Наконец, он объединяет обе эти строки

Однако обратите внимание, что для каждого из этих методов преобразования есть исключение для чисел, которые заканчиваются только нулями. Например, 1000 устанавливается равным одной тысяче вместо одной тысячи нуля. 1000000, это также должно быть установлено в один миллион вместо миллиона нуля.

Эта seperateDigits функция - это способ, которым Брайан разбирает цифры. Здесь его метод сильно отличается от моего.

  • Последняя цифра ввода помещается в массив с помощью оператора по модулю 10.
  • Оператор по модулю берет остаток от деления. Например, в операторе по модулю 10 модуль 456 равен 6, поэтому 6 помещается в массив
  • Поскольку Java усекает числа, а не округляет их, все десятичные цифры будут удалены. Таким образом, деление на 10 в основном удаляет последнюю цифру (например, 456 становится 45,6, а Java делает это 45)
  • Затем эти шаги повторяются до тех пор, пока число не станет нулевым и все цифры не будут помещены в массив.
  • seperateDigits затем вернетnumDigits, который будет преобразован и обработан в основном методе

Ключевые выводы:

  • Есть много способов кодировать один и тот же результат, некоторые из них могут быть более эффективными, чем другие :)