如何将数字拆分成数字字符串?

时间:2014-03-16 15:00:55

标签: java

我是java编程的新手,我尝试了一个示例代码来获取两位数的输入并打印该数字的措辞。

public class ReadNumberInWord {

    public Integer number;

    public ReadNumberInWord() {
        Scanner userInput = new Scanner(System.in);
        System.out.println("Enter the number to read out : ");

        try {
            number = userInput.nextInt();
            readNumber();
        } catch (Exception e) {
            System.out.println("Please enter an integer");
            new ReadNumberInWord();
        }
    }

    public void readNumber() {
        System.out.println("Entered number is : " + number);
        int numSize = number.toString().length();
        System.out.println("number size is : " + numSize);

        switch (numSize) {
            case 1:
                sizeOne();
                break;
            case 2:
                sizeTwo();
                break;
            case 3:
                sizeThree();
                break;
            case 4:
                sizeFour();
                break;
            default:
                System.out.println("Enter number of four digit or less ");
                new ReadNumberInWord();
                break;
        }
    }

    private void sizeFour() {
        System.out.println("Number in words : " + numberCheck(number.toString()));
    }

    private void sizeThree() {
        String[] sizeThree = number.toString().split("");
        System.out.println(sizeThree[0]);
        System.out.println(sizeThree[1]);
        System.out.println(sizeThree[2]);

        for (int i = 0; i <= sizeThree.length - 1; i++) {
            System.out.println(sizeThree[i]);
        }

        System.out.println("Number in words : " + numberCheck(number.toString()));
    }

    private void sizeTwo() {
        String[] sizeTwo = number.toString().split("");
        //System.out.println(sizeTwo[0]);
        //System.out.println(sizeTwo[1]);
        String wordsString1 = "";
        ArrayList<String> wordsArray = new ArrayList<String>();
        for (int i = 0; i <= sizeTwo.length - 1; i++) {
            System.out.println(sizeTwo[i]);
            String words = numberCheck(sizeTwo[i]);
            wordsArray.add(words);
        }

        for (String w : wordsArray) {
            wordsString1 += w + "\t";
        }
        System.out.println("Number in words : " + wordsString1);
    }

    private void sizeOne() {
        System.out.println("Number in words : " + numberCheck(number.toString()));
    }

    public String numberCheck(String numb) {
        int num = Integer.parseInt(numb);
        switch (num) {
            case 0:
                return "zero";
            case 1:
                return "one";
            case 2:
                return "two";
            case 3:
                return "three";
            case 4:
                return "four";
            case 5:
                return "five";
            case 6:
                return "six";
            case 7:
                return "seven";
            case 8:
                return "eight";
            case 9:
                return "nine";
            case 10:
                return "ten";
            default:
                return "unknown";
        }
    }

    public static void main(String[] args) {
        new ReadNumberInWord();
    }
}

在上面的代码中,如果我输入两位数字作为78,它应该打印七八。但是,这不适用于此。相反,我得到了例外。请帮我解决。

3 个答案:

答案 0 :(得分:3)

在调试时,堆栈跟踪是非常有用的信息,如果遇到意外的异常但忽略堆栈跟踪,则忽略此信息。如果你打印了异常的堆栈跟踪,你会看到这个:

Enter the number to read out : 
78
Entered number is : 78
number size is : 2

Exception in thread "main" java.lang.NumberFormatException: For input string: ""
    at java.lang.NumberFormatException.forInputString(Unknown Source)
    at java.lang.Integer.parseInt(Unknown Source)
    at java.lang.Integer.parseInt(Unknown Source)
    at ReadNumberInWord.numberCheck(ReadNumberInWord.java:74)
    at ReadNumberInWord.sizeTwo(ReadNumberInWord.java:58)
    at ReadNumberInWord.readNumber(ReadNumberInWord.java:26)
    at ReadNumberInWord.<init>(ReadNumberInWord.java:13)
    at ReadNumberInWord.main(ReadNumberInWord.java:94)

这清楚地表明Integer.parseInt(),通过numberCheck(),使用空字符串""进行输入,这不是一个有效的整数,会导致Integer.parseInt()抛出你看到的例外。

现在你需要找出正在发生的为什么。您知道传递给parseInt()的字符串直接来自numberCheck()参数,因此这意味着numberCheck()传递一个空字符串。既然你知道输入来自sizeTwo中的sizeTwo()数组,那么一个好的开始就是在那里打印那个数组的内容:

System.out.println(Arrays.toString(sizeTwo));

这样做,你会看到:

[ , 7, 8 ]

第一个空元素是提示。以这种方式使用split是不太对的,从技术上讲,输入字符串以&#34; empty&#34;开头。字符串,你最终得到它(例如在":7:8"上分割:)。您必须使numberCheck()忽略空字符串,或者找到将字符串拆分为数字的其他方法。前者是对问题根本原因的创可贴(请记住:你的实际意图是不在数字列表中包含任何空字符串),所以我们将关注后者。

一种选择是将数字转换为String(跳过String[]事物),然后转换为char数组,例如:

char[] digits = number.toString().toCharArray();

然后,您可以使用char代替String。另一个选择是在循环中使用substring(),例如:

String numberstr = number.toString();

for (int n = 0; n < numberstr.length(); ++ n) {
   String digit = number.substring(n, 1);
   ...
}

当然,拥有这个字符串中间人并不是必需的,你可以用算术来做:

for (int n = (int)Math.log10(number); n >= 0; -- n) {
    int digit = (number / (int)Math.pow(10, n)) % 10;
    System.out.println(digit);
}

或反过来但不依赖于浮点计算:

int temp = number;

while (temp) {
    digit = temp % 10;
    temp /= 10;
    System.out.println(digit);
}

您的代码可以通过许多其他方式进行清理和大大简化(例如Richard Miskin在评论中暗示,您真的需要解析int吗?)但我认为以上涵盖了您当前问题的根源。


至于错误处理本身,我建议您只使用Scanner.next()来读取字符串,然后您可以使用Integer.parseInt()来解析它,如果您看到NumberFormatException,请再次询问。这将适当地使用异常,并且使用next()而不是nextInt()将令牌从流中拉出,即使它是无效的int(让您继续请求输入)。例如:

Scanner userInput = new Scanner(System.in);
System.out.println("Enter the number to read out : ");

while (true) {
    try {
        number = Integer.parseInt(userInput.next());
        break;
    } catch (NumberFormatException x) {     
        System.out.println("Please enter a valid integer");
    }
};

请注意以下几个关键概念:

  • 可能捕获最窄的异常(即NumberFormatException,而不是Exception)。有道理因为:NumberFormatException是我们试图处理的唯一问题。
  • 异常处理程序通常应该尝试恢复;否则在处理它们时毫无意义。在这种情况下,我们的恢复尝试是通知用户出现问题并要求新的有效输入。

您当前的实现设置了一个递归堆栈,还有一些其他问题。

答案 1 :(得分:1)

问题在于:

String[] sizeTwo=number.toString().split("");

当数字为“78”时,它产生数组[“”,“7”,“8”],而不是[“7”,“8”]。 您应该以不同方式将字符串拆分为数字(或忽略始终为空字符串的第一个标记)。

split(..)接受一个正则表达式,指定哪些模式被视为标记分隔符。在您的情况下,我发现以下正则表达式很有用:

String[] sizeTwo=number.toString().split("(?<=\\d)(?=\\d)");

它要求分隔符为空字符串,前后跟一个数字(使用一个名为positive lookbehind和positive lookahead的功能)

答案 2 :(得分:1)

你正在从终端读取字符Integer,然后不得不跳过箍将其转换为字符数组以便进一步处理,这似乎有点奇怪。通过阅读String,验证String符合您的要求,然后处理String中的每个字符,可以简化逻辑。

我还有其他一些变化:

  1. 没有理由将每个长度视为一种特殊情况,
  2. 如果出现错误,你可以循环而不是再次调用构造函数,
  3. number不需要是成员变量,您只需将其作为参数传递给每个方法调用,
  4. 如果您使用String,则无需将toCharArray()的各个元素转换回switch语句的整数。
  5. 以下示例适用于String而不是Integer

    import java.util.Scanner;
    
    public class ReadNumberInWord {
    
        public ReadNumberInWord() {
            final Scanner userInput = new Scanner(System.in);
            System.out.println("Enter the number to read out : ");
            boolean success = false;
            // Keep looping until the correct input is supplied.
            while (!success) {
                final String number = userInput.nextLine();
                if (validNumber(number)) {
                    readNumber(number);
                    success = true;
                }
            }
        }
    
        /**
         * @param number
         *            the String to check.
         * @return <code>true</code> if and only if number is less than 5 characters
         *         long and can be parsed as an integer.
         */
        private boolean validNumber(final String number) {
            boolean returnValue = false;
            try {
                Integer.parseInt(number);
                if (number.length() <= 4) {
                    returnValue = true;
                } else {
                    System.out.println("Enter number of four digit or less ");
                }
            } catch (final NumberFormatException e) {
                System.out.println("Please enter an integer");
            }
            return returnValue;
        }
    
        /**
         * When supplied a String that represents an integer this method writes out
         * each digit as a word to stdout.
         * 
         * @param number
         *            a String that represents an integer
         */
        public void readNumber(final String number) {
            System.out.println("Entered number is : " + number);
            final int numSize = number.length();
            System.out.println("number size is : " + numSize);
            final char[] chars = number.toCharArray();
            for (int i = 0; i < chars.length; i++) {
                System.out.print(numberCheck(chars[i]));
                if (i < chars.length - 1) {
                    System.out.print('\t');
                } else {
                    System.out.println();
                }
            }
        }
    
        /**
         * @param num
         *            a character that represents one of the numbers 0-9
         * @return the word representing the supplied number e.g. zero, one etc
         */
        public String numberCheck(final char num) {
            switch (num) {
            case '0':
                return "zero";
            case '1':
                return "one";
            case '2':
                return "two";
            case '3':
                return "three";
            case '4':
                return "four";
            case '5':
                return "five";
            case '6':
                return "six";
            case '7':
                return "seven";
            case '8':
                return "eight";
            case '9':
                return "nine";
            default:
                return "unknown";
            }
        }
    
        public static void main(final String[] args) {
            new ReadNumberInWord();
        }
    }