Есть ли способ преобразовать строковый массив чисел в форме букв c в их форму чисел c? - PullRequest
1 голос
/ 11 января 2020

Я все еще новичок в java, но у меня возник вопрос относительно теории, которую я хотел проверить. Я хотел знать, есть ли способ написать программу, которая конвертирует строковый массив чисел, написанных буквами, такими как раз, два, три и т. Д. c, в их числовые формы c в виде целых чисел. Это действительно возможно? У меня нет примера кода, поскольку я еще не протестировал это. Но некоторые ответы будут с благодарностью. Спасибо!

Ответы [ 3 ]

0 голосов
/ 11 января 2020

В общем, я выяснил проблему такого рода с помощью шаблона «конфигурация поверх реализации». Позвольте мне поделиться с вами решением по вашему вопросу.

Java предлагает нам возможность хранить огромные пары ключ / значение в файле свойств и запрашивать его для сопоставления так часто, как нам нужно. Поэтому я бы сохранил этот файл: string2int.properties :

zero:0
one:1
two:2 
three:3
four:4
five:5
six:6
seven:7
eight:8
nine:9

Это формат для .properties файлов

А потом я таким образом можно получить доступ к значению ключа благодаря Свойствам объекту:

    Properties properties = new Properties(); 
    try { 
        FileInputStream input = new FileInputStream("string2int.properties");
        properties.load(input);
        System.out.println("one is : " + properties.getProperty("one"));
    }
    catch(Exception e) {
        e.printStackTrace();
    }

Выводу:

one is : 1
0 голосов
/ 11 января 2020

Вам также понадобится десять, эллин, двенадцать, тринадцать, ..., двадцать, тридцать, .. девяносто, сто, тысяча, миллион ... в вашем деле. Затем вам придется анализировать записанные числа.

«двести двенадцать тысяч три» должно быть (2x100 + 12) x 1000 + 3.

С указанным выше числом вы Знайте, что вы должны остановиться на сто и умножить на два. Вы также знаете, что, когда вы получаете «тысячу», все, что находится слева, должно быть умножено на 1000. Если где-то слева также нет миллиона.

Я попробовал с примером, который начинается с правого конца, наименее Значительные числа. Я записываю ключи 100 и 1000 и делаю рекурсивный расчет. Я не включил файл свойств, но вместо этого использовал карту. Если есть сопоставление для слова, оно добавляется в список, если это не «и». Если сопоставление для слова отсутствует, программа завершает работу с NullPointerException.

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

Также обратите внимание, что не обнаружено незаконных письменных чисел, таких как «одна две тысячи девяносто девяносто пять четыре». Это будет просто 3000 + 18000 + 9

public class TextToNumber{
  public static void main(String[] args){
    String s;
    TextToNumber textToNumber = new TextToNumber();

    s = "four";
    System.out.println(s);
    System.out.println(textToNumber.translateNumber(s));

    System.out.println("----");
    s = "one hundred";
    System.out.println(s);
    System.out.println(textToNumber.translateNumber(s));

    System.out.println("----");
    s = "five thousand";
    System.out.println(s);
    System.out.println(textToNumber.translateNumber(s));

    System.out.println("----");
    s = "twelve thousand two hundred fifty six";
    System.out.println(s);
    System.out.println(textToNumber.translateNumber(s));

    System.out.println("----");
    s = "two hundred and twelve thousand and three";
    System.out.println(s);
    System.out.println(textToNumber.translateNumber(s));

    System.out.println("----");
    s = "one two thousand ninety ninety hundred five four";
    System.out.println(s);
    System.out.println(textToNumber.translateNumber(s));
  }

  Map<String, Integer> map = new HashMap<>();
  public TextToNumber() {
    map.put("one", 1);
    map.put("two", 2);
    map.put("three", 3);
    map.put("four", 4);
    map.put("five", 5);
    map.put("six", 6);
    map.put("seven", 7);
    map.put("eight", 8);
    map.put("nine", 9);
    map.put("ten", 10);
    map.put("eleven", 11);
    map.put("twelve", 12);
    map.put("thirteen", 13);
    map.put("fourteen", 14);
    map.put("fifteen", 15);
    map.put("sixteen", 16);
    map.put("seventeen", 17);
    map.put("eighteen", 18);
    map.put("nineteen", 19);
    map.put("twenty", 20);
    map.put("thirty", 30);
    map.put("fourty", 40);
    map.put("fifty", 50);
    map.put("sixty", 60);
    map.put("seventy", 70);
    map.put("eighty", 80);
    map.put("ninety", 90);
    map.put("hundred", 100);
    map.put("thousand", 1000);
  }

  public int translateNumber(String text){
    List<Integer> numbers = new ArrayList<>(10);

    if (text == null) throw new IllegalArgumentException("Number cannot be empty");

    // borrowed from https://docs.oracle.com/javase/tutorial/i18n/text/word.html
    BreakIterator wordIterator = BreakIterator.getWordInstance();
    wordIterator.setText(text);

    int start = wordIterator.first();
    int end = wordIterator.next();

    while (end != wordIterator.DONE) {
        String word = text.substring(start,end);
        if (Character.isLetterOrDigit(word.charAt(0))) {
            if (!("and".equals(word))) numbers.add(map.get(word));
        }
        start = end;
        end = wordIterator.next();
    }

    System.out.println(numbers);
    return recursiveCalculation(numbers);
  }

  private int recursiveCalculation(List<Integer> list){
    int result = 0;
    int index1000 = list.lastIndexOf(Integer.valueOf(1000));
    int index100  = list.lastIndexOf(Integer.valueOf(100));

    // add all numbers that's to the right of the hundred marker
    //  (or 1000 marker in case there's no hundred marker)
    result += add(list, Math.max(index100+1,Math.max(index1000+1,0)), list.size());

    if (index100 != -1 && index100 > index1000) {
      result += 100 * recursiveCalculation(list.subList(index1000+1,index100));
    }

    if (index1000 != -1) {
      result += 1000 * recursiveCalculation(list.subList(0,index1000));
    }

    return result;
  }

  private int add(List<Integer> list, int begin, int end) {
    int sum = 0;
    for (int i = begin; i < end; i++) {
      sum += list.get(i);
    }
    return sum;
  }
}

Вот результат:

C:\..snip..>java -cp compiled/default TextToNumber
four
[4]
4
----
one hundred
[1, 100]
100
----
five thousand
[5, 1000]
5000
----
twelve thousand two hundred fifty six
[12, 1000, 2, 100, 50, 6]
12256
----
two hundred and twelve thousand and three
[2, 100, 12, 1000, 3]
212003
----
one two thousand ninety ninety hundred five four
[1, 2, 1000, 90, 90, 100, 5, 4]
21009
0 голосов
/ 11 января 2020

Скорее всего, вы захотите создать карту для поиска строковых значений в целых числах.

Map<String, Integer> map = new HashMap<>();
map.put("one", 1);
map.put("two", 2);
map.put("three", 3);
map.put("four", 4);

et c

Затем вы проанализируете вашу строку и посмотрите ее на карте

String text = "four"
Integer value = map.get(text); 

Если у вас есть множество вещей для преобразования тогда вам потребуется l oop, и, очевидно, ваш синтаксический анализ станет более сложным с более широким диапазоном возможных строковых значений, например: «Четыре тысячи тридцать пять»

...