【剑指Offer】面试题20. 表示数值的字符串

题目

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

本题同

思路

有效数字满足模式A[.[B]][e|EC]或者.B[e|EC]表示,其中A和C都是整数(可以有正负号,也可以没有),而B是一个无符号整数

代码

时间复杂度:O(n)
空间复杂度:O(1)

class Solution {
public:
    bool isNumber(string s) {
        if (s.empty()) return false;  
        int i = 0;     
        while (s[i] == ' ') ++i;  // 去除开头空格
        bool numeric = scanInteger(s, i);
        if (s[i] == '.') {
            ++i;  // 跳过点号
            // 用 || 原因:
            // 1. 小数可以没哟整数部分,如.123等于0.123
            // 2. 小数点后面可以没有数字,如233.等于233.0
            // 3. 小数点前后都有数字
            numeric = scanUnsignedInteger(s, i) || numeric;
        }
        if (s[i] == 'e' || s[i] == 'E') {
            ++i; // 跳过e|E
            // 用 && 原因:e|E 前面没有数字或后面没有整数都不能表示数字,如.e1、e1、12e、12e+5.4            
            numeric = numeric && scanInteger(s, i);
        }
        while (s[i] == ' ') ++i;  // 去除结尾空格
        return numeric && i == s.size();
    }

    bool scanInteger(string &s, int &i) {
        int size = s.size();
        if (i < size && (s[i] == '+' || s[i] == '-')) ++i;  // 跳过正负号
        return scanUnsignedInteger(s, i);
    }

    bool scanUnsignedInteger(string &s, int &i) {
        int size = s.size(), start = i;
        while (i < size && s[i] >= '0' && s[i] <= '9') ++i;
        return i > start;
    }
};
posted @ 2020-05-11 21:57  Galaxy_hao  阅读(201)  评论(0编辑  收藏  举报