LeetCode: Valid Number

本文探讨了如何判断一个给定的字符串是否表示一个数值。通过详细分析案例并提供代码实现,展示了处理这一问题时可能遇到的各种复杂情况。

问题描述

<pre> Validate if a given string is numeric. Some examples: ` "0" => true " 0.1 " => true "abc" => false "1 a" => false "2e10" => true ` Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one. </pre>

<!--more-->

这道题看上去很简单,但是实际做的时候发现有很多意外的情况,主要是 case 没有想完全,有的 case 甚至是想错了。每次发现意外情况就微调下代码,到最后代码乱得自己都不想看了,而且再改起来牵一发动全身的感觉。于是又稍微重构了一下代码。最后 AC 的代码如下:

public class ValidNumber {

    public boolean isNumber(String s) {
        String trimed = s.trim();
        int len = trimed.length();

        boolean isNewGroup = true, hasNumberInGroup = false, hasPointInGroup = false;
        int groupNum = 1;
        for (int i = 0; i < len; i++) {
            char ch = trimed.charAt(i);
            if (!validChar(ch)) {
                return false;
            }
            if (isNewGroup) {
                isNewGroup = false;
                if (isDigit(ch)) {
                    hasNumberInGroup = true;
                } else if (isPoint(ch)) {
                    if (groupNum > 1) {
                        return false;
                    }
                    hasPointInGroup = true;
                } else if (isE(ch)){
                    return false;
                } else {
                    continue;
                }
            } else {
                if (isSign(ch)) {
                    return false;
                } else if (isPoint(ch)) {
                    if (hasPointInGroup) {
                        return false;
                    } else {
                        if (groupNum > 1) {
                            return false;
                        }
                        hasPointInGroup = true;
                    }
                } else if(isE(ch)) {
                    if (!hasNumberInGroup) {
                        return false;
                    }
                    isNewGroup = true;
                    hasNumberInGroup = false;
                    hasPointInGroup = false;
                    groupNum++;
                    if (groupNum > 2) {
                        return false;
                    }
                } else {
                    hasNumberInGroup = true;
                    continue;
                }
            }
        }
        if (!hasNumberInGroup) {
            return false;
        }

        return true;
    }

    private boolean validChar(char ch) {
        return (isSign(ch)
                || isDigit(ch)
                || isE(ch)
                || isPoint(ch));
    }

    private boolean isSign(char ch) {
        return (ch == '-' || ch == '+');
    }

    private boolean isDigit(char ch) {
        return (ch >= '0' && ch <= '9');
    }

    private boolean isE(char ch) {
        return (ch == 'e' || ch == 'E');
    }

    private boolean isPoint(char ch) {
        return ch == '.';
    }
}

可以说这段代码写的并不漂亮,勉强能行吧。后来看到网上有人用状态机去做,代码比较清晰。不过我想当他不断遇到意外情况的时候调整状态机,应该也比较费劲吧。

后来给一个同事看这个题,刚开始也跟我感觉一样,觉得应该挺简单的,真正做起来也发现挺坑爹的。

转载于:https://my.oschina.net/u/1412485/blog/264411

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值