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

表示数值的字符串

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

来源:力扣(LeetCode)
链接:点击跳转https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof


思路:

这就是一道考测试用例的题,一次不可能写成功,得一直改
我遇到的几个奇葩的测试用例摆出来:

测试用例返回值
" "false
“1.”true
“.1”true
“1.1”true
“.1.”false
“…”false
“2e0”true
“1 4”false
“1e.”false
“G76”false
“±.”false
“-1E-16”true
“6+1”false
“3-2”false
“+.8”true
" -."false
“.44.8”false
“46.e3”true
“6e6.5”false
" 4e3."false
“92e1740e91”false
" 005047e+6"true
“4e+”false

如果这些都能有对应的输出,则基本没有问题


采用分而治之的思想,分别对符号位进行限制,限制哪些情况需要输出false,如果全部通过限制,则返回true

代码如下:

class Solution {
    public boolean isNumber(String s) {
        s = s.trim();   //去掉首位空格
        if (s.length() == 0) return false;
        char[] arr = s.toCharArray();
        int len = arr.length;
        int count = 0;  //记录.的个数
        boolean haveE = false;  //记录字符数组中是否有e或E
        //循环遍历字符数组
        for(int i = 0; i < len; i++) {
            //不为符号 和 数字
            if(!isnum(arr[i]) && !isnor(arr[i])) return false;
            //e,E
            if(arr[i] == 'e' || arr[i] == 'E') {
                //如果有过e或E了
                if(haveE) return false;
                haveE = true;   //变为有e或E
                //e的前后位置越界
                if(i-1 < 0 || i+1 >= len) {
                    return false;
                }
                //e的前位置不为 数字 .
                if(!isnum(arr[i-1]) && arr[i-1]!='.') return false;
                //e的后位置不为 数字 - . +
                if(!isnum(arr[i+1]) && arr[i+1] != '-' && arr[i-1]!='.' && arr[i+1]!='+') return false;
            }
            //+
            if(arr[i] == '+') {
                //第一位不为+
                if(i == 0) continue;
                //最后一位为+
                if(i == len-1) return false;
                //为e或E不执行后面代码
                if(arr[i - 1] == 'e' || arr[i - 1] == 'E') continue;
                return false;
            }
            //-
            if(arr[i] == '-') {
                //最后为-
                if(arr[len-1] == '-') return false;
                //-的前不为e和E
                if(i-1 >=0 && arr[i-1] != 'e' && arr[i-1] != 'E') {
                    return false;
                }
            }
            //.
            if(arr[i] == '.') {
                //.在最前
                if(i == 0) {
                    count++;
                    //.后一位越界和不越界
                    if(i+1 < len) {
                        //.后不为数字
                        if(!isnum(arr[i+1])) return false;
                        continue;   //不执行后面的代码
                    }else {
                        return false;
                    }
                }
                //.在最后一位
                if(i == len-1) {
                    count++;
                    //.只能出现一次
                    if(count > 1) return false;
                    //.前面为符号,且后面越界
                    if(isnor(arr[i-1]) && i+1>=len) return false;
                    //.的前面有e
                    if(haveE) return false;
                    continue;   //不执行下面.在中间的代码
                }
                //.在中间位
                count++;
                //.的后位置不为数字 e E
                if(!isnum(arr[i+1]) && arr[i+1]!='e' && arr[i+1]!='E') return false;
                //.的前面有e
                if(haveE) return false;
                //.只能出现一次
                if(count > 1) return false;
            }
        }
        return true;
    }

    //是否存在数字
    public boolean isnum(char en) {
        char[] num = {'0','1','2','3','4','5','6','7','8','9'};
        int i;
        for(i = 0; i < 10; i++) {
            if(en == num[i]) break;
        }
        return i != 10;
    }

    //是否存在符号
    public boolean isnor(char en) {
        char[] num = {'+','-','e','E','.'};
        int i;
        for(i = 0; i < num.length; i++) {
            if(en == num[i]) break;
        }
        return i != num.length;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值