美文网首页剑指Offer-PHP实现
《剑指Offer》-20.表示数值的字符串

《剑指Offer》-20.表示数值的字符串

作者: 懒人成长 | 来源:发表于2018-08-07 07:18 被阅读2次

    题干

    请实现一个函数用来判断字符串是否表示数值(包括整数和小数),例如,字符串 +1005e2-1233.1416-1E-16 都表示数值,但 12e1a3.141.2.3+-512e+5.4 都不是。

    解题思路

    数值字符串的模式 A[.[B]][e|EC],A是数值的整数部分,有正负值区分,B是数值的小数部分,紧跟着小数点,C为指数部分,紧跟着e或E,C也有正负值区分。

    在小数里可能没有整数部分,整数后也可能只有小数点而没有小数部分。

    因此可以按照字符串是否符合这个模式来判断是否是数值。

    代码实现

    function isNumeric($str)
    {
        if (!isset($str)) {
            return false;
        }
        $idx = 0;
        $numeric = scanInteger($str, $idx);
    
        if ($str[$idx] == '.') {
            $idx++;
    
            /**
             * 小数可以没有整数部分,如.123 等于 0.123
             * 小数点后面可以没有数字,如123. 等于 123.0
             * 小数点前后都有数字
             */
            $numeric = scanUnsignedInteger($str, $idx) || $numeric;
        }
        if (isset($str[$idx]) && ($str[$idx] == 'e' || $str[$idx] == 'E')) {
            $idx++;
            /**
             * e|E 后面必须有数字,且必须是整数
             */
            $numeric = $numeric && scanInteger($str, $idx);
        }
    
        return $numeric && !isset($str[$idx]);
    }
    
    function scanInteger($str, &$idx)
    {
        if ($str[$idx] == '+' || $str[$idx] == '-') {
            $idx++;
            return scanUnsignedInteger($str, $idx);
        }
    
        return scanUnsignedInteger($str, $idx);
    }
    
    function scanUnsignedInteger($str, &$idx)
    {
        $hasNumeric = false;
        while (isset($str[$idx]) && $str[$idx] >= '0' && $str[$idx] <= '9') {
            $idx++;
            $hasNumeric = true;
        }
    
        return $hasNumeric;
    }
    
    var_dump(isNumeric('123.'));
    var_dump(isNumeric('.123'));
    

    相关文章

      网友评论

        本文标题:《剑指Offer》-20.表示数值的字符串

        本文链接:https://www.haomeiwen.com/subject/sianvftx.html