Leetcode.65 有效数字

该问题要求判断一个字符串是否符合有效数字的定义,包括整数、小数和科学计数法。主要策略是对字符串进行遍历,检查操作符、小数点和e的出现次数及位置,并验证数字部分。代码分别处理了整数和小数的情况,以及带或不带E/e的情况。
摘要由CSDN通过智能技术生成

题目链接

Leetcode.65 有效数字

题目描述

有效数字(按顺序)可以分成以下几个部分:

一个 小数 或者 整数
(可选)一个 'e''E',后面跟着一个 整数
小数(按顺序)可以分成以下几个部分:

(可选)一个符号字符('+''-'
下述格式之一:
至少一位数字,后面跟着一个点 '.'
至少一位数字,后面跟着一个点 '.' ,后面再跟着至少一位数字
一个点 '.',后面跟着至少一位数字
整数(按顺序)可以分成以下几个部分:

(可选)一个符号字符('+' '-'
至少一位数字
部分有效数字列举如下:["2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10", "-90E3", "3e+7", "+6e-1", "53.5e93", "-123.456e789"]

部分无效数字列举如下:["abc", "1a", "1e", "e3", "99e2.5", "--6", "-+3", "95a54e53"]

给你一个字符串 s ,如果 s 是一个 有效数字 ,请返回 true 。

示例 1:

输入:s = “0”
输出:true

示例 2:

输入:s = “e”
输出:false

示例 3:

输入:s = “.”
输出:false

提示:
  • 1 < = s . l e n g t h < = 20 1 <= s.length <= 20 1<=s.length<=20
  • s 仅含英文字母(大写和小写),数字(0-9),加号 '+' ,减号 '-',或者点 '.'

分析:

本题是一道比较复杂的模拟题,我们根据题意进行模拟即可。

首先我们先过滤一些非法字符,便于我们我后面处理

        int op = 0,point = 0,e = 0,e_idx = -1,point_idx = -1;
        int n = s.length();
        for(int i = 0;i < n;i++){
        
            char c = s.charAt(i);
            //如果 c 是数字直接跳过本次循环
            if(isdigit(c)) continue;
            //如果是操作符 记录操作符的个数
            if(c == '+' || c == '-'){
                op++;
                continue;
            }
            //记录小数点的个数
            if(c == '.'){
                point++;
                //记录小数点的位置
                point_idx = i;
                continue;
            }
            //记录 e 的个数
            if(c == 'E' || c == 'e'){
                e++;
                //记录 e 的位置
                e_idx = i;
                continue;
            }
            //如果都不是 只能是除了(E/e)之外的大小写字母,不满足要求,直接返回false
            return false;
        }
        // 一个合法的数字中 操作符号最多两个 小数点最多一个 e最多一个 超过的都是不符合要求的 直接返回 false
        if(op > 2 || point > 1 || e > 1) return false;

紧接着我们根据是否存在小数点,来分别处理 整数小数,整数 和 小数 再细分为带 E/e不带E/e的数。

  • 整数,不带E/e
                //整数不带E/e 的合法数字的形式为 (+/-)....
                //由于通过先前的过滤 现在的 s 只包含操作符 (+/-) 和 数字
                //操作符只能在第 0 个位置,如果在后面的位置出现了操作符 即为不合法
                //用 a 记录数字个数,a必须大于0,避免出现 s = "+“ 也通过的情况
                int a = 0;
                for(int i = 0;i < n;i++){
                    char ch = s.charAt(i);
                    if(i == 0 && (ch =='+' || ch == '-')) continue;
                    if(!isdigit(ch)) return false;
                    a++;
                }
                return a>0;
  • 整数,带E/e
                //此时合法数字的形式为 (+/-)....E/e (+/-)...
                //用 a b分别记录两段数字个数,a 和 b都必须大于0
                
                int a = 0,b = 0;
                //只能在第0个位置有操作符,第一段的后面的位置都必须是数字,统计第一段数字的个数
                for(int i = 0;i < e_idx;i++){
                    char ch = s.charAt(i);
                    if(i == 0 &&(ch == '+' || ch == '-')) continue;
                    if(!isdigit(ch)) return false;
                    a++;
                }
                 //只能在第e_idx+1个位置(也就是s中 E/e 后面的一个位置)有操作符,第二段的后面的位置都必须是数字,统计第二段数字的个数
                for(int i = e_idx + 1;i < n;i++){
                    char ch = s.charAt(i);
                    if(i == e_idx + 1 &&(ch == '+' || ch == '-')) continue;
                    if(!isdigit(ch)) return false;
                    b++;
                }
                return (a>0) && (b>0);
  • 小数,不带E/e
                //此时的合法数字形式为 (+/-)a.b
                //小数点两边的数字,可以两个都存在,也可以只有一边有数字,不能两边都没有。即 2.3 , .3 ,2. 都合法。  . 不合法
                int a = 0,b = 0;
                for(int i = 0;i < point_idx;i++){
                    char ch = s.charAt(i);
                    if(i == 0 && (ch == '+' || ch == '-')) continue;
                    if(!isdigit(ch)) return false;
                    a++;
                }
                for(int i = point_idx + 1;i < n;i++){
                    char ch = s.charAt(i);
                    if(!isdigit(ch)) return false;
                    b++;
                }
                return (a>0)||(b>0);
  • 小数,带E/e
                //此时的合法数字的形式为 (+/-)a.b E/e (+/-)c
                //a 和 b可以同时存在,也可以只存在其中一个,不可以都不存在
                //c 必须存在
                //分别统计三段的数字 a b c 即可
                int a = 0,b = 0,c = 0;
                for(int i = 0;i < point_idx;i++){
                    char ch = s.charAt(i);
                    if(i == 0 && (ch == '+' || ch == '-')) continue;
                    if(!isdigit(ch)) return false;
                    a++;
                }

                for(int i = point_idx + 1;i < e_idx;i++){
                    char ch = s.charAt(i);
                    if(!isdigit(ch)) return false;
                    b++;
                }

                for(int i = e_idx+1;i < n;i++){
                    char ch = s.charAt(i);
                    if(i == e_idx+1 && (ch == '+' || ch == '-')) continue;
                    if(!isdigit(ch)) return false;
                    c++;
                }
                return (a>0||b>0)&&(c>0);

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

C++代码:

class Solution {
public:
    bool isNumber(string s) {
        int op = 0,point = 0,e = 0,e_idx = -1,point_idx = -1;
        int n = s.size();
        for(int i = 0;i < n;i++){
            char c = s[i];
            if(isdigit(c)) continue;
            if(c == '+' || c == '-'){
                op++;
                continue;
            }
            if(c == '.'){
                point++;
                point_idx = i;
                continue;
            }
            if(c == 'E' || c == 'e'){
                e++;
                e_idx = i;
                continue;
            }
            return false;
        }
        if(op > 2 || point > 1 || e > 1) return false;
        bool flag = point == 1;
        //小数
        if(flag){
            //带 e 的
            if(e == 1){
                int a = 0,b = 0,c = 0;
                for(int i = 0;i < point_idx;i++){
                    if(i == 0 && (s[i] == '+' || s[i] == '-')) continue;
                    if(!isdigit(s[i])) return false;
                    a++;
                }

                for(int i = point_idx + 1;i < e_idx;i++){
                    if(!isdigit(s[i])) return false;
                    b++;
                }

                for(int i = e_idx+1;i < n;i++){
                    if(i == e_idx+1 && (s[i] == '+' || s[i] == '-')) continue;
                    if(!isdigit(s[i])) return false;
                    c++;
                }
                return (a||b)&&c;
            }
            //不带 e 的
            else{
                int a = 0,b = 0;
                for(int i = 0;i < point_idx;i++){
                    if(i == 0 && (s[i] == '+' || s[i] == '-')) continue;
                    if(!isdigit(s[i])) return false;
                    a++;
                }
                for(int i = point_idx + 1;i < n;i++){
                    if(!isdigit(s[i])) return false;
                    b++;
                }
                return a||b;
            }
        }
        //整数
        else{
            if(e == 1){
                int a = 0,b = 0;
                for(int i = 0;i < e_idx;i++){
                    if(i == 0 &&(s[i] == '+' || s[i] == '-')) continue;
                    if(!isdigit(s[i])) return false;
                    a++;
                }
                for(int i = e_idx + 1;i < n;i++){
                    if(i == e_idx + 1 &&(s[i] == '+' || s[i] == '-')) continue;
                    if(!isdigit(s[i])) return false;
                    b++;
                }
                return a && b;
            }
            else{
                //cout<<"不带e"<<endl;
                int a = 0;
                for(int i = 0;i < n;i++){
                    if(i == 0 && (s[i] =='+' || s[i] == '-')) continue;
                    if(!isdigit(s[i])) return false;
                    a++;
                }
                return a;
            }
        }
        return true;
    }
};

Java代码:

class Solution {
    public boolean isdigit(char c){
        return c >= '0' && c <= '9';
    }

    public boolean isNumber(String s) {
        int op = 0,point = 0,e = 0,e_idx = -1,point_idx = -1;
        int n = s.length();
        for(int i = 0;i < n;i++){
            char c = s.charAt(i);
            if(isdigit(c)) continue;
            if(c == '+' || c == '-'){
                op++;
                continue;
            }
            if(c == '.'){
                point++;
                point_idx = i;
                continue;
            }
            if(c == 'E' || c == 'e'){
                e++;
                e_idx = i;
                continue;
            }
            return false;
        }
        if(op > 2 || point > 1 || e > 1) return false;
        boolean flag = point == 1;
        //小数
        if(flag){
            //带 e 的
            if(e == 1){
                int a = 0,b = 0,c = 0;
                for(int i = 0;i < point_idx;i++){
                    char ch = s.charAt(i);
                    if(i == 0 && (ch == '+' || ch == '-')) continue;
                    if(!isdigit(ch)) return false;
                    a++;
                }

                for(int i = point_idx + 1;i < e_idx;i++){
                    char ch = s.charAt(i);
                    if(!isdigit(ch)) return false;
                    b++;
                }

                for(int i = e_idx+1;i < n;i++){
                    char ch = s.charAt(i);
                    if(i == e_idx+1 && (ch == '+' || ch == '-')) continue;
                    if(!isdigit(ch)) return false;
                    c++;
                }
                return (a>0||b>0)&&(c>0);
            }
            //不带 e 的
            else{
                int a = 0,b = 0;
                for(int i = 0;i < point_idx;i++){
                    char ch = s.charAt(i);
                    if(i == 0 && (ch == '+' || ch == '-')) continue;
                    if(!isdigit(ch)) return false;
                    a++;
                }
                for(int i = point_idx + 1;i < n;i++){
                    char ch = s.charAt(i);
                    if(!isdigit(ch)) return false;
                    b++;
                }
                return (a>0)||(b>0);
            }
        }
        //整数
        else{
            if(e == 1){
                int a = 0,b = 0;
                for(int i = 0;i < e_idx;i++){
                    char ch = s.charAt(i);
                    if(i == 0 &&(ch == '+' || ch == '-')) continue;
                    if(!isdigit(ch)) return false;
                    a++;
                }
                for(int i = e_idx + 1;i < n;i++){
                    char ch = s.charAt(i);
                    if(i == e_idx + 1 &&(ch == '+' || ch == '-')) continue;
                    if(!isdigit(ch)) return false;
                    b++;
                }
                return (a>0) && (b>0);
            }
            else{
                int a = 0;
                for(int i = 0;i < n;i++){
                    char ch = s.charAt(i);
                    if(i == 0 && (ch =='+' || ch == '-')) continue;
                    if(!isdigit(ch)) return false;
                    a++;
                }
                return a>0;
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值