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

完整代码地址

完整代码地址

题目

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

解题时犯的错误

我在提交的时候错了三次:
1.第一次挂:-.123应该输出true(错在不懂得有这种情况)
2.第二次挂:12e应该输出false(错在粗心)
3.第三次挂:+-5应该输出false(错在粗心)
书上给的代码的c++版本的,c++版本的指针可以移动到数组中的任意一个位置,解这道题比较方便。
我一开始使用int index作为函数中的参数,判断字符串接下去是否出现了整数,但是这样的做法极不方便,因为index要不断重复判断是否到达了str.lengthindex是否等于 -1(-1表示没有找到匹配的整数)

解题时的思考

用一开始不方便的做法,可以用很复杂的逻辑判断解决这个问题,但是重复的代码和逻辑代码量实在太多!!
看了别人的解后,发现有一种做法可以大大减少代码量:
使用成员变量,private int index代表当前需要进行比较的字符对应的下标

总结:思路

数字有如下两种情况:
A[.B][e|EC]
[+|-].B[e|EC]

其中A、C表示数字(带符号或不带符号 ),B表示不带符号的数字
[]包含的整个部分可有可无,
即:如果是第一种类型 A必须有,[.B]可以有,[e|EC]可以有
  如果是第二种类型 [+|-]可以有,.B必须有,[e|EC]可以有

代码

public class _20_NumericStrings {

    private int index;

    public boolean isNumeric(char[] str) {
        if(str == null || str.length == 0)
            return false;
        index = 0;
        boolean isNumeric = false;
        // 走到 A↓[.B][e|EC]  或者  [+|-]↓.B[e|EC]
        isNumeric = isNumericCore(str);
        // 走到 A[.B]↓[e|EC]  或者  [+|-].B↓[e|EC]
        if(index != str.length && str[index] == '.') {
            ++index;
            isNumeric = isUnsignedNumeric(str);
        }
        // 必须有的A或者.B都没有
        if(isNumeric == false)
            return false;

        if(index != str.length && (str[index] == 'e' || str[index] == 'E')) {
            ++index;
            isNumeric = isNumericCore(str);
        }
        return isNumeric && index == str.length;
    }


    private boolean isUnsignedNumeric(char[] str) {
        boolean hasNumeric = false;
        while(index < str.length) {
            if('0' <= str[index] && str[index] <= '9') {
                hasNumeric = true;
                ++index;
                continue;
            }
            break;
        }
        return hasNumeric;
    }

    private boolean isNumericCore(char[] str) {
        if(index >= str.length)
            return false;
        if(str[index] == '+' || str[index] == '-')
            ++index;
        return isUnsignedNumeric(str);
    }
}

测试

public class _20_Test {

    public static void main(String[] args) {
        test1();
        test2();
        test3();
        test4();
    }

    /**
     * 功能测试
     * +1.23e-6
     * -2.2
     * 2.4
     * 2
     * .4E+9
     * .123
     */
    private static void test1() {
        _20_NumericStrings ns = new _20_NumericStrings();
        boolean b = ns.isNumeric(new char[] {'+','1','.','2','3','e','-','6'});
        MyTest.equal(b, true);

        b = ns.isNumeric(new char[] {'-','2','.','2'});
        MyTest.equal(b, true);

        b = ns.isNumeric(new char[] {'2','.','4'});
        MyTest.equal(b, true);

        b = ns.isNumeric(new char[] {'2'});
        MyTest.equal(b, true);

        b = ns.isNumeric(new char[] {'.','4','E','+','9'});
        MyTest.equal(b, true);

        b = ns.isNumeric(new char[] {'.','1','2','3'});
        MyTest.equal(b, true);
        System.out.println("==================================================");
    }

    /**
     * 功能测试
     * +1.23-6
     * -2.
     * 2+
     * e.123
     */
    private static void test2() {
        _20_NumericStrings ns = new _20_NumericStrings();
        boolean b = ns.isNumeric(new char[] {'+','1','.','2','3','-','6'});
        MyTest.equal(b, false);

        b = ns.isNumeric(new char[] {'-','2','.'});
        MyTest.equal(b, false);

        b = ns.isNumeric(new char[] {'2','+'});
        MyTest.equal(b, false);

        b = ns.isNumeric(new char[] {'e','.','1','2','3'});
        MyTest.equal(b, false);
        System.out.println("==================================================");
    }

    /**
     * 边界测试
     * 1.只有一个数字
     * 2.只有一个符号
     * 3.e
     * 4.只有一个.
     * 5.字符串长度为0
     */
    private static void test3() {
        _20_NumericStrings ns = new _20_NumericStrings();
        boolean b = ns.isNumeric(new char[] {'1'});
        MyTest.equal(b, true);

        b = ns.isNumeric(new char[] {'-'});
        MyTest.equal(b, false);

        b = ns.isNumeric(new char[] {'e'});
        MyTest.equal(b, false);

        b = ns.isNumeric(new char[] {'.'});
        MyTest.equal(b, false);

        b = ns.isNumeric(new char[0]);
        MyTest.equal(b, false);
        System.out.println("==================================================");
    }

    /**
     * 极端测试
     * null
     */
    private static void test4() {
        _20_NumericStrings ns = new _20_NumericStrings();
        boolean b = ns.isNumeric(null);
        MyTest.equal(b, false);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值