Преобразование целых чисел в Java с использованием карты продолжить вопрос - PullRequest
0 голосов
/ 20 декабря 2018

Это вероятный ответ на мой вопрос о переполнении стека. Преобразование целых чисел в слова

Сначала я начал со словаря.Тогда я узнал, что это устарело.Так что теперь я использую карту вместо словаря.Мой код хорошо работает для числа до миллионов.Но подход, который я здесь использую, наивный.Основная проблема этого кода:

Первый: огромные числа использования переменных

Второй: избыточный кодовый блок согласно требованию программы

3-й: Множественный оператор if else

Я думаю об этой проблеме

Решение для 2-й проблемы: использование пользовательской функции или макроса для устранения избыточностикодовый блок

Решение для 3-ей проблемы: Использование переключателя

Мой код:

public class IntegerEnglish {
public static void main(String args[]){
    Scanner in=new Scanner(System.in);
    System.out.println("Enter the integer");
    int input_number=in.nextInt();
    Map<Integer,String> numbers_converter = new HashMap<Integer,String>();
    Map<Integer,String> number_place = new HashMap<Integer,String>();
    Map<Integer,String> number_2nd = new HashMap<Integer,String>();
    numbers_converter.put(0,"Zero");
    numbers_converter.put(1,"One");
    numbers_converter.put(2,"Two");
    numbers_converter.put(3,"Three");
    numbers_converter.put(4,"Four");
    numbers_converter.put(5,"Five");
    numbers_converter.put(6,"Six");
    numbers_converter.put(7,"Seven");
    numbers_converter.put(8,"Eight");
    numbers_converter.put(9,"Nine");
    numbers_converter.put(10,"Ten");
    numbers_converter.put(11,"Eleven");
    numbers_converter.put(12,"Twelve");
    numbers_converter.put(13,"Thirteen");
    numbers_converter.put(14,"Fourteen ");
    numbers_converter.put(15,"Fifteen");
    numbers_converter.put(16,"Sixteen");
    numbers_converter.put(17,"Seventeen");
    numbers_converter.put(18,"Eighteen");
    numbers_converter.put(19,"Nineteen");
    number_place.put(3,"Hundred");
    number_place.put(4,"Thousand");
    number_place.put(7,"Million");
    number_place.put(11,"Billion");
    number_2nd.put(2,"Twenty");
    number_2nd.put(3,"Thirty");
    number_2nd.put(4,"Forty");
    number_2nd.put(5,"Fifty");
    number_2nd.put(6,"Sixty");
    number_2nd.put(7,"Seventy");
    number_2nd.put(8,"Eighty");
    number_2nd.put(9,"Ninty");

   if(input_number== 0){
       System.out.println("zero");
   }
   else if(input_number>0 && input_number<19){
       System.out.println(numbers_converter.get(input_number));
   }
   else if(input_number>19 && input_number<100){
       int rem=input_number%10;
       input_number=input_number/10;
       System.out.print(number_2nd.get(input_number));
       System.out.print(numbers_converter.get(rem));
   }
   else if(input_number==100){
       System.out.println(number_place.get(3));
   }
   else if(input_number>100 && input_number<1000){
       int reminder=input_number%100;
       int r1=reminder%10;
       int q1=reminder/10;
       int quot=input_number/100;
       System.out.print(numbers_converter.get(quot) + "hundred");
       if(reminder>0 && reminder<20){
           System.out.print(numbers_converter.get(reminder));
       }
       else{
           System.out.println(number_2nd.get(q1) + numbers_converter.get(r1));
       }
   }
   else if(input_number==1000){
       System.out.println(number_place.get(4));
   }
   else if(input_number>1000 && input_number<10000){
       int rem=input_number%100;
       int rem_two=rem%10;
       int quotient =rem/10;
       input_number=input_number/100;
       int thousand=input_number/10;
       int hundred = input_number%10;
       System.out.print(numbers_converter.get(thousand) + "thousand" + numbers_converter.get(hundred)+ " hundred");
       if(rem >0 && rem<20){
           System.out.print(numbers_converter.get(rem));
       }
       else if(rem >19 && rem <100){
           System.out.print(number_2nd.get(quotient) + numbers_converter.get(rem_two));
       }
   }
   else if(input_number>10000 && input_number<1000000000){
       //Say number 418,229,356
       int third_part=input_number%1000;//hold 356
       input_number=input_number/1000;//hold 418,229
       int sec_part=input_number%1000;//hold 229
       input_number=input_number/1000;// hold 418
       int rem_m=third_part%100;//hold 56
       int rem_m1=rem_m%10;//hold 6
       int rem_q=rem_m/10;// hold 5
       int q_m=third_part/100;// hold 3
       int sec_part_rem=sec_part%100;// hold 29
       int sec_part_rem1=sec_part_rem%10;//9
       int sec_part_q=sec_part_rem/10;//hold 2
       int sec_q=sec_part/100;// hold 2
       int input_q=input_number/100;// hold 4
       int input_rem=input_number%100;//hold 18
       int input_q_q=input_rem/10;//hold 1
       int input_rem1=input_rem%10;// hold 8
       System.out.print(numbers_converter.get(input_q) + " hundred ");
       if(input_rem>0 && input_rem<20){
           System.out.print(numbers_converter.get(input_rem)+ " Million ");
       }
       else{
           System.out.print(number_2nd.get(input_q_q) + " " + numbers_converter.get(input_rem1) + " Million ");
       }
       System.out.print(numbers_converter.get(sec_q) + " hundred ");
       if(sec_part_rem >0 && sec_part_rem<20){
           System.out.println(numbers_converter.get(sec_part_rem) + " thousand ");
       }
       else{
           System.out.print(number_2nd.get(sec_part_q) + " " + numbers_converter.get(sec_part_rem1) + " thousand ");
       }
       System.out.print(numbers_converter.get(q_m) + " hundred ");
       if(rem_m>0 && rem_m<20){
           System.out.print(numbers_converter.get(rem_m));
       }
       else{
           System.out.print(number_2nd.get(rem_q) + " " + numbers_converter.get(rem_m1));
       }
   }
  }
   }

Избыточные кодовые блоки

       int rem=input_number%100;
       int rem_two=rem%10;
       int quotient =rem/10;
       input_number=input_number/100;
       int thousand=input_number/10;
       int hundred = input_number%10;

Этот тип кодового блока используется почти везде.Взяв число, разделите его на 100 или 1000, чтобы узнать позицию в сотне, затем разделите его на 10, чтобы узнать десятую позицию числа.Наконец, используя% (модульное деление), чтобы выяснить позицию.

Как я могу включить определяемую пользователем функцию и переключать регистр, чтобы минимизировать блок кода.

Ответы [ 2 ]

0 голосов
/ 20 декабря 2018

Я бы посоветовал вам разбить ваш единственный основной метод на пару классов.И если вы еще не создали несколько модульных тестов, которые позволят вам легко тестировать / реорганизовывать вещи.Вы найдете это быстрее, чем запустите приложение и начнете читать из стандартного ввода.

Вам будет проще работать с числом в виде строки.Вместо того, чтобы делить на 10 все время, вы просто берете последний символ строки.У вас может быть класс, который делает этот бит для вас, и отдельный класс, который выполняет конвертацию.

Вот то, что я придумал, но я уверен, что его можно улучшить.Он имеет класс PoppableNumber, который позволяет легко извлечь последний символ исходного числа.И класс NumberToString, который имеет метод статического преобразования для выполнения преобразования.

Примером теста может быть

@Test
public void Convert102356Test() {
    assertEquals("one hundred and two thousand three hundred and fifty six", NumberToString.convert(102356));
}

А вот класс NumberToString:

import java.util.HashMap;
import java.util.Map;

public class NumberToString {

    // billion is enough for an int, obviously need more for long
    private static String[] power3 = new String[] {"", "thousand", "million", "billion"};

    private static Map<String,String> numbers_below_twenty = new HashMap<String,String>();
    private static Map<String,String> number_tens = new HashMap<String,String>();

    static {
        numbers_below_twenty.put("0","");
        numbers_below_twenty.put("1","one");
        numbers_below_twenty.put("2","two");
        numbers_below_twenty.put("3","three");
        numbers_below_twenty.put("4","four");
        numbers_below_twenty.put("5","five");
        numbers_below_twenty.put("6","six");
        numbers_below_twenty.put("7","seven");
        numbers_below_twenty.put("8","eight");
        numbers_below_twenty.put("9","nine");
        numbers_below_twenty.put("10","ten");
        numbers_below_twenty.put("11","eleven");
        numbers_below_twenty.put("12","twelve");
        numbers_below_twenty.put("13","thirteen");
        numbers_below_twenty.put("14","fourteen ");
        numbers_below_twenty.put("15","fifteen");
        numbers_below_twenty.put("16","sixteen");
        numbers_below_twenty.put("17","seventeen");
        numbers_below_twenty.put("18","eighteen");
        numbers_below_twenty.put("19","nineteen");

        number_tens.put(null,"");
        number_tens.put("","");
        number_tens.put("0","");
        number_tens.put("2","twenty");
        number_tens.put("3","thirty");
        number_tens.put("4","forty");
        number_tens.put("5","fifty");
        number_tens.put("6","sixty");
        number_tens.put("7","seventy");
        number_tens.put("8","eighty");
        number_tens.put("9","ninty");
    }

    public static String convert(int value) {
        if (value == 0) {
            return "zero";
        }
        PoppableNumber number = new PoppableNumber(value);

        String result = "";
        int power3Count = 0;
        while (number.hasMore()) {
            String nextPart = convertUnitTenHundred(number.pop(), number.pop(), number.pop());
            nextPart = join(nextPart, " ", power3[power3Count++], true);
            result = join(nextPart, " ", result);
        }

        if (number.isNegative()) {
            result = join("minus", " ", result);
        }

        return result;
    }

    public static String convertUnitTenHundred(String units, String tens, String hundreds) {
        String tens_and_units_part = "";
        if (numbers_below_twenty.containsKey(tens+units)) {
            tens_and_units_part =  numbers_below_twenty.get(tens+units);
        }
        else {
            tens_and_units_part = join(number_tens.get(tens), " ", numbers_below_twenty.get(units));
        }
        String hundred_part = join(numbers_below_twenty.get(hundreds), " ", "hundred", true);
        return join(hundred_part, " and ", tens_and_units_part);
    }

    public static String join(String part1, String sep, String part2) {
        return join(part1, sep, part2, false);
    }

    public static String join(String part1, String sep, String part2, boolean part1Required) {
        if (part1 == null || part1.length() == 0) {
            return (part1Required) ? "" : part2;
        }
        if (part2.length() == 0) {
            return part1;
        }
        return part1 + sep + part2;

    }

    /**
     * 
     * Convert an int to a string, and allow the last character to be taken off the string using pop() method.
     * 
     * e.g.
     * 1432
     * Will give 2, then 3, then 4, and finally 1 on subsequent calls to pop().
     * 
     * If there is nothing left, pop() will just return an empty string.
     * 
     */
    static class PoppableNumber {

        private int original;
        private String number;
        private int start;
        private int next;


        PoppableNumber(int value) {
            this.original = value;
            this.number = String.valueOf(value);
            this.next = number.length();
            this.start = (value < 0) ? 1 : 0;   // allow for minus sign.
        }

        boolean isNegative() {
            return (original < 0);
        }

        boolean hasMore() {
            return (next > start);
        }

        String pop() {
            return hasMore() ? number.substring(--next, next+1) : "";
        }
    }

}
0 голосов
/ 20 декабря 2018

Вместо сохранения результатов в переменных, используйте вызов метода:

int remainder100(int aNumber) {
    return aNumber % 100;
}

int remainder10(int aNumber) {
    return aNumber % 10;
}

...etc.

System.out.println(numbers_converter.get(remainder100(input_number)));

О третьей проблеме: я бы не использовал switch ... case, слишком много падежей.

Вместо этого воспользуйтесь тем, что нумерация повторяется каждые 3 цифры.Это означает, что шаблон для тысяч и миллионов одинаков (и миллиарды, триллионы и т. Д.).

Для этого используйте цикл, подобный следующему:

ArrayList<String> partialResult = new ArrayList<String>();
int powersOf1000 = 0;
for (int kiloCounter = input_number; kiloCounter > 0; kiloCounter /= 1000) {
    partialResult.add(getThousandsMilionsBillionsEtc(powersOf1000++);
    partialResult.add(convertThreeDigits(kiloCounter % 1000));
}

Затем вы можете распечататьсодержимое partialResult в обратном порядке, чтобы получить окончательный номер.

...