Valid Number

Valid Number

问题:

判断所给的字符串是不是数字。
例子:
“0” -> true
“0.1” -> true
“abc” -> false

面试者可能会问的问题:

Q: 如果字符串中有空格怎么处理?
A: 当决定一个字符串是否是数字时,忽略所有的前缀和后缀空格。
Q: 如果碰到字符中间有空格我是否应该忽略?比如”1 1”
A: 不,只忽略开始和结束空格,”1 1”不是数字。
Q: 如果字符串在数字部分之后包含其他的字符,这个属于有效吗?
A: 不,如果字符串含有不是数字部分(除了空格和小数点),都不属于数字。
Q: 如果有正负号出现在数字前面,这个属于有效吗?
A: 有效,”+1”和”-1”都属于数字。
Q: 是不是只有十进制的数字才算是数字?如果是16进制的数字呢?(0xFF)
A: 只考虑十进制的数字,”0xFF”不是数字。
Q: 我是否要认为指数”1e10”是数字?
A: 不,但是请自己选择接受这样的挑战。(网上习题有这样一道题)

解决方案:

这道问题非常像之前的[8. String to Integer (atoi)],由于很多的边界问题,将问题分成小块,分而治之是非常有帮助的。
一个字符串从左到右可以分成以下几个方面:
s1. 前缀空格 (可能有或没有)
s2. 正负号 (可能有或没有)
s3. 数字
s4. 后缀空格 (可能有或没有)
我们忽略s1,s2,s4,而直接判断s3是否是有效数字。我们意识到一个数字可以是一个整数或者是一个小数。如果是一个整数,非常简单:我们可以判断每一位数位是不是数字,是的话就解决了。
另外一方面,一个小数可以分成以下几部分:
a. 整数部分
b. 小数点
c. 小数部分
整数和小数部分应该只包含数字。例如:”3.64”就有整数部分(3)和小数部分(64)。他们都是可选的,但是他们之间至少有一个需要在。例如,”.”不是一个有效的数字,但是”1.”,”.1”或者”1.0”都是有效的。注意”1.”有效是因为它代表”1.0”。
至此为止,将需求转化为代码已经非常直接了。在下面代码中,在中间几行是处理判断s3是否是数字的逻辑。

public boolean isNumber(String s) {
    int i = 0, n = s.length();
    while (i < n && Character.isWhitespace(s.charAt(i))) i++;
    if (i < n && (s.charAt(i) == '+' || s.charAt(i) == '-')) i++;
    boolean isNumeric = false;
    while (i < n && Character.isDigit(s.charAt(i))) {
        i++;
        isNumeric = true;
    }
    if (i < n && s.charAt(i) == '.') {
        i++;
        while (i < n && Character.isDigit(s.charAt(i))) {
            i++;
            isNumeric = true;
        }
    }
    while (i < n && Character.isWhitespace(s.charAt(i))) i++;
    return isNumeric && i == n;
}

进一步思考

一个数字可能会包含指数部分,其中有一个”e”字符以及接下去的完整的数字(指数部分)。例如,”1e10”是一个数字。修改代码来兼容这个新需求。
根据上面已经实现的方案能非常容易的扩展。以下是代码:

public boolean isNumber(String s) {
    int i = 0, n = s.length();
    while (i < n && Character.isWhitespace(s.charAt(i))) i++;
    if (i < n && (s.charAt(i) == '+' || s.charAt(i) == '-')) i++;
    boolean isNumeric = false;
    while (i < n && Character.isDigit(s.charAt(i))) {
        i++;
        isNumeric = true;
    }
    if (i < n && s.charAt(i) == '.') {
        i++;
        while (i < n && Character.isDigit(s.charAt(i))) {
            i++;
            isNumeric = true;
        }
    }
    // 以下代码块是新增加的内容以兼容指数,如果碰到了'e'
    if (isNumeric && i < n && s.charAt(i) == 'e') {
        // 继续往前进
        i++;
        // 将isNumeric设置为false
        isNumeric = false;
        // 如果当前字符是正负号,则继续向前
        if (i < n && (s.charAt(i) == '+' || s.charAt(i) == '-')) i++;
        // 剩下的数字每一位都应该是数字
        while (i < n && Character.isDigit(s.charAt(i))) {
            i++;
            isNumeric = true;
        }
    }
    while (i < n && Character.isWhitespace(s.charAt(i))) i++;
    return isNumeric && i == n;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值