题目:请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串 +100, 5e2, -123, 3.14e+1 都表示数值,而 12e, 1a3.12, 1.2.3, +-5 都不是。

    首先我们要明白数值的格式为 A.B[e|E]C,其中 A, B, C 代表的是数字,有一点不同的是 A, C 中的前方可以有正负号,而 B 不能有正负号。我们变成的思路便是,首先扫描字符串,看是否匹配 A,即字符串的前方是否是数字(可包含正负号),接着如果碰到小数点,则扫描小数点后的字符是否是数字(不能包含正负号);最后匹配科学计数法,如果碰到 e|E,那么扫描后面的字符是否是数字(可包含正负号)。

    代码如下:

    1. public class IsNumberic {
    2. // 全局变量,控制从哪里开始扫描字符串
    3. private static int index;
    4. public static boolean isNumberic(char[] str) {
    5. if (str == null) {
    6. return false;
    7. }
    8. // 扫描字符串开头是否是数字(可带正负号)
    9. boolean numberic = scanInteger(str, 0);
    10. if (index < str.length) {
    11. // 如果有小数点
    12. if (str[index] == '.') {
    13. index++;
    14. // 扫描小数点后的数字(不带正负号)
    15. // 使用 || 是因为 A. 或者 .B都算有效的数值
    16. numberic = scanUnsignedInteger(str, index) || numberic;
    17. }
    18. }
    19. if (index < str.length) {
    20. // 如果扫描到 e|E
    21. if (str[index] == 'e' || str[index] == 'E') {
    22. index++;
    23. // 扫描 e|E 字符后面是否为数字(可带正负号)
    24. numberic = numberic && scanInteger(str, index);
    25. }
    26. }
    27. // 符合A.B[e|E]C的形式,并且字符串全部扫描完毕
    28. return numberic && index == str.length;
    29. }
    30. // 判断从某个位置开始,后面是否有数字(可带正负号)
    31. private static boolean scanInteger(char[] str, int start) {
    32. if (start >= str.length) {
    33. return false;
    34. }
    35. if (str[start] == '+' || str[start] == '-') {
    36. return scanUnsignedInteger(str, start + 1);
    37. }
    38. return scanUnsignedInteger(str, start);
    39. }
    40. // 判断从某个位置开始,后面是否有数字(不带正负号)
    41. private static boolean scanUnsignedInteger(char[] str, int start) {
    42. index = start;
    43. if (index < str.length) {
    44. while(str[index] >= '0' && str[index] <= '9') {
    45. index++;
    46. if (index == str.length) {
    47. break;
    48. }
    49. }
    50. }
    51. return index > start;
    52. }
    53. public static void main(String[] args) {
    54. System.out.println(isNumberic(".123".toCharArray())); // true
    55. System.out.println(isNumberic("123.".toCharArray())); // true
    56. System.out.println(isNumberic("+.123".toCharArray())); // true
    57. System.out.println(isNumberic("-.123".toCharArray())); // true
    58. System.out.println(isNumberic(".123e-2".toCharArray())); // true
    59. System.out.println(isNumberic("1.2.2".toCharArray())); // false
    60. System.out.println(isNumberic("1.2e+2".toCharArray())); // true
    61. }
    62. }