在Java中将单词转换为数字

16

我看过很多算法,可以将数字如“123”转换为“一百二十三”。但我找不到相反的方法,而我找到的那些只能将数字转换到1000。有没有人可以指导我正确的方法,创建一个将“一千二百三十四”转换为“1234”的方法?


@jordiburgos 这只是复杂性问题。 - Anubian Noob
9个回答

24

我希望以下代码可以在大多数情况下完成工作。但是,由于我还没有经过充分的测试,因此可能需要进行一些修改。

假设:

  1. 不允许使用正数、负数、加号、减号。
  2. 不允许使用“lac”、“crore”等词语。
  3. 仅支持英文语言。

如果你需要支持前两个点,你可以很容易地做到这一点。

    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);
        }
    }

1
测试过了,目前运行得非常好。非常感谢你:D!! - Alizoh
很高兴能帮到你,这让我感到非常愉快 :) - Kartic

5

3
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
我已经得出了这个解决方案。 它适用于零到一百万之间的数字(可以轻松扩展),可以支持破折号/和/仅数字。
public int parseInt(String number) {
    //Edge cases
    if("one million".equals(number)) return 1000000;
    if("zero".equals(number)) return 0;
    
    String[] splitted = number.split("thousand");
    String hundreds = splitted.length == 1 ? splitted[0].trim() : splitted[1].trim();
    
    int resultRight = calculateTriplet(hundreds);
    
    //X thousand case
    if(splitted.length == 1) {
        if(number.contains("thousand"))
            return resultRight*1000;
        return resultRight;
    }
    
    String thous = splitted[0].trim();
    int resultLeft = calculateTriplet(thous) * 1000;
    
    return resultLeft+resultRight;
}

private int calculateTriplet(String hundreds) {
    String[] triplet = hundreds.split(" |-");
    int result = 0;
    for (int i=0;i<triplet.length;i++) {
        result *= triplet[i].equals("hundred") ? 100 : 1;
        result += upTo19.indexOf(triplet[i]) != -1 ? 
                upTo19.indexOf(triplet[i]) 
                : tens.indexOf(triplet[i]) != -1 ?
                        tens.indexOf(triplet[i])*10 :
                            0;
    }
    return result;
}

  private static final List<String> tens = new ArrayList<String> (Arrays.asList(
            "","ten","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"));

 private static final List<String> upTo19 = new ArrayList<String> (Arrays.asList(
            "","one","two","three","four","five","six","seven","eight","nine", "ten","eleven","twelve","thirteen",
            "fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"));

0

适用于卢比和亿,忽略“and”。不处理:

  1. 无效的情况,例如“eight and crores”。
  2. 像“fifty billion crores”这样的输入
    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","lakhs","lakh","thousand","crore","crores","and",
    "million","billion","trillion"
    );

    //String input="one hundred";
    String input = String.join(" ", args);
    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)
            {
                String compare=str.toLowerCase();
                switch(compare){
                case "and":break;
                case "zero":result += 0;
                            break;
                case "one":result += 1;
                           break;
                
                case "two":result += 2;
                           break;
                case "three":result += 3;
                           break;
                case "four":result += 4;
                           break; 
                case "five":result += 5;
                           break;  
                case "six":result += 6;
                           break;
                case "seven":result += 7;
                           break;
                case "eight":result += 8;
                           break;
                case "nine":result += 9;
                           break;
                case "ten":result += 10;
                           break;
                case "eleven":result += 11;
                           break;
                case "twelve":result += 12;
                           break;
                case "thirteen":result += 13;
                           break;
                case "fourteen":result += 14;
                           break;
                case "fifteen":result += 15;
                           break;
                case "sixteen":result += 16;
                           break;
                case "seventeen":result += 17;
                           break;
                case "eighteen":result += 18;
                           break;
                case "nineteen":result += 19;
                           break;
                case "twenty":result += 20;
                           break;
                case "thirty":result += 30;
                           break;
                case "forty":result += 40;
                           break;
                case "fifty":result += 50;
                           break;
                case "sixty":result += 60;
                           break;
                case "seventy":result += 70;
                           break;
                case "eighty":result += 80;
                           break;
                case "ninety":result += 90;
                           break;
                case "hundred":result *= 100;
                           break;
                case "thousand":result *= 1000;
                           finalResult += result;
                           result=0;
                           break;
                case "lakh":result *= 100000;
                           finalResult += result;
                           result=0;
                           break;
                case "lakhs":result *= 100000;
                           finalResult += result;
                           result=0;
                           break;
                case "crore":result *= 10000000;
                           finalResult += result;
                           result=0;
                           break;   
                case "crores":result *= 10000000;
                           finalResult += result;
                           result=0;
                           break;
                case "million":result *= 1000000;
                           finalResult += result;
                           result=0;
                           break;
                case "billion":result *= 1000000000;
                           finalResult += result;
                           result=0;
                           break;
                case "trillion":result *= 1000000000000L;
                           finalResult += result;
                           result=0;
                           break;
                }
            }

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

0

另一种选择 :)

enum numbers {
    zero,
    one,
    two,
    three,
    four,
    five,
    six,
    eight,
    nine
}

public static String parseNumbers(String text) {

    String out = "";
    for(String s: text.split(" ")) {
        out += numbers.valueOf(s).ordinal();
    }
    return out;
}

0

好的,我想我已经有了一些东西。


有一个名为“debug”的变量,当产生的数字不像应该的那样工作时,请将其设置为true并执行以下操作:

  1. 给我你使用的字符串和你期望的数字
  2. 给我它生成的日志
  3. 请耐心等待

如果您需要超过1万亿的数字(我无法想象,但是好吧),请告诉我这个数字叫什么;)

代码:

    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);

如果它有效,请告诉我,并不要忘记提供反馈(无论是积极的还是消极的)
编程愉快 :) -Charlie PS:我的母语不是英语,但这样写数字是可以的。如果有问题,请告诉我!


我对解决方案进行了基本测试,因为我觉得这个问题和答案很有趣。看起来对于“eighteen”,它给出了正确的答案,但同时也抛出了ArrayIndexOutOfBoundsException异常。此外,它对于“ten hundred thousand”、“one million”、“one billion”等数字无法正常工作。我们还可以添加一个逻辑来处理负数的“minus”。 - Kartic
"eighteen" 仍然与正确答案一起引发异常。 - Kartic
@Kartic 感谢您的评论,我纠正了这个问题。如果您还发现其他问题,请告诉我。 - Charlie
"eighteen" 是什么意思?请注意两边的空格。 - Kartic
1
抱歉回复大家这么晚。我先测试了这段代码,但对于所有单词,结果总是“999999999999999”,不确定为什么。 - Alizoh
显示剩余5条评论

0

我已经使用HashMap实现了相同的功能,避免在语句中使用if else。

假设: 未处理负数

代码:

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);
}
}

输出:

I have 20000 twenti 2 rupees

110000

110147

-3

打印0到99999数字转换为单词的最佳简单方法

注意:您也可以使用相同的逻辑扩展大于99999的更多数字。

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));   
    }    
}

感谢您的阅读!


问题反过来了:给定一个字符串,返回相应的整数。 - Teepeemm
我们需要将单词转换为数字,而不是将数字转换为单词。 - Rohit Chaurasiya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接