leetcode 剑指 Offer 20. 表示数值的字符串

leetcode 剑指 Offer 20. 表示数值的字符串

题目详情

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

我的代码

class Solution {
     
public:
    bool isNum(char &letter) {
     
        return letter >= '0' && letter <= '9';
    }

    bool isNumber(string s) {
     
        int start = 0, end = s.size();
        for (int i = 0; i < s.size(); ++i) {
     
            if (s[i] != ' ') {
     
                start = i;
                break;
            }
        }
        for (int j = s.size() - 1; j >= 0; --j) {
     
            if (s[j] != ' ') {
     
                end = j + 1;
                break;
            }
        }
        s = s.substr(start, end - start);
        int n = s.size();
        if (n < 2) {
     
            return isNum(s[0]);
        }
        bool hasSym = false, hasE = false, hasDot = false;
        for (int i = 0; i < n; ++i) {
     
            if (isNum(s[i])) {
     
                continue;
            } else if ((s[i] == '+') || (s[i] == '-')) {
     
                if (i == 0) {
     
                    continue;
                } if (!hasSym && (i > 0) && (i < n) && (s[i - 1] == 'E' || s[i - 1] == 'e') && isNum(s[i + 1])) {
     
                    hasSym = true;
                } else {
     
                    return false;
                }
            } else if ((s[i] == 'E') || (s[i] == 'e')) {
     
                if (!hasE && ((i > 0) && (i < n - 1) && (isNum(s[i - 1]) || (s[i - 1] == '.' && i >= 2 && isNum(s[i - 2]))))) {
     
                    if (isNum(s[i + 1]) || s[i + 1] == '+' || s[i + 1] == '-') {
     
                        hasE = true;
                    } else {
     
                        return false;
                    }
                } else {
     
                    return false;
                }
            } else if (s[i] == '.') {
     
                if (!hasDot && !hasE && ((i == 0) || ((i > 0) && (isNum(s[i - 1]) || ((s[i - 1] == '+' || s[i - 1] == '-') && (i + 1 < n) && isNum(s[i + 1])))))) {
     
                    hasDot = true;
                } else {
     
                    return false;
                }
            } else {
     
                return false;
            }
        }
        return true;
    }
};

我的成绩

执行结果:通过
执行用时:4 ms, 在所有 C++ 提交中击败了76.56%的用户
内存消耗:6.1 MB, 在所有 C++ 提交中击败了74.16%的用户

一些想法

本道题不是太难,但需要考虑很多规则。我错误了17次,第18次才通过。。。

执行用时为 8 ms 的范例


class Solution {
     
public:
    bool isNumber(string s) {
     
        size_t i=s.find_first_not_of(' ');//第一个不是空格的位置
        if(i==string::npos)return false;
        size_t j=s.find_last_not_of(' ');//最后一个不是空格的位置
        s=s.substr(i,j-i+1);//去除首尾空格
        if(s.empty())return false;
        size_t k = s.find_first_of('E');
        if(k != string::npos)   s[k] = 'e';//大写转小写
        size_t pos=s.find('e');
        if(pos == string::npos) return judgeLeft(s);//没有e
        return judgeLeft(s.substr(0,pos)) && judgeRight(s.substr(pos+1));
    }

    bool judgeLeft(string s){
     
        if(s.empty())   return false;
        if(s[0] == '+' || s[0] == '-')  s.erase(0, 1);
        bool flag = false;
        for(int i = 0; i < s.size(); ++i){
     
            if(isdigit(s[i]))   continue;
            //符号位只能在第一位
            if(s[i]=='.'){
     
                if(flag)   return false;//有多个小数点,返回false
                flag=true;//记录已经有一个小数点
            }else return false;
        }
        return !s.empty() && s != ".";
    }

    bool judgeRight(string s){
      
        cout << s << endl;
        if(s.empty())   return false;
        if(s[0] == '+' || s[0] == '-')  s.erase(0, 1);
        //右边不能出现小数点,所以出现除符号位的非纯数字表示指数不合法
        for(int i=0;i<s.size();++i){
     
            if(!isdigit(s[i]))   return false;
        }
        return !s.empty();
    }
};

思考

参见官方解答

你可能感兴趣的:(我的leetcode刷题系列,leetcode,字符串)