【算法】Valid Number 有效数字

Valid Number 有效数字

题目

给出一个数字的字符串,可以是科学记数,其中 “3. “、 " .3”、”+.8"也算是正确记数
“0” => true
" 0.1 " => true
“abc” => false
“1 a” => false
“2e10” => true
" -90e3 " => true
" 1e" => false
“e3” => false
" 6e-1" => true
" 99e2.5 " => false
“53.5e93” => true
" --6 " => false
“-+3” => false
“95a54e53” => false
“3. " => true
" .3” => true
“+.8” => true

解题思路

关键字:有限状态自动机
首先输入为:INVALID,BLANK,SIGN,DIGIT,DOT,EXPONENT共六类
输入后字符串的状态共有八种为:
0:初始无输入或者只有BLANK的状态
1:输入了数字之后的状态
2:前面无数字,只输入了Dot的状态
3:输入了符号状态
4:前面有数字和有dot的状态
5:‘e’ or 'E’输入后的状态
6:输入e之后输入Sign的状态
7:输入e后输入数字的状态
8:前面有有效数输入之后,输入BLANK的状态

其中第1、4、7、8种状态为有效状态

如此,在遍历字符串的时候,字符串的状态也会不断变换,通过对比状态是否有效来判断字符串是否为有效数字

代码实现

class func ValidNumberSolution(_ s: String) -> Bool {
//        枚举输入的六类情况
        enum InputType : Int {
           case INVALID = 0    // 0 Include: Alphas, '(', '&' ans so on
           case BLANK = 1  // 1 " "
           case SIGN = 2   // 2 '+','-'
           case DIGIT = 3  // 3 numbers
           case DOT = 4    // 4 '.'
           case EXPONENT = 5   // 5 'e' 'E'
       }
//        将不同状态下输遇到不同输入时得到的状态以二位数组的形式列出来,-1代表非法状态
        let transTable : [[Int]] = [
                //0INVA,1SPA,2SIG,3DI,4DO,5E
                    [-1,  0,  3,  1,  2, -1],//0初始无输入或者只有BLANK的状态
                    [-1,  8, -1,  1,  4,  5],//1输入了数字之后的状态
                    [-1, -1, -1,  4, -1, -1],//2前面无数字,只输入了Dot的状态
                    [-1, -1, -1,  1,  2, -1],//3输入了符号状态
                    [-1,  8, -1,  4, -1,  5],//4前面有数字和有dot的状态
                    [-1, -1,  6,  7, -1, -1],//5'e' or 'E'输入后的状态
                    [-1, -1, -1,  7, -1, -1],//6输入e之后输入Sign的状态
                    [-1,  8, -1,  7, -1, -1],//7输入e后输入数字的状态
                    [-1,  8, -1, -1, -1, -1],//8前面有有效数输入之后,输入BLANK的状态
                ];
//        创造数字数组,用以判断输入的是否为数字
        var numPool = [Character]()
        for i in 0 ... 9 {
            numPool.append(Character(String(i)))
        }
//        创造各合法字符常量,用以比对
        let blank = Character(" ")
        let plus =  Character("+")
        let sub =  Character("-")
        let dot =  Character(".")
        let eEX =  Character("e")
        let EEX =  Character("E")
//        初始状态为无输入或者只有BLANK的状态
        var state = 0;
//        遍历字符串
        for ch in s {
            var input = InputType.INVALID;
            if(ch == blank){
                input = .BLANK
            }else if(ch == plus || ch == sub){
                input = .SIGN
            }else if(numPool.contains(ch)){
                input = .DIGIT
            }else if(ch == dot){
                input = .DOT
            }else if(ch == eEX || ch == EEX){
                input = .EXPONENT
            }
//            将当前当前状态和当前输入作为序号找到目标状态
            state = (transTable[state])[input.rawValue];
//            非法状态,即为非法字符串
            if (state == -1){ return false};
        }
//        最终状态只有为第1、4、7、8l种状态时,才是有效数字
        return state == 1 || state == 4 || state == 7 || state == 8;
    }

代码地址:https://github.com/sinianshou/EGSwiftLearning

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值