Converting Words to Numbers in Java

前端 未结 6 925
深忆病人
深忆病人 2020-12-09 19:24

I have seen a lot of algorithms in which you give them a number say \"123\" and it converts it to One hundred twenty three. But i can\'t seem to find something that does the

相关标签:
6条回答
  • 2020-12-09 19:26

    Okay, I think I've gotten something.

    There is a variable called 'debug', when the number produces doesn't work like it should please set this to true and do the following things:
    1) Give me the string you used and the number you expected
    2) Give me the log it produces
    3) Be patient

    If you want numbers above 1 trillion (which I can't imagine, but well) please tell me what that number is called ;)

    The code:

        boolean debug=true;
        String word="";
    
        // All words below and others should work
        //word="One thousand two hundred thirty four"; //1234
        //word="Twenty-one hundred thirty one"; //2131
        //word="Forty-three thousand seven hundred fifty one"; //43751
        //word="Nineteen thousand eighty"; // 19080
        //word="five-hundred-forty-three thousand two hundred ten"; //543210
        //word="ninety-eight-hundred-seventy-six thousand"; // 9876000
    
        // Max:
        word="nine-hundred-ninety-nine trillion nine-hundred-ninety-nine billion nine-hundred-ninety-nine million nine-hundred-ninety-nine thousand nine hundred ninety nine";
    
    
        word=word.toLowerCase().trim();
    
        String oldWord="";
        while(word!=oldWord) {
            oldWord=word;
            word=word.replace("  "," ");
        }
    
        String[] data=word.split(" ");
    
        HashMap<String, Long> database=new HashMap<String, Long>();
        database.put("zero", 0L);
        database.put("one", 1L);
        database.put("two", 2L);
        database.put("three", 3L);
        database.put("four", 4L);
        database.put("five", 5L);
        database.put("six", 6L);
        database.put("seven", 7L);
        database.put("eight", 8L);
        database.put("nine", 9L);
    
        database.put("ten", 10L);
        database.put("hundred", 100L);
        database.put("thousand", 1000L);
        database.put("million", 1000000L);
        database.put("billion", 1000000000L);
        database.put("trillion", 1000000000000L);
    
        // Exceptional prefixes
        database.put("twen", 2L);
        database.put("thir", 3L);
        database.put("for", 4L);
        database.put("fif", 5L);
        database.put("eigh", 8L);
    
        // Other exceptions
        database.put("eleven", 11L);
        database.put("twelve", 12L);
    
    
        boolean negative=false;
        long sum=0;
        for(int i=0; i<data.length; i+=2) {
    
            long first=0;
            long second=1;
    
            try {
                if(data[i].equals("minus")) {
                    if(debug) System.out.println("negative=true");
                    negative=true;
                    i--;
                } else if(data[i].endsWith("ty")) {
                    first=database.get(data[i].split("ty")[0])*10;
                    i--;
                } else if(data[i].endsWith("teen")) {
                    first=database.get(data[i].split("teen")[0])+10;
                    if(data.length>i+1)
                        if(database.get(data[i+1])%10!=0)
                            i--;
                        else
                            second=database.get(data[i+1]);
                } else if(data[i].contains("-")){
                    String[] moreData=data[i].split("-");
    
                    long a=0;
                    long b=0;
    
                    if(moreData[0].endsWith("ty")) {
                        a=database.get(moreData[0].split("ty")[0])*10;
                    } else {
                        a=database.get(moreData[0]);
                    }
    
                    if(debug) System.out.println("a="+a);
    
                    b=database.get(moreData[1]);
                    if(b%10==0)
                        first=a*b;
                    else
                        first=a+b;
    
                    if(debug) System.out.println("b="+b);
    
                    if(moreData.length>2) {
                        for(int z=2; z<moreData.length; z+=2) {
                            long d=0;
                            long e=0;
    
                            if(moreData[z].endsWith("ty")) {
                                d=database.get(moreData[z].split("ty")[0])*10;
                            } else {
                                d=database.get(moreData[z]);
                            }
    
                            if(debug) System.out.println("d="+d);
    
                            if(d%100==0) {
                                first*=d;
                                z--;
                            } else {
                                e=database.get(moreData[z+1]);
                                if(e%10==0)
                                    first+=d*e;
                                else
                                    first+=d+e;
                                if(debug) System.out.println("e="+e);
                            }
                        }
                    }
    
                    second=database.get(data[i+1]);
    
                } else if(word.length()>0){
                    first=database.get(data[i]);
                    if(data.length>i+1)
                        second=database.get(data[i+1]);
                } else {
                    System.err.println("You didn't even enter a word :/");
                }
    
                if(debug) System.out.println("first="+first);
                if(debug) System.out.println("second="+second);
    
            } catch(Exception e) {
                System.out.println("[Debug Info, Ignore] Couldn't parse "+i+"["+data[i]+"]");
                e.printStackTrace(System.out);
            }
    
            sum+=first*second;
        }
        if(negative)
            sum*=-1;
    
        System.out.println("Result: "+sum);
    

    Let me know if it works and don't forget to give feedback. (Both positive and negative)
    Happy coding :) -Charlie PS: My native language isn't English, but this works as I should write numbers. Let me know if it isn't!

    0 讨论(0)
  • 2020-12-09 19:29

    I have done another implementation of the same using HashMap to store the numbers and avoiding if else in a statement.

    Assumptions: Negative numbers not handled

    Code:

    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Set;
    
    public class TranslateSentenceTonumber2 {
    
    public static void main(String[] args) {
        initFIRSTTWENTY();
    
        String sentence1 = "I have twenty thousand twenti two rupees";
        translateNumber(sentence1);
      
        String sentence4 = "one hundred ten thousand";
        translateNumber(sentence4);
    
        String sentence5 = "one hundred forty seven";
        translateNumber(sentence4 + " " +sentence5);
    }
    
    private static HashMap<String, Integer> FIRSTTWENTY;
    
    private static final String SPACES_SPLIT = "\\s+";
    
    private static void translateNumber(String playSentence){
        String sentence = playSentence;
        HashMap<String, Long> CALCULATION = new HashMap<>();
        Set<String > ALLOWED = new HashSet<>(FIRSTTWENTY.keySet());
        ALLOWED.add("hundred");
        ALLOWED.add("thousand");
        ALLOWED.add("million");
        if (sentence != null && sentence.length() >0) {
            sentence = sentence.replace("-", " ");
            String [] splittedString = sentence.split(SPACES_SPLIT);
            String continuousString = "";
            int length = splittedString.length;
            for (int i=0; i<length; i++){
                String str  = splittedString[i];
                if (ALLOWED.contains(str.toLowerCase()) && !continuousString.trim().equalsIgnoreCase(str)){
                    continuousString = continuousString.trim() + " " + str;
                    if (i== length-1){
                        CALCULATION.put(continuousString.trim(), null);
                        continuousString = "";
                    }
                }
                if (!ALLOWED.contains(str.toLowerCase()) && !continuousString.trim().isEmpty()) {
                    CALCULATION.put(continuousString.trim(), null);
                    continuousString = "";
                }
            }
    
            CALCULATION.replaceAll((c, v) -> calculation(c));
    
            for(String calc : CALCULATION.keySet()){
                playSentence = playSentence.replace(calc, "" +CALCULATION.get(calc));
            }
            System.out.println(playSentence);
        }
    }
    
    private static long calculation(String input){
        long inBetweenCalculation = 0;
        long output = 0;
        if (input != null && !input.isEmpty()) {
            String [] array = input.split(SPACES_SPLIT);
            for (String str: array) {
                if (FIRSTTWENTY.containsKey(str.toLowerCase())) {
                    inBetweenCalculation += FIRSTTWENTY.get(str.toLowerCase());
                } else if ("hundred".equalsIgnoreCase(str)) {
                    inBetweenCalculation *= 100;
                } else if ("thousand".equalsIgnoreCase(str)) {
                    inBetweenCalculation *= 1000;
                    output += inBetweenCalculation;
                    inBetweenCalculation = 0;
                } else if ("million".equalsIgnoreCase(str)) {
                    inBetweenCalculation *= 1000000;
                    output += inBetweenCalculation;
                    inBetweenCalculation = 0;
                }
            }
            output += inBetweenCalculation;
        }
        return output;
    }
    
    
    private static void initFIRSTTWENTY(){
        FIRSTTWENTY = new HashMap<>();
        FIRSTTWENTY.put("zero", 0);
        FIRSTTWENTY.put("one", 1);FIRSTTWENTY.put("eleven", 11);
        FIRSTTWENTY.put("two", 2);FIRSTTWENTY.put("twelve", 12);
        FIRSTTWENTY.put("three", 3);FIRSTTWENTY.put("thirteen", 13);
        FIRSTTWENTY.put("four", 4);FIRSTTWENTY.put("fourteen", 14);
        FIRSTTWENTY.put("five", 5);FIRSTTWENTY.put("fifteen", 15);
        FIRSTTWENTY.put("six", 6);FIRSTTWENTY.put("sixteen", 16);
        FIRSTTWENTY.put("seven", 7);FIRSTTWENTY.put("seventeen", 17);
        FIRSTTWENTY.put("eight", 8);FIRSTTWENTY.put("eighteen", 18);
        FIRSTTWENTY.put("nine", 9);FIRSTTWENTY.put("nineteen", 19);
        FIRSTTWENTY.put("ten", 10);FIRSTTWENTY.put("twenty", 20);
        FIRSTTWENTY.put("thirty", 30);FIRSTTWENTY.put("forty", 40);
        FIRSTTWENTY.put("fifty", 50);FIRSTTWENTY.put("sixty", 60);
        FIRSTTWENTY.put("seventy", 70);FIRSTTWENTY.put("eighty", 80);
        FIRSTTWENTY.put("ninety", 90);
    }
    }
    

    Output:

    I have 20000 twenti 2 rupees
    
    110000
    
    110147
    
    0 讨论(0)
  • 2020-12-09 19:29

    Best and simple way to print 0 to 99999 numbers to words conversion program

    Note: You can also extend more numbers greater than 99999 using same logic.

    import java.util.Scanner;
    class NumberToWord
    {  
        final private static String[]units = {"Zero", "One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten",
        "Eleven","Twelve","Thirteen","Fourteen","Fifteen","Sixteen","Seventeen","Eighteen","Nineteen"};
    
        final private static String[]tens = {"","","Twenty ","Thirty ","Forty ","Fifty ","Sixty ","Seventy ","Eighty ","Ninety "};
        public static String convert(int number)
        {
                if(number<0)
                {
                    throw new ArithmeticException("Number should be positive.");            
                }
                else if(number<20)
                {
                    return (units[number]);
                }   
                else if(number<100)
                {
                    return tens[number/10] + ((number % 10 > 0)? convert(number % 10):"");
                }           
                else if(number<1000)
                {
                    return units[number/100] + " hundred" + ((number%100>0)? " and " + convert(number%100):"");
                }           
                else if(number<20000)
                {
                    return  units[number/1000] + " Thousand " + ((number%1000>0)? convert(number%1000):"");
                }           
                    return tens[number/10000] + ((number%10000>0)? convert(number%10000):"Thousand" );      
        }   
    
        public static void main(String[] args) 
        {
            Scanner sc = new Scanner(System.in);
            System.out.print("Enter a number between 0 to 99999: ");
            int num = sc.nextInt();
            System.out.println(convert(num));   
        }    
    }
    

    Thank you for reading!!

    0 讨论(0)
  • 2020-12-09 19:38

    Full credit to Kartic for the elegant answer. I've added to it to allow for processing a large block of text with these types of "word numbers" dispersed inside of it. Not as clean as I hoped since I have to process it without losing any formatting.

    It's a work in progress but might be of some use to people: https://github.com/jgraham0325/words-to-numbers/blob/master/src/main/java/org/jg/wordstonumbers/WordsToNumbersUtil.java

    0 讨论(0)
  • 2020-12-09 19:42

    I hope below code will do the job in most of the cases. However some modification might be required as I've not tested properly yet.

    Assumption:

    1. Positive, negative, plus, minus is not allowed.
    2. Lac, crore is not allowed.
    3. Only English language is supported.

    If you need to support first two points, you can very easily do that.

        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);
            }
        }
    
    0 讨论(0)
  • 2020-12-09 19:51
    package com;
    
    import java.util.HashMap;
    
    public class WordNNumber {
    
        static HashMap<String, Integer> numbers= new HashMap<String, Integer>();
    
        static HashMap<String, Integer> onumbers= new HashMap<String, Integer>();
        static HashMap<String, Integer> tnumbers= new HashMap<String, Integer>();
    
        static {
            numbers.put("zero", 0);
            numbers.put("one", 1);
            numbers.put("two", 2);
            numbers.put("three", 3);
            numbers.put("four", 4);
            numbers.put("five", 5);
            numbers.put("six", 6);
            numbers.put("seven", 7);
            numbers.put("eight", 8);
            numbers.put("nine", 9);
            numbers.put("ten", 10);
            numbers.put("eleven", 11);
            numbers.put("twelve", 12);
            numbers.put("thirteen", 13);
            numbers.put("fourteen", 14);
            numbers.put("fifteen", 15);
            numbers.put("sixteen", 16);
            numbers.put("seventeen", 17);
            numbers.put("eighteen", 18);
            numbers.put("nineteen", 19);
    
    
            tnumbers.put("twenty", 20);
            tnumbers.put("thirty", 30);
            tnumbers.put("fourty", 40);
            tnumbers.put("fifty", 50);
            tnumbers.put("sixty", 60);
            tnumbers.put("seventy", 70);
            tnumbers.put("eighty", 80);
            tnumbers.put("ninety", 90);
    
            onumbers.put("hundred", 100);
            onumbers.put("thousand", 1000);
            onumbers.put("million", 1000000);
            onumbers.put("billion", 1000000000);
    
            //numbers.put("", );
        }
    
        public static void main(String args[]){
            String input1="fifty five million twenty three thousand ninety one";
            String input2="fifty five billion three thousand one";
            String input3="fifty five million ninety one";
    
            wordToNumber(input1);
            wordToNumber(input2);
            wordToNumber(input3);
    
    
        }
    
        private static void wordToNumber(String input) {
            System.out.println("===========\nInput string = "+input);
            long sum=0;
            Integer temp=null;
            Integer previous=0;
            String [] splitted= input.toLowerCase().split(" ");
    
    
            for(String split:splitted){
    
                if( numbers.get(split)!=null){
                    temp= numbers.get(split);
    
                    sum=sum+temp;
    
                    previous=previous+temp;
                }
                else if(onumbers.get(split)!=null){
                    if(sum!=0){
                        sum=sum-previous;
                    }
                    sum=sum+(long)previous*(long)onumbers.get(split);
                    temp=null;
                    previous=0;
    
    
                }
                else if(tnumbers.get(split)!=null){
                    temp=tnumbers.get(split);
                    sum=sum+temp;
    
                    previous=temp;
                }
    
            }
    
            System.out.println(sum);
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题