开发者

How to convert words to a number? [closed]

开发者 https://www.devze.com 2023-01-22 13:30 出处:网络
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.

Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist

Closed 9 years ago.

Improve this question

I want to convert words containing alphabetical characters into a representative number in Java.

For example, four hundred fou开发者_如何学JAVAr should evaluate to the number 404.

If the letters are gibberish like asdf then that's an error.

I know I can convert bare Characters to their ascii equivalent Integer, appending those together, but I only want the numbers behind the English word phrases extracted.


Here is some code that I came up with when trying to solve the same problem. Keep in mind that I am not a professional and do not have insane amounts of experience. It is not slow, but I'm sure it could be faster/cleaner/etc. I used it in converting voice recognized words into numbers for calculation in my own "Jarvis" a la Iron Man. It can handle numbers under 1 billion, although it could easily be expanded to include much higher magnitudes at the cost of very little time.

public static final String[] DIGITS = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
public static final String[] TENS = {null, "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"};
public static final String[] TEENS = {"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"};
public static final String[] MAGNITUDES = {"hundred", "thousand", "million", "point"};
public static final String[] ZERO = {"zero", "oh"};

public static String replaceNumbers (String input) {
    String result = "";
    String[] decimal = input.split(MAGNITUDES[3]);
    String[] millions = decimal[0].split(MAGNITUDES[2]);

    for (int i = 0; i < millions.length; i++) {
        String[] thousands = millions[i].split(MAGNITUDES[1]);

        for (int j = 0; j < thousands.length; j++) {
            int[] triplet = {0, 0, 0};
            StringTokenizer set = new StringTokenizer(thousands[j]);

            if (set.countTokens() == 1) { //If there is only one token given in triplet
                String uno = set.nextToken();
                triplet[0] = 0;
                for (int k = 0; k < DIGITS.length; k++) {
                    if (uno.equals(DIGITS[k])) {
                        triplet[1] = 0;
                        triplet[2] = k + 1;
                    }
                    if (uno.equals(TENS[k])) {
                        triplet[1] = k + 1;
                        triplet[2] = 0;
                    }
                }
            }


            else if (set.countTokens() == 2) {  //If there are two tokens given in triplet
                String uno = set.nextToken();
                String dos = set.nextToken();
                if (dos.equals(MAGNITUDES[0])) {  //If one of the two tokens is "hundred"
                    for (int k = 0; k < DIGITS.length; k++) {
                        if (uno.equals(DIGITS[k])) {
                            triplet[0] = k + 1;
                            triplet[1] = 0;
                            triplet[2] = 0;
                        }
                    }
                }
                else {
                    triplet[0] = 0;
                    for (int k = 0; k < DIGITS.length; k++) {
                        if (uno.equals(TENS[k])) {
                            triplet[1] = k + 1;
                        }
                        if (dos.equals(DIGITS[k])) {
                            triplet[2] = k + 1;
                        }
                    }
                }
            }

            else if (set.countTokens() == 3) {  //If there are three tokens given in triplet
                String uno = set.nextToken();
                String dos = set.nextToken();
                String tres = set.nextToken();
                for (int k = 0; k < DIGITS.length; k++) {
                    if (uno.equals(DIGITS[k])) {
                        triplet[0] = k + 1;
                    }
                    if (tres.equals(DIGITS[k])) {
                        triplet[1] = 0;
                        triplet[2] = k + 1;
                    }
                    if (tres.equals(TENS[k])) {
                        triplet[1] = k + 1;
                        triplet[2] = 0;
                    }
                }
            }

            else if (set.countTokens() == 4) {  //If there are four tokens given in triplet
                String uno = set.nextToken();
                String dos = set.nextToken();
                String tres = set.nextToken();
                String cuatro = set.nextToken();
                for (int k = 0; k < DIGITS.length; k++) {
                    if (uno.equals(DIGITS[k])) {
                        triplet[0] = k + 1;
                    }
                    if (cuatro.equals(DIGITS[k])) {
                        triplet[2] = k + 1;
                    }
                    if (tres.equals(TENS[k])) {
                        triplet[1] = k + 1;
                    }
                }
            }
            else {
                triplet[0] = 0;
                triplet[1] = 0;
                triplet[2] = 0;
            }

            result = result + Integer.toString(triplet[0]) + Integer.toString(triplet[1]) + Integer.toString(triplet[2]);
        }
    }

    if (decimal.length > 1) {  //The number is a decimal
        StringTokenizer decimalDigits = new StringTokenizer(decimal[1]);
        result = result + ".";
        System.out.println(decimalDigits.countTokens() + " decimal digits");
        while (decimalDigits.hasMoreTokens()) {
            String w = decimalDigits.nextToken();
            System.out.println(w);

            if (w.equals(ZERO[0]) || w.equals(ZERO[1])) {
                result = result + "0";
            }
            for (int j = 0; j < DIGITS.length; j++) {
                if (w.equals(DIGITS[j])) {
                    result = result + Integer.toString(j + 1);
                }   
            }

        }
    }

    return result;
}

Input must be in grammatically correct syntax, otherwise it will have issues (create a function to remove "and"). A string input of "two hundred two million fifty three thousand point zero eight five eight oh two" returns:

two hundred two million fifty three thousand point zero eight five eight oh two
202053000.085802
It took 2 milliseconds.


The basic strategy would be to have a value variable that you work with. Each time you see a string "one", "two", "eleven", "seventy" you would add that amount to value. When you see a string like "hundred", "thousand", "million", you would multiply value by that amount.

For larger numbers you'll probably need to create a few subtotals and combine at the end. The steps to process a number like 111,374 written out as "one hundred eleven thousand three hundred seventy four" would be

  • "one" -> value[0] += 1 (now 1)
  • "hundred" -> value[0] *= 100 (now 100)
  • "eleven" -> value[0] += 11 (now 111)
  • "thousand" -> value[0] *= 1000 (now 111000)
  • "three" -> value[1] += 3
  • "hundred" -> value[1] *= 100 (now 300)
  • "seventy" -> value[1] += 70 (now 370)
  • "four" -> value[1] += 4 now (374)

You'll still need to figure out how to decide when to build it as multiple values. It appears you should start a new subtotal when you encounter a multiplier ("hundred") which is smaller than the most recently seen multiplier.


public class InNumerals5Digits {

static String testcase1 = "ninety nine thousand nine hundred ninety nine";//

public static void main(String args[]){
    InNumerals5Digits testInstance = new InNumerals5Digits();
    int result = testInstance.inNumerals(testcase1);
    System.out.println("Result : "+result);
}

//write your code here
public int inNumerals(String inwords)
{
    int wordnum = 0;
    String[] arrinwords = inwords.split(" ");
    int arrinwordsLength = arrinwords.length;
    if(inwords.equals("zero"))
    {
        return 0;
    }
    if(inwords.contains("thousand"))
    {
        int indexofthousand = inwords.indexOf("thousand");
        //System.out.println(indexofthousand);
        String beforethousand = inwords.substring(0,indexofthousand);
        //System.out.println(beforethousand);
        String[] arrbeforethousand = beforethousand.split(" ");
        int arrbeforethousandLength = arrbeforethousand.length;
        //System.out.println(arrbeforethousandLength);
        if(arrbeforethousandLength==2)
        {
            wordnum = wordnum + 1000*(wordtonum(arrbeforethousand[0]) + wordtonum(arrbeforethousand[1]));
            //System.out.println(wordnum);
        }
        if(arrbeforethousandLength==1)
        {
            wordnum = wordnum + 1000*(wordtonum(arrbeforethousand[0]));
            //System.out.println(wordnum);
        }

    }
    if(inwords.contains("hundred"))
    {
        int indexofhundred = inwords.indexOf("hundred");
        //System.out.println(indexofhundred);
        String beforehundred = inwords.substring(0,indexofhundred);

        //System.out.println(beforehundred);
        String[] arrbeforehundred = beforehundred.split(" ");
        int arrbeforehundredLength = arrbeforehundred.length;
        wordnum = wordnum + 100*(wordtonum(arrbeforehundred[arrbeforehundredLength-1]));
        String afterhundred = inwords.substring(indexofhundred+8);//7 for 7 char of hundred and 1 space
        //System.out.println(afterhundred);
        String[] arrafterhundred = afterhundred.split(" ");
        int arrafterhundredLength = arrafterhundred.length;
        if(arrafterhundredLength==1)
        {
            wordnum = wordnum + (wordtonum(arrafterhundred[0]));
        }
        if(arrafterhundredLength==2)
        {
            wordnum = wordnum + (wordtonum(arrafterhundred[1]) + wordtonum(arrafterhundred[0]));
        }
        //System.out.println(wordnum);

    }
    if(!inwords.contains("thousand") && !inwords.contains("hundred"))
    {
        if(arrinwordsLength==1)
        {
            wordnum = wordnum + (wordtonum(arrinwords[0]));
        }
        if(arrinwordsLength==2)
        {
            wordnum = wordnum + (wordtonum(arrinwords[1]) + wordtonum(arrinwords[0]));
        }
        //System.out.println(wordnum);
    }


    return wordnum;
}   


public int wordtonum(String word)
{
        int num = 0;
        switch (word) {
            case "one":  num = 1;
                     break;
            case "two":  num = 2;
                     break;
            case "three":  num = 3;
                     break;
            case "four":  num = 4;
                     break;
            case "five":  num = 5;
                     break;
            case "six":  num = 6;
                     break;
            case "seven":  num = 7;
                     break;
            case "eight":  num = 8;
                     break;
            case "nine":  num = 9;
                     break;
            case "ten": num = 10;
                     break;
            case "eleven": num = 11;
                     break;
            case "twelve": num = 12;
                     break;
            case "thirteen": num = 13;
                     break;
            case "fourteen": num = 14;
                     break;             
            case "fifteen": num = 15;
                     break;
            case "sixteen": num = 16;
                     break;
            case "seventeen": num = 17;
                     break;
            case "eighteen": num = 18;
                     break;
            case "nineteen": num = 19;
                     break;
            case "twenty":  num = 20;
                     break;
            case "thirty":  num = 30;
                     break;
            case "forty":  num = 40;
                     break;
            case "fifty":  num = 50;
                     break;
            case "sixty":  num = 60;
                     break;
            case "seventy":  num = 70;
                     break;
            case"eighty":  num = 80;
                     break;
            case "ninety":  num = 90;
                     break; 
            case "hundred": num = 100;
                        break;
            case "thousand": num = 1000;
                        break;     
           /*default: num = "Invalid month";
                             break;*/
        }
        return num;
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消