# 有效数字

<p><strong>有效数字</strong>（按顺序）可以分成以下几个部分：</p><ol>	<li>一个 <strong>小数</strong> 或者 <strong>整数</strong></li>	<li>（可选）一个 <code>'e'</code> 或 <code>'E'</code> ，后面跟着一个 <strong>整数</strong></li></ol><p><strong>小数</strong>（按顺序）可以分成以下几个部分：</p><ol>	<li>（可选）一个符号字符（<code>'+'</code> 或 <code>'-'</code>）</li>	<li>下述格式之一：	<ol>		<li>至少一位数字，后面跟着一个点 <code>'.'</code></li>		<li>至少一位数字，后面跟着一个点 <code>'.'</code> ，后面再跟着至少一位数字</li>		<li>一个点 <code>'.'</code> ，后面跟着至少一位数字</li>	</ol>	</li></ol><p><strong>整数</strong>（按顺序）可以分成以下几个部分：</p><ol>	<li>（可选）一个符号字符（<code>'+'</code> 或 <code>'-'</code>）</li>	<li>至少一位数字</li></ol><p>部分有效数字列举如下：</p><ul>	<li><code>["2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10", "-90E3", "3e+7", "+6e-1", "53.5e93", "-123.456e789"]</code></li></ul><p>部分无效数字列举如下：</p><ul>	<li><code>["abc", "1a", "1e", "e3", "99e2.5", "--6", "-+3", "95a54e53"]</code></li></ul><p>给你一个字符串 <code>s</code> ，如果 <code>s</code> 是一个 <strong>有效数字</strong> ，请返回 <code>true</code> 。</p><p><strong>示例 1：</strong></p><pre><strong>输入：</strong>s = "0"<strong><br />输出：</strong>true</pre><p><strong>示例 2：</strong></p><pre><strong>输入：</strong>s = "e"<strong><br />输出：</strong>false</pre><p><strong>示例 3：</strong></p><pre><strong>输入：</strong>s = "."<strong><br />输出：</strong>false</pre><p><strong>示例 4：</strong></p><pre><strong>输入：</strong>s = ".1"<strong><br />输出：</strong>true</pre><p><strong>提示：</strong></p><ul>	<li><code>1 <= s.length <= 20</code></li>	<li><code>s</code> 仅含英文字母（大写和小写），数字（<code>0-9</code>），加号 <code>'+'</code> ，减号 <code>'-'</code> ，或者点 <code>'.'</code> 。</li></ul>
<p>以下<span style="color:red">错误</span>的选项是？</p>

## aop

### before

```c
#include <bits/stdc++.h>
using namespace std;
```

### after

```c
int main()
{
    Solution sol;
    string s = ".1";
    bool res;
    res = sol.isNumber(s);
    cout << res;
    return 0;
}
```

## 答案

```c
class Solution
{
public:
    bool isNumber(string s)
    {
        int len = s.size();
        int left = 0, right = len - 1;
        bool eExisted = false;
        bool dotExisted = false;
        bool digitExisited = false;

        while (s[left] == ' ')
            ++left;
        while (s[right] == ' ')
            --right;

        if (left >= right && (s[left] < '0' || s[left] > '9'))
            return false;

        if (s[left] == '.')
            dotExisted = true;
        else if (s[left] >= '0' && s[left] <= '9')
            digitExisited = true;
        else if (s[left] != '+' && s[left] != '-')
            return false;

        for (int i = left + 1; i <= right - 1; ++i)
        {
            if (s[i] >= '0' && s[i] <= '9')
                digitExisited = true;
            else if (s[i] == 'e' || s[i] == 'E')
            {
                if (!eExisted && s[i - 1] != '+' && s[i - 1] != '-' && digitExisited)
                    eExisted = true;
                else
                    return false;
            }
            else if (s[i] == '+' || s[i] == '-')
            {
                if (s[i - 1] != 'e' && s[i - 1] != 'E')
                    return false;
            }
            else if (s[i] == '.')
            {
                if (!dotExisted && !eExisted)
                    dotExisted = true;
                else
                    return false;
            }
            else
                return false;
        }

        if (s[right] >= '0' && s[right] <= '9')
            return true;
        else
            return false;
    }
};
```
## 选项


### A

```c
class Solution
{
public:
    bool isInt(string &s, int &index)
    {
        if (index < s.size() && (s[index] == '-' || s[index] == '+'))
            index++;
        return isUnsigned(s, index);
    }

    bool isUnsigned(string &s, int &index)
    {
        int pre = index;
        while (index < s.size())
        {
            if (s[index] >= '0' && s[index] <= '9')
                index++;
            else
                break;
        }
        return index > pre;
    }

    bool isNumber(string s)
    {
        if (s.empty())
        {
            return false;
        }

        int index = 0;
        while (index < s.size() && s[index] == ' ')
        {
            index++;
        }

        bool ans = isInt(s, index);
        if (index < s.size() && s[index] == '.')
        {
            index++;
            ans = isUnsigned(s, index) || ans;
        }

        if (index < s.size() && s[index] == 'e')
        {
            index++;
            ans = isInt(s, index) && ans;
        }

        while (index < s.size() && s[index] == ' ')
        {
            index++;
        }

        return ans && index == s.size();
    }
};
```

### B

```c
class Solution
{
public:
    bool isNumber(string s)
    {
        int tail = s.size() - 1;
        int head = 0;
        while (tail >= 0)
        {
            if (s[tail] == ' ')
                --tail;
            else
                break;
        }
        while (head <= tail)
        {
            if (s[head] == ' ')
                ++head;
            else
                break;
        }
        if (head > tail)
            return false;
        s = s.substr(head, tail - head + 1);
        int index = s.find('e');
        if (index == string::npos)
            return judgea(s);
        else
            return judgea(s.substr(0, index)) && judgeb(s.substr(index + 1));
    }
    bool judgea(string s)
    {
        bool have_num = false;
        bool have_pointed = false;
        for (int i = 0; i < s.size(); i++)
        {
            if (s[i] >= '0' && s[i] <= '9')
                have_num = true;
            else if (s[i] == '+' || s[i] == '-')
            {
                if (i != 0)
                    return false;
            }
            else if (s[i] == '.')
            {
                if (have_pointed)
                    return false;
                have_pointed = true;
            }
            else
                return false;
        }
        return have_num;
    }

    bool judgeb(string s)
    {
        bool have_num = false;
        for (int i = 0; i < s.size(); i++)
        {
            if (s[i] >= '0' && s[i] <= '9')
                have_num = true;
            else if (s[i] == '-' || s[i] == '+')
            {
                if (i != 0)
                    return false;
            }
            else
                return false;
        }
        return have_num;
    }
};
```

### C

```c
class Solution
{
public:
    bool isNumber(string s)
    {
        bool num = false, numAfterE = true, dot = false, sign = false, exp = false;
        int n = s.size();
        for (int i = 0; i < n; ++i)
        {
            if (s[i] == ' ')
            {
                if (i < n - 1 && s[i + 1] != ' ' && (num || dot || sign || exp))
                    return false;
            }
            else if (s[i] == '+' || s[i] == '-')
            {
                if (i > 0 && s[i - 1] != 'e' && s[i - 1] != ' ')
                    return false;
                sign = true;
            }
            else if (s[i] >= '0' && s[i] <= '9')
            {
                num = true;
                numAfterE = true;
            }
            else if (s[i] == '.')
            {
                if (dot || exp)
                    return false;
                dot = true;
            }
            else if (s[i] == 'e')
            {
                if (exp || !num)
                    return false;
                exp = true;
                numAfterE = false;
            }
            else
                return false;
        }
        return num && numAfterE;
    }
};
```
