【剑指offer】20. 表示数值的字符串

145 阅读1分钟

题目描述

在这里插入图片描述

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

// 建议做牛客的题,这题在力扣里的测试用例会带空格,非常智障

题解

////////////////////////////////// 条件判断 /////////////////////////////////

// 牛客
// 运行时间:10ms
// 占用内存:9448k
public class Solution {
	public boolean isNumeric(char[] str) {
		int len = str.length;
		if (len == 0)
			return false;
		
		boolean existE = false;
		int existSign = 0;
		boolean existSignM = false;
		boolean existPoint = false;
		// 遍历str元素索引记为i
		for (int i = 0; i < len; i++) { 
			if (str[i] == 'e' || str[i] == 'E') {
				if (existE) return false;  // E e出现过,false
				if (i == 0 || i == len - 1)
					return false;  // 首尾不能有E e
				existE = true;
			}
			else if (str[i] == '+' || str[i] == '-') {
				if (existSign == 2) return false;  // +-号最多2个
				if (i == 0) {
					existSign += 1;  // 第一个出现,计数一次
					continue;
				}
				else if (str[i - 1] != 'E' && str[i - 1] != 'e') {
					return false;  // 如果+-号前面没有E e,false
				}
				existSign += 1;
				existSignM = true;
			}
			else if (str[i] == '.') {
				if (existPoint) return false;  // 小数点出现两次,false
				if (i == 0 || i == len - 1)  // 头尾出现小数点,false
					return false;
				if (existSignM) return false;  // 小数点出现过,false
				existPoint = true;
			}
			else if (str[i] > '9' || str[i] < '0') {
				return false;
			}
		}
		return true;
	}
}


// 简化版
// 运行时间:8ms
// 占用内存:9696k
public class Solution {
	public boolean isNumeric(char[] str) {
		int len = str.length;
		if (len == 0)
			return false;
		
		boolean existE = false;
		boolean existSignM = false;
		boolean existPoint = false;
		// 遍历str元素索引记为i
		for (int i = 0; i < len; i++) { 
			if (str[i] == 'e' || str[i] == 'E') {
				if (existE) return false;  // E e出现过,false
				if (i == 0 || i == len - 1)  
					return false;  // 首尾不能有E e
				existE = true;
			}
			else if (str[i] == '+' || str[i] == '-') {
				if (existSignM) return false;  // +-号最多2个
				if (i == 0) {  // 第一个存在+-,无视
					continue;
				}
				else if (str[i - 1] != 'E' && str[i - 1] != 'e') {
					return false;  // 如果+-号前面没有Ee,false
				}
				existSignM = true;  // 后面的+-号必为存在于中间的+-号
			}
			else if (str[i] == '.') {
				if (existPoint) return false;  // 小数点出现两次,false
				if (i == 0 || i == len - 1)  // 头尾出现小数点,false
					return false;
				if (existSignM) return false;  // +-小数点出现过,false
				existPoint = true;
			}
			else if (str[i] > '9' || str[i] < '0') {
				return false;
			}	
		}
		return true;
	}
}
///////////////////////////////// 正则表达式 ////////////////////////////
// 牛客
// 运行时间:14ms
// 占用内存:9892k

// []  : 字符集合
// ()  : 分组
// ?   : 重复 0 ~ 1 次
// +   : 重复 1 ~ n 次
// *   : 重复 0 ~ n 次
// .   : 任意字符
// \\. : 转义后的 .
// \\d : 数字

public class Solution {
    public boolean isNumeric(char[] str) {
		if (str == null || str.length == 0)
			return false;
		return new String(str).matches("[+-]?\\d*(\\.\\d+)?([eE][+-]?\\d+)?");
    }
}