2015-03-27 3 views
1

Я ищу способ сортировки «числовых слов» в числовом порядке. Например, предположим, что у меня есть список [«пять», «три», «шесть», «восемь»], я хотел бы сортировать его как «три», «пять», «шесть», «восемь»] а не в лексикографическом порядке. Я огляделся вокруг, включая этот сайт, и ближайшим/лучшим решением является использование карты и сортировка списка на основе пар ключ-значение.Сортировка «чисел» в цифровом порядке

Я придумал другие идеи, подобные этому, но, в конце концов, все они требуют создания большого стола/списка для сопоставления числа слов с фактическим числом. Я бы хотел, чтобы решение, по возможности, автоматически расширялось, поэтому, если оно работает для списка выше, оно также будет работать для списка [«десять квадриллионов девятьсот миллионов пять тысяч два», «шесть», «четыре», ]. Чем больше я думаю об этом, тем менее я уверен, что это можно сделать. Любая помощь приветствуется.

+0

Я не уверен, что это полностью подходит для стандарта SO формата вопрос, но я думаю, что вы хотите сделать, это: A) Написать синтаксический анализатор, который может преобразовывать слова в их числовой эквивалент (обратите внимание, что вы можете использовать wolfram alpha, что также позволит вам сортировать [«десять плюс пять», «три», «шесть раз восемь»]) B) Создать словарь для сопоставления между словом и числом для каждого элемента в списке C) Сортировка этого словаря D) Remap для создания отсортированного списка Я бы предложил попробовать это, а затем, если вам все еще нужна помощь, покажите, что вы пробовали, и где вы застряли – Foon

+0

@Foon - Спасибо! Слово-парсер - это то, что мне нужно в основном. В SO есть хороший вариант http://stackoverflow.com/questions/70161/how-to-read-values-from-numbers-written-s-words, и я попытаюсь реализовать алгоритм, указанный в java. Когда я застрял, я отправлю свою работу. Еще раз спасибо! – Ron

ответ

0

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

public static int convertNum(String input) 
{  
    ArrayList<String> prefixTable = new ArrayList<String>(); 
    prefixTable.add("ZE"); 
    prefixTable.add("ON"); 
    prefixTable.add("TW"); 
    prefixTable.add("TH"); 
    prefixTable.add("FO"); 
    prefixTable.add("FI"); 
    prefixTable.add("SI"); 
    prefixTable.add("SE"); 
    prefixTable.add("EI"); 
    prefixTable.add("NI"); 
    prefixTable.add("TEN"); 
    prefixTable.add("ELEVEN"); 
    prefixTable.add("TWELVE"); //MUST BE AT END OTHERWISE TW REGISTERS AS PREFIX 

    Map<String, Integer> delimTable = new HashMap<String, Integer>(); 
    delimTable.put("HUNDRED", 100); 
    delimTable.put("THOUSAND", 1000); 
    delimTable.put("MILLION", 1000000); 
    delimTable.put("BILLION", 1000000000); 

    String[] theWords = input.toUpperCase().split(" "); 
    int runningTotal = 0; 
    int currentRunningNum = 0; 
    int currentNum = 1; 
    boolean skipTransfer = false; 

    for(int i = 0; i < theWords.length; i++) 
    { 
     if(theWords[i].equals("AND") || theWords[i].equals("NEGATIVE")) 
      continue; 

     if(delimTable.containsKey(theWords[i])) 
     { 
      if(delimTable.get(theWords[i]) == 100) 
       skipTransfer = true; 
      else 
       skipTransfer = false; 
      currentRunningNum *= delimTable.get(theWords[i]); 
      continue; 
     } 

     if(!skipTransfer) 
     { 
      runningTotal += currentRunningNum; 
      currentRunningNum = 0; 
     } 
     skipTransfer = false; 

     currentNum = 1; 

     for(int j = prefixTable.size() - 1; j >= 0 && currentNum == 1; j--) 
      if(theWords[i].startsWith(prefixTable.get(j))) 
       currentNum *= j; 

     if(theWords[i].endsWith("EEN")) 
      currentNum += 10; 
     if(theWords[i].endsWith("TY")) 
     { 
      currentNum *= 10; 
      skipTransfer = true; 
     } 

     currentRunningNum += currentNum; //ADD TOTAL 
    } 
    runningTotal += currentRunningNum; 
    if(theWords[0].equals("NEGATIVE")) 
     runningTotal *= -1; 

    return runningTotal; 
} 
0

Возможно, попробуйте этот ответ: https://stackoverflow.com/a/26951693/3663023. Это работало для меня, когда я пытался решить эту проблему. Как упоминал @abagshaw, сортировка массива с использованием любого алгоритма сортировки будет работать после преобразования чисел в текстовой форме в цифровую форму.

код из @Kartic выглядит следующим образом:

boolean isValidInput = true; 
long result = 0; 
long finalResult = 0; 
List<String> allowedStrings = Arrays.asList 
(
     "zero","one","two","three","four","five","six","seven", 
     "eight","nine","ten","eleven","twelve","thirteen","fourteen", 
     "fifteen","sixteen","seventeen","eighteen","nineteen","twenty", 
     "thirty","forty","fifty","sixty","seventy","eighty","ninety", 
     "hundred","thousand","million","billion","trillion" 
     ); 

String input="One hundred two thousand and thirty four"; 

if(input != null && input.length()> 0) 
{ 
    input = input.replaceAll("-", " "); 
    input = input.toLowerCase().replaceAll(" and", " "); 
    String[] splittedParts = input.trim().split("\\s+"); 

    for(String str : splittedParts) 
    { 
     if(!allowedStrings.contains(str)) 
     { 
      isValidInput = false; 
      System.out.println("Invalid word found : "+str); 
      break; 
     } 
    } 
    if(isValidInput) 
    { 
     for(String str : splittedParts) 
     { 
      if(str.equalsIgnoreCase("zero")) { 
       result += 0; 
      } 
      else if(str.equalsIgnoreCase("one")) { 
       result += 1; 
      } 
      else if(str.equalsIgnoreCase("two")) { 
       result += 2; 
      } 
      else if(str.equalsIgnoreCase("three")) { 
       result += 3; 
      } 
      else if(str.equalsIgnoreCase("four")) { 
       result += 4; 
      } 
      else if(str.equalsIgnoreCase("five")) { 
       result += 5; 
      } 
      else if(str.equalsIgnoreCase("six")) { 
       result += 6; 
      } 
      else if(str.equalsIgnoreCase("seven")) { 
       result += 7; 
      } 
      else if(str.equalsIgnoreCase("eight")) { 
       result += 8; 
      } 
      else if(str.equalsIgnoreCase("nine")) { 
       result += 9; 
      } 
      else if(str.equalsIgnoreCase("ten")) { 
       result += 10; 
      } 
      else if(str.equalsIgnoreCase("eleven")) { 
       result += 11; 
      } 
      else if(str.equalsIgnoreCase("twelve")) { 
       result += 12; 
      } 
      else if(str.equalsIgnoreCase("thirteen")) { 
       result += 13; 
      } 
      else if(str.equalsIgnoreCase("fourteen")) { 
       result += 14; 
      } 
      else if(str.equalsIgnoreCase("fifteen")) { 
       result += 15; 
      } 
      else if(str.equalsIgnoreCase("sixteen")) { 
       result += 16; 
      } 
      else if(str.equalsIgnoreCase("seventeen")) { 
       result += 17; 
      } 
      else if(str.equalsIgnoreCase("eighteen")) { 
       result += 18; 
      } 
      else if(str.equalsIgnoreCase("nineteen")) { 
       result += 19; 
      } 
      else if(str.equalsIgnoreCase("twenty")) { 
       result += 20; 
      } 
      else if(str.equalsIgnoreCase("thirty")) { 
       result += 30; 
      } 
      else if(str.equalsIgnoreCase("forty")) { 
       result += 40; 
      } 
      else if(str.equalsIgnoreCase("fifty")) { 
       result += 50; 
      } 
      else if(str.equalsIgnoreCase("sixty")) { 
       result += 60; 
      } 
      else if(str.equalsIgnoreCase("seventy")) { 
       result += 70; 
      } 
      else if(str.equalsIgnoreCase("eighty")) { 
       result += 80; 
      } 
      else if(str.equalsIgnoreCase("ninety")) { 
       result += 90; 
      } 
      else if(str.equalsIgnoreCase("hundred")) { 
       result *= 100; 
      } 
      else if(str.equalsIgnoreCase("thousand")) { 
       result *= 1000; 
       finalResult += result; 
       result=0; 
      } 
      else if(str.equalsIgnoreCase("million")) { 
       result *= 1000000; 
       finalResult += result; 
       result=0; 
      } 
      else if(str.equalsIgnoreCase("billion")) { 
       result *= 1000000000; 
       finalResult += result; 
       result=0; 
      } 
      else if(str.equalsIgnoreCase("trillion")) { 
       result *= 1000000000000L; 
       finalResult += result; 
       result=0; 
      } 
     } 

     finalResult += result; 
     result=0; 
     System.out.println(finalResult); 
    } 
}