题目描述

请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100"、"5e2"、"-123"、"3.1416"、"0123"及"-1E-16"都表示数值,但"12e"、"1a3.14"、"1.2.3"、"+-5"及"12e+5.4"都不是。

思路

  1. 可以先整理出数字中所有异常的元素,分别为'.','-','+','E',‘e’。

  2. 再整理出特殊一些的用例,例如'.3',‘.e3’,'3.14e3',‘3.’等等。

  3. 可以将数字分为特殊元素,以及有符号整数和无符号整数的组合。

  • 有符号数之后,必须为无符号数,例如‘-+3’是不合法的

  • 小数点之后,必须为无符号整数,例如'3.-5'是不合法的

  • 'e'或者‘E’之后,必须为整数,例如'3E-3.5'是不合法的

  1. 可以定义一个指针,按照找到的规则,从头到尾遍历,若最后指针扫描到了字符串的尾部,并且扫描到了数字,说明字符串是合法的数字。

Java代码实现

class Solution {
    private int index = 0;
    public boolean isNumber(String s) {
        s = s.trim();
        boolean flag1 = judgeIsNumber(s);
        boolean flag2 = false;

        if(index < s.length() && (s.charAt(index) == '.')){
            index++;
            flag2 = judgeIsUnsignedNumber(s);
        }

        if(index < s.length() && (s.charAt(index) == 'E' || s.charAt(index) == 'e')){
            index++;
            if(!judgeIsNumber(s)){
                return false;
            }
        }

        return index == s.length() && (flag1 || flag2);
    }

    private boolean judgeIsNumber(String s){
        if(index<s.length() && (s.charAt(index) == '-' || s.charAt(index) == '+')){
            index++;
        }
        return judgeIsUnsignedNumber(s);
    }

    private boolean judgeIsUnsignedNumber(String s){
        int cur = index;

        while(index < s.length() && (s.charAt(index)>='0' && s.charAt(index) <= '9')){
            index++;
        }

        return index>cur;
    }
}

Golang代码实现

var index int = 0
func isNumber(s string) bool {
    strings.Trim(s,s)
    flag1 := judgeIsNumber(s)
    flag2 := false

    if index<len(s) && s[index] == '.'{
        index++
        flag2 = judgeIsUnsignerNumber(s)
    }

    if index<len(s) && (s[index] == 'e' || s[index] == 'E'){
        index++
        if !judgeIsNumber(s){
            return false
        }
    }

    return index == len(s) && (flag1 || flag2)
}

func judgeIsNumber(s string) bool {
    if index < len(s) && (s[index] == '+' || s[index] == '-'){
        index++
    }
    return judgeIsUnsignerNumber(s)
}

func judgeIsUnsignerNumber(s string) bool {
    temp := index
    for index < len(s) && (s[index] >= '0' && s[index] <= '9'){
        index++;
    }
    return index > temp
}