剑指 Offer 20. 表示数值的字符串

题目描述

请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
输入:s = "    .1  " 输出:true
🔗题目链接:https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/

思路

遍历字符串,字符串中出现数字、小数点、e或E、正负号是合法的,其他情况就直接返回false,因此根据这几种情况对当前字符进行判断,除了判断当前字符是否合法,在确定了字符的类型后,还需根据不同的情况进一步判断,如遇到小数点,小数点前面可以没有整数,但是不能重复出现小数点,或出现‘e’、'E'。
下面的解法就是通过几个变量标识是否遇到数字、小数点、‘e’或'E'等,除了推断当前是否合法,还要给下一个字符的判断提供依据。

代码实现

class Solution {
    public boolean isNumber(String s) {
        if(s == null || s.length() == 0) {
            return false; 
        }
        //标记是否遇到数位、小数点、‘e’或'E'
        boolean isNum = false, isDot = false, ise_or_E = false;
        char[] str = s.trim().toCharArray();
        for(int i = 0; i < str.length; i++) {
            if(str[i] >= '0' && str[i] <= '9') { //判断当前字符是否为 0~9 的数位
                isNum = true;
            }
            else if(str[i] == '.') { //遇到小数点
                if(isDot || ise_or_E){ //小数点之前可以没有整数,但是不能重复出现小数点、或出现‘e’、'E'
                    return false;
                }
                isDot = true; //标记已经遇到小数点
            }
            else if(str[i] == 'e' || str[i] == 'E') { // 遇到‘e’或'E'
                if(!isNum || ise_or_E) { //‘e’或'E'前面必须有整数,且前面不能重复出现‘e’或'E'
                    return false;
                }
                ise_or_E = true; //标记已经遇到‘e’或'E'
                isNum = false; //重置isNum,因为‘e’或'E'之后也必须接上整数,防止出现 123e或者123e+的非法情况
            }
            else if(str[i] == '-' ||str[i] == '+') { 
                if(i!=0 && str[i-1] != 'e' && str[i-1] != 'E') {
                    return false; //正负号只可能出现在第一个位置,或者出现在‘e’或'E'的后面一个位置
                }
            }
            else { //其它情况均为不合法字符
                return false;
            }
        }
        return isNum;
    }
}

剑指 Offer 67. 把字符串转换成整数

题目描述

写一个函数 StrToInt,实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。
输入: "4193 with words" 输出: 4193 解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。
🔗题目链接:https://leetcode-cn.com/problems/ba-zi-fu-chuan-zhuan-huan-cheng-zheng-shu-lcof/

思路

其实就是按照要求从字符串的第一个非空字符开始,若第一个非空字符为正负号或者数字,就往后提取连续的数字字符,为防止最终的结果越界,在提取拼接的过程中同时进行越界判断,总体思路实现不难,但难在要把输入字符串的各种情况考虑全面。

代码实现

class Solution {
    public int strToInt(String str) {
        String s = str.trim(); //去除字符串前后的空字符
        int length = s.length();
        if(length == 0){
            return 0;
        }
        StringBuilder sbr = new StringBuilder();
        char c1 = s.charAt(0);
        int sign = 1; //标记正负
        int index = 0;
        if(c1 == '+'){ //判断第一个非空字符
            index++;
        }else if(c1 == '-'){
            sign = -1;
            index++;
        }else if((c1 < '0' && c1 > '9')){ //不为正负号和数字就直接返回0
            return 0;   
        }
        long l = 0;
        //第一个非空字符符合要求就继续遍历字符串拼接数字,同时判断是否越界,遇到非数字就跳出
        for(int i = index; i < length; i++){
            char c = s.charAt(i);
            if(c >= '0' && c <= '9'){
                sbr.append(String.valueOf(c));
            }else{
                break;
            }
            l = Long.parseLong(sbr.toString()) * sign; //转换为长整型
            if(l < Integer.MIN_VALUE){ //判断是否超出整数的范围
                return Integer.MIN_VALUE;
            }else if(l > Integer.MAX_VALUE){
                return Integer.MAX_VALUE;
            }
        }
        return (int)l;
    }
}