繁体   English   中英

在 Java 中将单词转换为数字

[英]Converting words to numbers in Java

我见过很多算法,你给他们一个数字,比如“123”,然后它将它转换为一百二十三。 但是我似乎找不到相反的东西,而我确实找到的东西只能达到数字 1000。谁能以正确的方式指导我,因为我可以做些什么来创建一个采用“一个”的方法千二百三十四”并回馈“1234”

我希望下面的代码在大多数情况下都能完成这项工作。 但是,由于我尚未正确测试,可能需要进行一些修改。

假设:

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

完全归功于 Kartic 的优雅答案。 我已经添加到它以允许处理一大块文本,其中这些类型的“字数”分散在其中。 没有我希望的那么干净,因为我必须在不丢失任何格式的情况下处理它。

这是一项正在进行的工作,但可能对人们有用: https ://github.com/jgraham0325/words-to-numbers/blob/master/src/main/java/org/jg/wordstonumbers/WordsToNumbersUtil.java

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

}

好吧,我想我得到了一些东西。

有一个名为 '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:我的母语不是英语,但我应该写数字。 如果不是,请告诉我!

我已经完成了另一个相同的实现,使用 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

为十万和千万工作并忽略“和”。不处理

  1. 像“八”和“千万”这样的无效案例。
  2. 像“五千万亿”这样的输入
    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);
        }
    }

替代 :)

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

我最终得到了这个解决方案。 它适用于零到一百万之间的数字(可以轻松增强),可以支持破折号/和/只是数字。

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

谢谢你的阅读!!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM