打卡系列-剑指 Offer 20. 表示数值的字符串

造孽啊,造孽啊,造孽啊。。。。。。。。。。。。。。。。。。。。。

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

太造孽了,主要是这个题有点扯蛋,我理解的数字字符串和题目不太一样,导致调试了很多次

我自己画的状态转移图

 public boolean isNumber(String s) {
        if(s == null || s.length() == 0){
                return false;
            }
            //标记是否遇到相应情况
            boolean numSeen = false;
            boolean dotSeen = false;
            boolean eSeen = false;
            char[] str = s.trim().toCharArray();
            for(int i = 0;i < str.length; i++){
                if(str[i] >= '0' && str[i] <= '9'){
                    numSeen = true;
                }else if(str[i] == '.'){
                    //.之前不能出现.或者e
                    if(dotSeen || eSeen){
                        return false;
                    }
                    dotSeen = true;
                }else if(str[i] == 'e' || str[i] == 'E'){
                    //e之前不能出现e,必须出现数
                    if(eSeen || !numSeen){
                        return false;
                    }
                    eSeen = true;
                    numSeen = false;//重置numSeen,排除123e或者123e+的情况,确保e之后也出现数
                }else if(str[i] == '-' || str[i] == '+'){
                    //+-出现在0位置或者e/E的后面第一个位置才是合法的
                    if(i != 0 && str[i-1] != 'e' && str[i-1] != 'E'){
                        return false;
                    }
                }else{//其他不合法字符
                    return false;
                }
            }
            return numSeen;
    }

    public static boolean isNumber2(String s){
        if(s == null || s.length() == 0){
            return false;
        }
        String str = s.trim();

        //整个字符串中是否出现过数字
        boolean haveNumber = false;
        //.出现在数字前面则后面不能有e
        char isDot = 0;
        boolean isPreDot = false;
        Map<Integer , Map<Character , Integer>> state = new HashMap<>();
        //状态0跳转到下一状态
        Map<Character , Integer> t0 = new HashMap<>(){{
            put('s' , 1); //如果是符号位则跳转到状态 1
            put('d' , 2);//如果是数字则跳转到状态 2
            put('o' , 3);//如果是小数点则跳转到状态3
        }};
        //状态1跳转到下一状态
        Map<Character , Integer> t1 = new HashMap<>(){{
            put('d' , 2);//如果是数字则跳转到状态2
            put('o' , 3);//如果是小数点则跳转到状态3
        }};
        //状态2跳转到下一状态
        Map<Character , Integer> t2 = new HashMap<>(){{
            put('d' , 2);//如果是数字则跳回自身
            put('o' , 3);//如果是点则跳转到状态3
            put('e' , 5);//如果是e则跳转到状态5
        }};
        //状态3跳转到下一状态
        Map<Character , Integer> t3 = new HashMap<>(){{
            put('d' , 4);//如果是数字则跳转到状态4
            put('e' , 5);//如果是e则跳转到状态5
        }};
        //状态4跳转到下一状态
        Map<Character , Integer> t4 = new HashMap<>(){{
            put('d' , 4);//如果是数字则跳转到自身
            put('e' , 5);//如果是e则跳转到状态5
        }};
        //状态5跳转到下一状态
        Map<Character , Integer> t5 = new HashMap<>(){{
            put('s' , 6);//如果是符号位则跳转到状态6
            put('d' , 7);//如果是数字则跳转到h状态7
        }};
        //状态6跳转到下一状态
        Map<Character , Integer> t6 = new HashMap<>(){{
            put('d' , 7);//如果是数字则跳转到状态7
        }};
        //状态7
        Map<Character , Integer> t7 = new HashMap<>(){{
            put('d' , 7);//如果是数字则跳回自身
        }};
        //加入状态集
        state.put(0 , t0);
        state.put(1 , t1);
        state.put(2 , t2);
        state.put(3 , t3);
        state.put(4 , t4);
        state.put(5 , t5);
        state.put(6 , t6);
        state.put(7 , t7);
        int stateNum = 0;
        char key = 0;
        int i = 0;
        for(i = 0 ; i < str.length() ; i++){
            if(str.charAt(i) == '-' || str.charAt(i) == '+'){
                key = 's';
            }else if(str.charAt(i) <= '9' && str.charAt(i) >= '0'){
                key = 'd';
                //数字先出现
                if(isDot == 0){
                    isDot = 'd';
                }
                haveNumber = true;
            }else if(str.charAt(i) == '.'){
                key = 'o';
                //点先出现
                if(isDot == 0){
                    isDot = 'o';
                    isPreDot = true;
                }
            }else if(str.charAt(i) == 'e' || str.charAt(i) == 'E'){
                key = 'e';
            }
            if(state.get(stateNum).get(key) == null){
                break;
            }
            //预防 [+、-].e 这样的格式,太扯淡了
            if(key == 'e' && str.charAt(i - 1) == '.' && isPreDot){
                break;
            }
            //获取下一状态
            stateNum = state.get(stateNum).get(key);
            //重置key
            key = 0;
        }
        //只有状态 2、3、4和7最后是合法的 还需要遍历完
        return (stateNum == 2 || stateNum == 3 ||stateNum == 4  || stateNum == 7) && i == str.length() && haveNumber;
    }

主要思路就是想想怎么样构成一个数字字符串才是合法的,情况很多

其实就是逻辑判断。状态转移只能从左往右不能右往左

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

void welcome() { printf("**********欢迎使用管理系统*************\n"); //以不同的角色进行登录系统 printf("1.管理员身份登录\n"); printf("2.普通用户学生登录\n"); printf("3.退出\n"); printf("******************************************\n"); } //管理员的菜单界面 void mangeview() { printf("**********欢迎管理员登录********\n"); printf("-----------------1.注册学生信息------------------\n"); printf("-----------------2.输出学生信息------------------\n"); printf("-----------------3.删除学生信息------------------\n"); printf("-----------------4.修改学生信息------------------\n"); printf("-----------------5.查询学生信息------------------\n"); printf("-----------------6.学生请假和补卡------------------\n"); printf("-----------------7.排序(姓名、学号、打卡次数)--\n"); printf("-----------------8.考勤数据统计------------------\n"); printf("-----------------9.返回------o( ̄ヘ ̄o#)----\n"); //........ printf("********************************\n"); } //普通用户界面 //普通用户界面提示 void comuser(){ printf("************欢迎学生登录************\n"); printf("-----------------1.录入学生信息------------------\n"); printf("-----------------2.输出学生信息------------------\n"); printf("-----------------3.查询学生信息------------------\n"); printf("-----------------4.排序(姓名、学号、打卡次数)--\n"); printf("-----------------5.学生请假和补卡------------------\n"); printf("-----------------6.返回------o( ̄ヘ ̄o#)----\n"); printf("********************************************\n"); } 这个代码怎么描述,运用了什么函数
06-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值